Re: Space in preference string
Posted: Sun Sep 08, 2024 5:26 am
I just use CreateFile, ReadFile, WriteString, and ReadString. Nothing fancy, but it means the format is exact.
http://www.purebasic.com
https://www.purebasic.fr/english/
I just use CreateFile, ReadFile, WriteString, and ReadString. Nothing fancy, but it means the format is exact.
Code: Select all
EnableExplicit
Structure ini
filepath.s
file_id.i
format.i
pos.i
EndStructure
Procedure ini_Open(*inifile.ini)
*inifile\file_id = ReadFile(#PB_Any, *inifile\filepath)
*inifile\format = ReadStringFormat(*inifile\file_id)
EndProcedure
Procedure ini_SetGroup(*inifile.ini, Group$)
Protected String$
If *inifile\file_id
FileSeek(*inifile\file_id, 0)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
; Debug "|" + String$ + "|"
If String$ = "[" + Group$ + "]"
*inifile\pos = Loc(*inifile\file_id)
; Debug "найдено"
Break
EndIf
Wend
EndIf
EndProcedure
Procedure.s ini_GetValue(*inifile.ini, Key$)
Protected String$, Result$, pos2
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
pos2 = FindString(String$, "=")
If Asc(String$) = '['
Break
EndIf
If pos2 And Left(String$, pos2 - 1) = Key$
Result$ = Mid(String$, pos2 + 1)
Break
EndIf
Wend
EndIf
ProcedureReturn Result$
EndProcedure
; Procedure ini_Close(*inifile.ini)
; CloseFile(*inifile\file_id)
; EndProcedure
Global inifile.ini
inifile\filepath = "C:\PB\Source\Current\ini\1.ini"
ini_Open(inifile)
If inifile\file_id
Debug "Size = " + Str(FileSize(inifile\filepath))
Debug "file_id = " + Str(inifile\file_id)
ini_SetGroup(inifile.ini, "fuf")
Debug "pos = " + Str(inifile\pos)
Debug ini_GetValue(inifile.ini, "param")
CloseFile(inifile\file_id)
EndIfCode: Select all
;- AZJIO 08.09.2024
EnableExplicit
; Structure CacheGroups
; name.s
; pos.i
; EndStructure
Structure ini
filepath.s
file_id.i
format.i
pos.i
; List GroupPosList.CacheGroups()
EndStructure
Procedure ini_Open(*inifile.ini)
*inifile\file_id = OpenFile(#PB_Any, *inifile\filepath)
*inifile\format = ReadStringFormat(*inifile\file_id)
EndProcedure
Procedure ini_SetGroup(*inifile.ini, Group$)
Protected String$, *start, *c.Character
If *inifile\file_id
FileSeek(*inifile\file_id, 0)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
; Debug "open"
; кешировать группы при чтении, чтобы не искать позицию.
*c + SizeOf(Character)
*start = *c
While *c\c
If *c\c = ']'
*c\c = 0
String$ = PeekS(*start)
; Debug "|" + String$ + "|"
If String$ = Group$
*inifile\pos = Loc(*inifile\file_id)
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
Default
Break
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
EndProcedure
Procedure.s ini_GetValue(*inifile.ini, Key$)
Protected String$, tmp$, *start, *c.Character, Result$; = -2147483646
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
Break 2 ; открывается новая группа, не найдено, выпрыгиваем
Default
*start = *c
*c + SizeOf(Character)
While *c\c
If *c\c = '='
*c\c = 0
tmp$ = RTrim(PeekS(*start))
; Debug "|" + tmp$ + "|"
If tmp$ = Key$
Result$ = PeekS(*c + SizeOf(Character))
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
ProcedureReturn Result$
EndProcedure
Procedure ini_SetValue(*inifile.ini, Key$, Value$)
Protected String$, tmp$, tmp2$, *mem, filepos, *start, *c0, *c.Character, Result; = -2147483646
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
filepos = Loc(*inifile\file_id)
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
*c0 = *c
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
Break 2 ; открывается новая группа, не найдено, выпрыгиваем
Default
*start = *c
*c + SizeOf(Character)
While *c\c
If *c\c = '='
*c\c = 0
String$ = RTrim(PeekS(*start))
; Debug "|" + String$ + "|"
If String$ = Key$
tmp$ = ReadString(*inifile\file_id, *inifile\format + #PB_File_IgnoreEOL) ; читаем остаток до конца строки
FileSeek(*inifile\file_id, filepos) ; перемещаем указатель в позицию до чтения параметра
tmp2$ = Key$ + "=" + Value$ + #CRLF$
Select *inifile\format
Case #PB_Ascii
*mem = Ascii(tmp2$)
WriteData(*inifile\file_id, *mem, StringByteLength(tmp2$, #PB_Ascii))
FreeMemory(*mem)
Case #PB_UTF8
*mem = UTF8(tmp2$)
WriteData(*inifile\file_id, *mem, StringByteLength(tmp2$, #PB_UTF8))
FreeMemory(*mem)
Case #PB_Unicode
WriteString(*inifile\file_id, tmp2$, *inifile\format) ; записываем строку
EndSelect
WriteString(*inifile\file_id, tmp$, *inifile\format) ; записываем остаток
TruncateFile(*inifile\file_id)
Result = 1
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
ProcedureReturn Result
EndProcedure
; Procedure ini_Close(*inifile.ini)
; CloseFile(*inifile\file_id)
; EndProcedure
Global inifile.ini
inifile\filepath = "C:\PB\Source\Current\ini\1.ini"
ini_Open(inifile)
If inifile\file_id
Debug "Size = " + Str(FileSize(inifile\filepath))
Debug "file_id = " + Str(inifile\file_id)
ini_SetGroup(inifile.ini, "fuf")
Debug "pos = " + Str(inifile\pos)
Debug ini_GetValue(inifile.ini, "param")
Debug ini_SetValue(inifile.ini, "param", "кукареку-абракадабра")
CloseFile(inifile\file_id)
EndIfWe are already in the bug forum.
The #PB_Preference_NoSpace constant means that by default, without this constant, there is a space after the "=" sign and it is not data. A space is the separator between the "=" sign and the start of data, so all spaces are ignored until a character other than a space appears. In this case, quotes are used to define the beginning of the data when the first character at the beginning may be a space. WinAPI functions work in the same way, so this is not a special rule, this rule has been in effect for decades, it is the ini file format that you need to know. Also the tab character is a whitespace character and is also ignored.le_magn wrote: Fri Dec 20, 2024 7:14 pm and in the help file it is not specified that the initial spaces are deleted arbitrarily, I suppose it would be better to warn in the help file
Ok I understand, but since I'm a beginner in programming I don't know many things, but precisely because I didn't know if it had been specified in the help file that the spaces before the data were all eliminated I would have saved myself a big headache a while ago, now I know and I'm certainly more careful, thanks for the explanationAZJIO wrote: Fri Dec 20, 2024 9:01 pm The #PB_Preference_NoSpace constant means that by default, without this constant, there is a space after the "=" sign and it is not data. A space is the separator between the "=" sign and the start of data, so all spaces are ignored until a character other than a space appears. In this case, quotes are used to define the beginning of the data when the first character at the beginning may be a space. WinAPI functions work in the same way, so this is not a special rule, this rule has been in effect for decades, it is the ini file format that you need to know. Also the tab character is a whitespace character and is also ignored.