Space in preference string

Just starting out? Need help? Post your questions and find answers here.
BarryG
Addict
Addict
Posts: 4219
Joined: Thu Apr 18, 2019 8:17 am

Re: Space in preference string

Post by BarryG »

AZJIO wrote: Sun Sep 08, 2024 5:23 amdoes it work as fast?
I just use CreateFile, ReadFile, WriteString, and ReadString. Nothing fancy, but it means the format is exact.
AZJIO
Addict
Addict
Posts: 2224
Joined: Sun May 14, 2017 1:48 am

Re: Space in preference string

Post by AZJIO »

First try

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)
EndIf
attempt number two

Code: 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)
EndIf
Last edited by AZJIO on Sun Sep 08, 2024 3:58 pm, edited 1 time in total.
Axolotl
Addict
Addict
Posts: 872
Joined: Wed Dec 31, 2008 3:36 pm

Re: Space in preference string

Post by Axolotl »

Here is another (good) one....
kenmo's ini.pbi

@AZJIO: No offense, but please look at the typo: Groop -> Group
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Space in preference string

Post by le_magn »

there are in the forum several workarounds and alternative procedures to the purebasic preference library, but that doesn't take away from the fact that in my opinion it is a bug, readpreference is not normal that it deletes all the spaces to the left of the string or is it?
Image
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Space in preference string

Post by le_magn »

Again today in one of my apps I was going crazy trying to find where the problem was, and the problem is always the preference function that removes spaces at the beginning of the field, I always have to come up with something every time to work around the problem, @Fred please report this as a bug, I didn't see written anywhere that the preference library cuts you spaces from strings
Image
User avatar
Kiffi
Addict
Addict
Posts: 1509
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: Space in preference string

Post by Kiffi »

le_magn wrote: Tue Nov 05, 2024 4:27 pm@Fred please report this as a bug
We are already in the bug forum.
Hygge
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Space in preference string

Post by le_magn »

Kiffi wrote: Tue Nov 05, 2024 4:43 pm
le_magn wrote: Tue Nov 05, 2024 4:27 pm@Fred please report this as a bug
We are already in the bug forum.
Yes, but before in the title of the discussion it was BUG and now it's not there, that's why I thought maybe it was discarded and not considered as a bug
Image
Fred
Administrator
Administrator
Posts: 18350
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Space in preference string

Post by Fred »

I don't think it's a bug, as if you are using a prefs file, it meant to be manually edited so spaces shouldn't be relevant. You can still use a special char or put the string inside quotes to be sure to preserve them.
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Space in preference string

Post by le_magn »

Thanks for the reply Fred. yes I use such a system I encapsulate the initial spaces and then I make an unescape, but it is not the most intuitive thing in the world 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, at least if someone else runs into this thing(which for me is a bug not being reported in the guide) at least he does not go crazy to figure out where the problem is, thanks for everything you are always very kind :)
Image
AZJIO
Addict
Addict
Posts: 2224
Joined: Sun May 14, 2017 1:48 am

Re: Space in preference string

Post by AZJIO »

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
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.
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Space in preference string

Post by le_magn »

AZJIO 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.
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 explanation
Image
Post Reply