Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

INI Library - FAST in memory functions NO REGEX


  • Please log in to reply
48 replies to this topic
Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Updated to 1.0
> Added: Ini_Count_Sections - count the total number of sections
> Added: Ini_Count_Keys - count the total number of keys or count the number of keys in a section
> Added: Ini_Get_Key_Value_No_E - get the value of a key
> Added: Ini_AutoKey_List_High_E/Low_E - add a delimiter split list of values to a section auto creating the key names based off the prefix you provide
> Added: Ini_Swap_Sections_High_E/Low_E - swap the keys and section comments of 2 sections
> Added: Default_Return options to the get key/keys/comments/size high and low E functions - if there are any errors or problems and the default return is set the default return is returned
> Changed: Create, Read, Variable_To high E functions to check if the reference number you provide is already set
> Changed: All functions that deal with checking if key values exist to only count "" as blank vs the normal "" and 0
> Changed: All of the expand functions to round the number of bytes it it will expand to prevent any possible problems when passing decimal
> Changed: All functions to use a faster section reference method - one that doesn't slow down nomater how many sections are added
> Fixed: Ini_Add_Sections_As_Keys_High_E - fixed comments not converting correctly
> Removed: Ini_Expand_Sections_High_E/Low_E and Ini_Contract_Sections - nolonger needed with the new section reference method

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Updated to 1.1
> Fixed: Ini_Count_Keys - the function would try to count all of the keys in the ini even if you specified what section you wanted to count in.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Updated to 1.2
> Added: Ini_Export_Keys_To_Globals(Reference_Number,Section,Replace_If_Exists=0,Replace_Spaces_with="_")
> Added: Ini_Check_Section_Exists_High_E(Reference_Number,Section)
> Added: Ini_Check_Section_Exists_Low_E(Reference_Number,Section)
> Added: Ini_Check_Section_Exists_No_E(Reference_Number,Section)
> Added: Ini_Check_Key_Exists_High_E(Reference_Number,Section,Key)
> Added: Ini_Check_Key_Exists_Low_E(Reference_Number,Section,Key)
> Added: Ini_Check_Key_Exists_No_E(Reference_Number,Section,Key)
> Added: Ini_Find_Key_High_E(Reference_Number,Key)
> Added: Ini_Find_Key_Low_E(Reference_Number,Key)
> Added: Ini_Find_Key_No_E(Reference_Number,Key)
> Changed: Ini_Write_High_E - added a Overwrite_If_Exists option, default is yes
> Changed: Ini_Write_High_E - added a Add_Newline_At_End option, default is no
> Changed: Ini_Write_Low_E - added a Overwrite_If_Exists option, default is yes
> Changed: Ini_Write_Low_E - added a Add_Newline_At_End option, default is no
> Fixed: Ini_Count_Keys now properly checks for sections with spaces in the section name when you specify a section

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Update:

As requested I changed the library to have 2 versions; Advanced and Basic.

The Advanced version contains all of the functions, most of which have a "High_E" "Low_E" and a "No_E" version.

The Basic version contains all of the functions minus the "Low_E" and "No_E" versions. Also, all of the "High_E" functions have been renamed to remove "High_E" from the name.

All of the functions in the Basic version are the "High_E" versions.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Updated to 1.3
> Fixed: 2 cases of local variables in the global scope

tomoe_uehara
  • Members
  • 2166 posts
  • Last active: Jun 11 2015 05:33 PM
  • Joined: 05 Sep 2009
Thank you for the update :)

bacon117
  • Members
  • 29 posts
  • Last active: Jun 03 2011 06:28 PM
  • Joined: 26 May 2010
Wow, incredible. Great job with these functions.

With your functions, how do I specify a different location for my ini files besides the script folder?

Edit: I understand now. I was confused by the reference number...

bacon117
  • Members
  • 29 posts
  • Last active: Jun 03 2011 06:28 PM
  • Joined: 26 May 2010
Can the basic file accept "-" in the key value? I am trying to set a key value to "TR11-Test" and it causes an error in the program for illegal character. I remove the - and it works. Any suggestions?

