Author |
Topic: struct type ptr (Read 3386 times) |
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #20 on: Nov 21st, 2015, 12:43am » |
|
I can make this code operate, but I can't make the "Get" work as a FUNCTION by returning the value. I had to pass a variable BYREF. It works, but wasn't my goal.
I speculate that since I am passing the STRUCT name that the FUNCTION is working on a copy of STRUCT. Interesting.
Any ideas on returning the STRUCT value with a FUNCTION?
Also, I found out that CHAR[10] really only stores a string of 9 characters. I guess the rest is overhead? I don't understand why specifying [10] in the code doesn't save 10.
OUTPUT LOOKS LIKE THE FOLLOWING:
Code:[settings]
config=30313233343536373839000D
Code:
if right$(DefaultDir$,1)<>"\" then
DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"
print inifile$
struct structName, keychars$ as CHAR[11] ' if CHAR[10] you can only write 9 characters
ret = WriteINIStruct1("settings","config","0123456789",structName,inifile$)
print "ret from write: ";ret
'structName.keychars$.struct = ""
'print "test struct clear: "+structName.keychars$.struct
ret = GetINIStruct1("settings","config",GetKeyChars$,structName,inifile$)
print "ret from get: ";ret
print "Got this: ->"+GetKeyChars$+"<- (from GetINIStruct1)"
end
function WriteINIStruct1(SectionName$,KeyName$,KeyChars$,structName,inifile$)
' Returns true (1) if nothing wrong or false (0) if a problem
'code by Richard Russell
structName.keychars$.struct = KeyChars$
size = len(structName.struct)
calldll #kernel32, "WritePrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
WriteINIStruct1 = ret
end function
function GetINIStruct1(SectionName$,KeyName$,byref GetKeyChars$,structName,inifile$)
' Returns true (1) if nothing wrong or false (0) if a problem
'code by Richard Russell
size = len(structName.struct)
calldll #kernel32, "GetPrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
GetKeyChars$ = structName.keychars$.struct
'GetINIStruct1 = structName.keychars$.struct ' this won't work. "Type mismatch" error.
GetINIStruct1 = ret
end function
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: struct type ptr
« Reply #21 on: Nov 21st, 2015, 03:35am » |
|
on Nov 21st, 2015, 12:43am, pnlawrence wrote:| I can't make the "Get" work as a FUNCTION by returning the value. |
|
I wonder if the problem is as simple as forgetting that a function which returns a string must itself have a name ending in a dollar. So for example the function might be called GetINIStruct1$().
Quote:| I speculate that since I am passing the STRUCT name that the FUNCTION is working on a copy of STRUCT. |
|
STRUCTs in Liberty BASIC are always global. You cannot pass a struct as a parameter to a SUB or FUNCTION. Is that what you were hoping to be able to do?
Quote:| I don't understand why specifying [10] in the code doesn't save 10. |
|
You berated me the other day for not reading all of your messages, now you're not reading all of mine! I wrote: "strings stored in a CHAR member are assumed to be NUL-terminated ... so CHAR[12] will hold at most an 11-character string."
Richard.
|
|
|
|
tsh73
Full Member
member is offline


Gender: 
Posts: 210
|
 |