bacon117
  • Members
  • 29 posts
  • Last active: Jun 03 2011 06:28 PM
  • Joined: 26 May 2010
I forgot my function is setting the key name to "TR11-Test". The first post clearly states "-" are not allowed in the key name. I would assume this means it cannot read "-" from a key name, either. I have not tested this yet to figure it out.

It would be nice if it could. :)

Morpheus
  • Members
  • 475 posts
  • Last active: Oct 21 2014 11:08 AM
  • Joined: 31 Jul 2008
rseding91 - My sections have characters in them that are illegal for variable names. I modified your script to work with the illegal characters. Also, I was getting an error that my dynamic variable length was too long, so I trimmed the length to 200.

Ini_Read_High_E(Reference_Number,File,Correct_Errors=1,Remove_Inline_Key_Comments=0,Remove_Lone_Line_Comments=0,Remove_Inline_Section_Comments=0,Treat_Duplicate_Sections=1,Treat_Duplicate_Keys=1,Read_Blank_Sections=1,Read_Blank_Keys=1,Trim_Spaces_From_Values=0)
{
	;Treat_Duplicate_Sections
	;1 - Skip
	;2 - Append
	;3 - Replace
	;4 - Add new keys
	;Treat_Duplicate_Keys
	;1 - Skip
	;2 - Append
	;3 - Replace
	Global
	Local Has_Equal, Section, Key, P_1, P_2, Section_Skip, C_Pos, Section_Append, Ini_Read_Var, T_Sections, T_Section, E, T_LoopField, Errored_Lines, T_Value
	Local T_Section_Number
	Reference_Number = %Reference_Number%
	If (Reference_Number = "")
		Return -10
	If (Ini_%Reference_Number%_Is_Set != "")
		Return -9
	File = %File%
	FileRead,Ini_Read_Var,%File%
	If Errorlevel
		Return -11
	If (Correct_Errors = 1)
		Ini_%Reference_Number%_Fix_Errors := 1
	Else If (Correct_Errors != 0)
		Return -4
	Ini_Unicode_Modifier := A_IsUnicode ? 2 : 1
	Ini_%Reference_Number%_Is_Set := 1
	Ini_%Reference_Number%_Section_Number := 1
	Loop,Parse,Ini_Read_Var,`n,`r
	{
		If A_LoopField =
			Continue
		T_LoopField = %A_LoopField%
		If (SubStr(T_Loopfield,1,1) = ";"){
			If !Section_Skip
			{
				If !Remove_Lone_Line_Comments
				{
					If Section
						%Reference_Number%_%Section%_Lone_Line_Comments .= A_LoopField "`n"
					Else
						%Reference_Number%_First_Comments .= A_LoopField "`n"
				}
			}
			Continue
		}
		Has_Equal := InStr(A_Loopfield,"=")
		If (!Has_Equal and InStr(A_LoopField,"[") and InStr(A_LoopField,"]")){
			Section_Skip := 0
			Section_Append := 0
			P_1 := InStr(A_LoopField,"[")
			P_2 := Instr(A_LoopField,"]")
			T_Section := Section
			Section := SubStr(A_LoopField,P_1+1,P_2-P_1-1)
			Section = %Section%
[color=red]			Section := Varize(Section)
			StringLeft, Section, Section, 200[/color]
;			If InStr(Section,A_Space)
;				StringReplace,Section,Section,%A_Space%,@[email protected],A
			If (T_Section){
				If (T_Section != Section){
					If (!Read_Blank_Sections and !%Reference_Number%_%T_Section%_Lone_Line_Comments and !%Reference_Number%_%T_Section%_Comment and !%Reference_Number%_All_%T_Section%_Keys)
						E := Ini_Delete_Section_High_E(Reference_Number,T_Section)
						If E
							Return E
				}
			}
			If (Ini_%Reference_Number%_%Section%_Is_Set){
				If (Treat_Duplicate_Sections = 1){
					Section_Skip := 1
				} Else If (Treat_Duplicate_Sections = 2){
					Section_Append := 1
					If InStr(A_LoopField,";"){
						If !Remove_Inline_Section_Comments
							%Reference_Number%_%Section%_Comment .= SubStr(A_Loopfield,P_2+1)
					}
				} Else If (Treat_Duplicate_Sections = 3){
					E := Ini_Delete_Section_High_E(Reference_Number,Section)
					If E
						Return E
					Ini_Add_Section_No_E(Reference_Number,Section)
					If InStr(A_LoopField,";"){
						If !Remove_Inline_Section_Comments
							%Reference_Number%_%Section%_Comment := SubStr(A_Loopfield,P_2+1)
					}
				} Else If (Treat_Duplicate_Sections = 4){
					Section_Append := 2
				}
				Continue
			} Else {
				If InStr(A_LoopField,";"){
					If !Remove_Inline_Section_Comments
						%Reference_Number%_%Section%_Comment := SubStr(A_Loopfield,P_2+1)
				}
				Ini_Add_Section_No_E(Reference_Number,Section)
			}
			Continue
		}
		If Has_Equal
		{
			If (!Section){
				If (Ini_%Reference_Number%_Fix_Errors){
					If Errored_Lines
						Errored_Lines .= "," A_Index
					Else
						Errored_Lines .= A_Index
					Continue
				}
				VarSetCapacity(Ini_%Reference_Number%_Fix_Errors,0)
				VarSetCapacity(Ini_Unicode_Modifier,0)
				VarSetCapacity(Ini_%Reference_Number%_Is_Set,0)
				Return -1
			}
			If Section_Skip
				Continue
			Key := SubStr(A_LoopField,1,Has_Equal-1)
			Key = %Key%
			
			If InStr(Key,A_Space)
				StringReplace,Key,Key,%A_Space%,@[email protected],A
			If (InStr("`n" %Reference_Number%_All_%Section%_Keys,"`n" Key "`n")){
				If (Section_Append = 2){
					Continue
				} Else If (Section_Append = 1){
					C_Pos := InStr(A_LoopField,";")
					If (C_Pos){
						If !Remove_Inline_Key_Comments
							%Reference_Number%_%Section%_%Key%_Comment .= SubStr(A_LoopField,C_Pos)
						%Reference_Number%_%Section%_%Key%_Value .= SubStr(A_LoopField,Has_Equal+1,C_Pos-Has_Equal-1)
					} Else
						%Reference_Number%_%Section%_%Key%_Value .= SubStr(A_Loopfield,Has_Equal+1)
				} Else If (Treat_Duplicate_Keys = 1){
					Continue
				} Else If (Treat_Duplicate_Keys = 2){
					C_Pos := InStr(A_LoopField,";")
					If (C_Pos){
						If !Remove_Inline_Key_Comments
							%Reference_Number%_%Section%_%Key%_Comment .= SubStr(A_LoopField,C_Pos)
						%Reference_Number%_%Section%_%Key%_Value .= SubStr(A_LoopField,Has_Equal+1,C_Pos-Has_Equal-1)
					} Else
						%Reference_Number%_%Section%_%Key%_Value .= SubStr(A_Loopfield,Has_Equal+1)
				} Else If (Treat_Duplicate_Keys = 3){
					E := Ini_Delete_Key_High_E(Reference_Number,Section,Key)
					If E
						Return E
					%Reference_Number%_All_%Section%_Keys .= Key "`n"
					C_Pos := InStr(A_LoopField,";")
					If (C_Pos){
						If !Remove_Inline_Key_Comments
							%Reference_Number%_%Section%_%Key%_Comment := SubStr(A_LoopField,C_Pos)
						%Reference_Number%_%Section%_%Key%_Value := SubStr(A_LoopField,Has_Equal+1,C_Pos-Has_Equal-1)
					} Else
						%Reference_Number%_%Section%_%Key%_Value := SubStr(A_Loopfield,Has_Equal+1)
				}
				If (Trim_Spaces_From_Values){
					T_Value := %Reference_Number%_%Section%_%Key%_Value
					%Reference_Number%_%Section%_%Key%_Value = %T_Value%
				}
			} Else {
				C_Pos := InStr(A_LoopField,";")
				If (C_Pos){
					If !Remove_Inline_Key_Comments
						%Reference_Number%_%Section%_%Key%_Comment := SubStr(A_LoopField,C_Pos)
					%Reference_Number%_%Section%_%Key%_Value := SubStr(A_LoopField,Has_Equal+1,C_Pos-Has_Equal-1)
				} Else {
					%Reference_Number%_%Section%_%Key%_Value := SubStr(A_Loopfield,Has_Equal+1)
					If (!Read_Blank_Keys and !%Reference_Number%_%Section%_%Key%_Value and %Reference_Number%_%Section%_%Key%_Value != 0)
						Continue
				}
				If (Trim_Spaces_From_Values){
					T_Value := %Reference_Number%_%Section%_%Key%_Value
					%Reference_Number%_%Section%_%Key%_Value = %T_Value%
				}
				%Reference_Number%_All_%Section%_Keys .= Key "`n"
			}
			Continue
		}
		If (Ini_%Reference_Number%_Fix_Errors){
			If Errored_Lines
				Errored_Lines .= "," A_Index
			Else
				Errored_Lines .= A_Index
		}
	}
	VarSetCapacity(Ini_Read_Var,0)
	If Errored_Lines
		Return Errored_Lines
}

Obviously, if a person wanted to write to the ini file (I'm only reading), the variables would have to be UnVarized(), and trimming the length would not be an option.

Nice functions - VERY Fast!

BGM
  • Members
  • 199 posts
  • Last active: Jun 05 2015 06:26 PM
  • Joined: 12 Jan 2011

The documentation link seems broken.

 

How can I copy the contents of an entire section into a single variable containing the contents as just a string?


(AutoHotkey 1.1.15.00 on Windows 7 Pro x64)


BGM
  • Members
  • 199 posts
  • Last active: Jun 05 2015 06:26 PM
  • Joined: 12 Jan 2011

Well, no help here on the library, but I did figure out how to get the section text:

 

 

ini_getsectiontext(whatini, whatsection){
    sectiontext := ""
    fileread, INIall, %whatini%
    inisection := "[" . whatsection . "]"
    
    iniregex := "ms)(?<=^\[" . whatsection . "\])(?:(?!^\[).)*"
    
    ;find from the end of inisection to the next section definition or the eof
    ismatch := regexmatch(INIall, iniregex, sectiontext)    ;get the key and the value whilst excluding the comments
    if(!ismatch)
        return ""
    else
        return sectiontext
}

(AutoHotkey 1.1.15.00 on Windows 7 Pro x64)


robertcollier4
  • Members
  • 141 posts
  • Last active: Jun 28 2019 01:05 AM
  • Joined: 11 Nov 2012

Cool, have you thought about having Lexikos integrating your "better" INI methods into the main Autohotkey? Are there any disadvantages to using your methods instead of the default IniRead and IniWrite provided by Autohotkey? If not - then lets have Autohotkey use these by default in IniRead and IniWrite!



BGM
  • Members
  • 199 posts
  • Last active: Jun 05 2015 06:26 PM
  • Joined: 12 Jan 2011

+1


(AutoHotkey 1.1.15.00 on Windows 7 Pro x64)


Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010

Well, no help here on the library, but I did figure out how to get the section text:

 

 

ini_getsectiontext(whatini, whatsection){
    sectiontext := ""
    fileread, INIall, %whatini%
    inisection := "[" . whatsection . "]"
    
    iniregex := "ms)(?<=^\[" . whatsection . "\])(?:(?!^\[).)*"
    
    ;find from the end of inisection to the next section definition or the eof
    ismatch := regexmatch(INIall, iniregex, sectiontext)    ;get the key and the value whilst excluding the comments
    if(!ismatch)
        return ""
    else
        return sectiontext
}

 

 

Sorry about that. I don't get emails anymore when people respond to my posts.

 

If you still wanted to do that with the functions in the library you would use the "Get section key names" function along with a loop and then pull the comments/values of each key in the loop.