Re: struct type ptr
« Reply #22 on: Nov 21st, 2015, 03:57am » |
|
Quote:| Also, I found out that CHAR[10] really only stores a string of 9 characters. I guess the rest is overhead? I don't understand why specifying [10] in the code doesn't save 10. |
|
ABS of API#5 says Quote:The GetWindowTextA function also requires an argument that specifies the length of the string buffer. We can get the length with the LEN() function, like this:
length=len(Caption$) + 1
We add 1 to the length argument because Liberty BASIC adds a null termination character to strings passed into API calls. |
|
Also, wikipedia::Null-terminated string
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #23 on: Nov 21st, 2015, 08:51am » |
|
Ok, ok. At least I only make simple mistakes. 
The old "$" specification problem. The error message was telling me, but I wasn't listening.
I thought I tried struct as GLOBAL but ... Oh well, I have an eye doctor appointment coming up. 
The last character at the end of the OUTPUT (in Notepad) looks like a "D" I haven't looked at it with anything else. I was thinking how did a CR get there?
PS. Richard, I don't "berate". I just gently "chide."
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #24 on: Nov 21st, 2015, 09:15am » |
|
I remember now.
tsh73 posted (on that "other" forum) that the API puts a CHECKSUM on the end.
The last 2 bytes are the checksum. (The least significant byte of the sum of all the ASCII values.)
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #25 on: Nov 21st, 2015, 09:39am » |
|
I found out that CHAR[32766] is the largest that works with the API (or is it a limit of CHAR[]?) That's plenty of room for INI stuff. I suppose there's a problem with running out of something while the program is running if the STRUCT gets too large.
Its a little clunky, because the name of the STRUCT is coded into the FUNCTION, but I envision several specific FUNCTIONs with several specific STRUCTs writing to the same INI file.
Maybe obfuscation isn't so clunky after all? :D
Code:
if right$(DefaultDir$,1)<>"\" then
DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"
print inifile$
struct structName, keychars$ as CHAR[32766] ' fails when CHAR[32766] is exceeded
ret = WriteINIStruct1("settings","config","0123456789:",inifile$)
print "ret from write: ";ret
print "Got this: ->"+GetINIStruct1$("settings","config",inifile$)+"<- (from GetINIStruct1$)"
end
function WriteINIStruct1(SectionName$,KeyName$,KeyChars$,inifile$)
' Returns true (1) if nothing wrong or false (0) if a problem
'code by Richard Russell
structName.keychars$.struct = KeyChars$
size = len(structName.struct)
calldll #kernel32, "WritePrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
WriteINIStruct1 = ret
end function
function GetINIStruct1$(SectionName$,KeyName$,inifile$)
' Returns string value if nothing wrong or NULL if a problem
'code by Richard Russell
size = len(structName.struct)
calldll #kernel32, "GetPrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
if ret = 0 then GetINIStruct1$ = "" : exit function
GetINIStruct1$ = structName.keychars$.struct
end function
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: struct type ptr
« Reply #26 on: Nov 21st, 2015, 10:00am » |
|
on Nov 21st, 2015, 09:39am, pnlawrence wrote:| I found out that CHAR[32766] is the largest that works with the API (or is it a limit of CHAR[]?) |
|
I'm really not sure what you are trying to achieve. If you are storing a single string, especially if it is quite a long string, using a STRUCT isn't a particularly appropriate method. For example it stores more than twice as much data in the INI file as it needs to (each character of the string gets expanded to two hex characters).
If your objective is to obfuscate the string, storing it as hex will defeat only the most simplistic attempts at reading it. Many people will immediately recognise hex text, and either be able to read it 'by inspection' or simply copy-and-paste it into their favourite hex editor.
A trivial encryption technique, like XOR-ing each character of the string with a pseudo-random key, would be much more effective and not waste space in the file. STRUCTs wouldn't be involved at all.
Richard.
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #27 on: Nov 21st, 2015, 10:46am » |
|
Not concerned with file size. "Many people" are not part of my target audience. Some folks just think its fun to poke around and see what they can do.
Also, I like it that the "fields" of the STRUCT are not delineated in the file.
Of course one wouldn't write a 32K section to an INI file, but that is a tested limit.
I used the word "obfuscation" instead of "encryption" for a reason. Not even trying to hide it in plain site.
If the STRUCT(s) look like the following, then I think the INI file data would be obscured well with little programming effort. And there's the checksum, although that's not much of a deterrent, to contend with if one just changes a character.
Code:
STRUCT startup, keychars$ as CHAR[12], numUsers as long, posX as ulong, posY as ulong, mainDataFilename$ as CHAR[32], thumbDrivePresent as boolean, screenSizeHeight as ulong, screenSizeWidth as ulong
STRUCT currentUser, userName$ as CHAR[12], userDescription$ as CHAR[257]
Write these in separate sections of an INI file, and Bob's your uncle. (Bob is your uncle, isn't he? :D )
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #28 on: Nov 22nd, 2015, 12:21am » |
|
Posted the following to the other forum, too.
My version using FUNCTIONS. (Thanks to R.R. and tsh73 for debugging.)
Code:
'===========================================
' WritePrivateProfileStructA Demo
'===========================================
' Acknowledgements to the original authors
' Submitted by pnlawrence 11/21/2015
' This is only one example on how to perform INI file Section writing with a STRUCT.
' Of course, the STRUCT(s) can be rewritten and the FUNCTION(s)
' can be slightly rewritten to return almost any INI file data.
if right$(DefaultDir$,1)<>"\" then
DefaultDir$=DefaultDir$+"\"
end if
inifile$ = DefaultDir$ + "JunkINIstruct.ini"
print inifile$
' STRUCT can be created however required with many different types included
' nothing in the resulting INI file section delineates the different parts of the STRUCT
' the resulting INI file section also includes a checksum to detect changes
' the resulting INI file section is more than double the original total length of the values written
' because each input character string/value is written as double-digit ASCII + nul termination + checksum
' the STRUCT is GLOBAL
struct structName, keychars$ as CHAR[12] ' fails when CHAR[32766] is exceeded
print "Return from write: "; WriteINIStruct("settings","config","0123456789:",inifile$)
print "Return from get: ->"+GetINIStruct$("settings","config",inifile$)+"<-"
end
'===========================================
' FUNCTIONS
'===========================================
function WriteINIStruct(SectionName$,KeyName$,KeyChars$,inifile$)
' Returns true (1) if nothing wrong or false (0) if a problem
'code by Richard Russell
structName.keychars$.struct = KeyChars$
size = len(structName.struct)
calldll #kernel32, "WritePrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
WriteINIStruct = ret
end function
function GetINIStruct$(SectionName$,KeyName$,inifile$)
' Returns string value if nothing wrong or NULL if a problem
'code by Richard Russell
size = len(structName.struct)
calldll #kernel32, "GetPrivateProfileStructA", _
SectionName$ as ptr, _ ' Section name
KeyName$ as ptr, _ ' Key name
structName as struct, _ ' Structure
size as ulong, _ ' Size of structure
inifile$ as ptr, ret as long
if ret = 0 then GetINIStruct$ = "" : exit function
GetINIStruct$ = structName.keychars$.struct
end function
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline


Posts: 1348
|
 |
Re: struct type ptr
« Reply #29 on: Nov 22nd, 2015, 8:03pm » |
|
on Nov 22nd, 2015, 12:21am, pnlawrence wrote:| Posted the following to the other forum |
|
I trust you explained, in 'the other place', why you are using a STRUCT to store a string. I wouldn't want anybody to be misled into thinking it was preferable to using WritePrivateProfileString / GetPrivateProfileString (in normal circumstances).
Richard.
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #30 on: Nov 23rd, 2015, 12:16am » |
|
They wouldn't listen anyway. They think I'm being difficult. I'll probably get banned, too.
|
|
Logged
|
|
|
|
AAW
New Member
member is offline


Posts: 22
|
 |
Re: struct type ptr
« Reply #31 on: Nov 23rd, 2015, 10:33am » |
|
on Nov 23rd, 2015, 12:16am, pnlawrence wrote:They wouldn't listen anyway. They think I'm being difficult. I'll probably get banned, too. |
|
When you wrote, "Apparently, you think I'm being difficult." I responded, "I reread my messages and I do not see anything that implies that I think you are being difficult. I am trying to be helpful."
In order to help you, I updated articles on LBPE. Anatoly created a new, in-depth demo for you, and Rod and I made suggestions of other ways you could accomplish your goal. I suggested a simple Rot13 encryption to obfuscate your text in WritePrivateProfileString.
I can find no place AT ALL where anybody indicates that you are being difficult, that we don't listen to you, and certainly not that you are about to be banned. I am completely confused. We've all tried to be polite and helpful.
I am sorry were were unable to help you do exactly as you wanted, but we tried.
|
|
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline


Posts: 93
|
 |
Re: struct type ptr
« Reply #32 on: Nov 23rd, 2015, 10:49am » |
|
Quote: Anatoly created a new, in-depth demo for you
|
|
A link please Dear Madam, I will appreciate that.
Regards Sarmed
|
| « Last Edit: Nov 23rd, 2015, 11:05am by SarmedNafi » |
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline


Posts: 93
|
 |
Re: struct type ptr
« Reply #33 on: Nov 23rd, 2015, 10:54am » |
|
Dear pnlawrence,
I have a question if you please. What is the benefits of using API for creating an initial file (.ini)? Why not using a normal sequential file? as I always did?
Regards Sarmed
|
|
Logged
|
|
|
|
joker
Global Moderator
member is offline


Gender: 
Posts: 157
|
 |
Re: struct type ptr
« Reply #34 on: Nov 23rd, 2015, 11:10am » |
|
Hey, Alyce, it was a joke. We're free to joke around on this forum.
Hey, Alyce, how come you can freely post on this forum for Liberty Basic Booster AKA LBB, about things that happen on the LB forum but it is "against the rules" for ANYONE to do the reverse? I'm just curious.
Wouldn't it be nice if Richard could comment on topics of interest to LBB on the LB forum? It is kind of difficult with the current arrangement.
I'm sure that Richard could have had several helpful suggestions with recent posts, but I don't think he's on the list of members with posting privileges. (Actually, he did comment, but he had to do it on this forum only. Remember that? I admit to copying text from LB to LBB forum, so there's your opportunity with the broken rule.)
I've read all the tiring posts about "promoting" etc., but I fail to see the difference between "promoting" Liberty Basic Booster and "promoting" languages like "Visual Basic" or "C" or "C++" or "Pascal" or etc. I'm purty sure those are OK to write about on that forum.
Can you explain how "promoting" those other languages are OK on the LB forum, but no one can even obliquely mention Liberty Basic Booster? (You surreptitiously deleted a forum post of mine because I obliquely mentioned Liberty Basic Booster.)
I'm just curious.
PS. Feel free to comment here, because I'm hoping to clear the air and get these BASIC programs back into a cooperative state instead of stuck in 2006.
|
|
Logged
|
|
|
|
|