Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include-once
- ; #INDEX# =======================================================================================================================
- ; Title .........: IniEx (1.1)
- ; Date ..........: 18.03.2011
- ; AutoIt Version : 3.3 + (development version = 3.3.6.0)
- ; Language ......: English
- ; Description ...: Extra functions for an extended ini support:
- ; - Functions to change the ini's encoding format and allow to use
- ; unicode for all ini-functions, prefered UTF-16 Little Endian since it's the fastest in AutoIt
- ; - Functions to read and write a whole ini into or from one three-dimensional array; also from a string
- ; - Functions to read keys, sections and sectionnames from a string instead of a file
- ; Remarks .......:
- ; Link ..........: http://www.autoitscript.com/forum/topic/125163-iniex-udf/
- ; Author ........: FichteFoll
- ; ===============================================================================================================================
- ; #CHANGELOG# ===================================================================================================================
- ; # 1.1
- ; - Changed: Fully imitates AutoIt's ini syntax using regex and parsing them by line
- ; (involves all _IniRead*FromString functions)
- ; ===============================================================================================================================
- ; #CURRENT# =====================================================================================================================
- ; _IniConvertToUnicode Converts encoding format of a text file to UTF-16 Little Endian
- ; _IniConvertToANSI Converts encoding format of a text file to ANSI
- ; _IniReadToArray Returns the whole ini file into one array with three dimensions
- ; _IniWriteFromArray Writes or creates an Ini out of an array
- ; _IniReadFromString Returns the value of a key in a specific section of an ini-formatted string
- ; _IniReadSectionNamesFromString Returns all keys and its values from a given section name of an ini-formatted string
- ; _IniReadSectionFromString Returns all section names of an ini-formatted string
- ; _IniReadToArrayFromString Returns the whole ini file into one array with three dimensions
- ; ===============================================================================================================================
- ; #INTERNAL_USE_ONLY# ===========================================================================================================
- ; __StringEscapeRegExp
- ; ===============================================================================================================================
- ; ###############################################################################################################################
- ; ###############################################################################################################################
- ;#Function# =====================================================================================================================
- ; Name............: _IniConvertToUnicode
- ; Description.....: Converts encoding format of a text file to UTF-16 Little Endian
- ; Syntax..........: _IniConvertToUnicode($szFile, $fCreate = True)
- ; Parameters......:
- ; $szFile - Path to text file (won't work with binary encoded files)
- ; $fCreate - [optional] The File will be created if it does not exist (default)
- ; Return values ..:
- ; Success - Returns 1 - sets @extended = 1 if the file is already encoded correctly
- ; Failure - Returns 0 - sets @error
- ; | 1 - The file does not exist (requires $fCreate = False)
- ; | 2 - The file is not a text file
- ; | 3 - Reading the file failed
- ; | 4 - Opening the file with unicode failed
- ; | 5 - Writing the file with unicode failed
- ; Author .........: FichteFoll
- ; Remarks ........: Use the related functions and _IniReadToArray or _IniWriteFromArray to access a unicode-formatted ini.
- ; If the file does not exist it will be created.
- ; Related ........: FileGetEncoding, IniRead, IniWrite, IniReadSection, IniWriteSection, IniReadSectionNames
- ; Link ...........; See on top
- ; Example ........; _IniConvertToUnicode("c:/file.ini")
- ; ===============================================================================================================================
- Func _IniConvertToUnicode($szFile, $fCreate = True)
- If Not FileExists($szFile) And $fCreate = False Then Return SetError(1)
- Local $iEncoding, $szContent, $f
- $iEncoding = FileGetEncoding($szFile)
- Switch $iEncoding
- Case 32
- Return SetExtended(1, 1) ; Nothing to be done
- Case -1
- If FileExists($szFile) Then SetError(2)
- ContinueCase
- Case Else
- $szContent = FileRead($szFile)
- If @error And FileExists($szFile) Then Return SetError(3)
- $f = FileOpen($szFile, 2 + 8 + 32) ; delete, create, utf-16 le
- If $f = -1 Then Return SetError(4)
- If FileWrite($f, $szContent) = 0 Then SetError(5, FileClose($f) * 0)
- FileClose($f)
- Return 1
- EndSwitch
- EndFunc ;==>_IniConvertToUnicode
- ;#Function# =====================================================================================================================
- ; Name............: _IniConvertToANSI
- ; Description.....: Converts encoding format of a text file to ANSI
- ; Syntax..........: _IniConvertToANSI($szFile, $fCreate = True)
- ; Parameters......:
- ; $szFile - Path to text file (won't work with binary encoded files)
- ; $fCreate - [optional] The File will be created if it does not exist (default)
- ; Return values ..:
- ; Success - Returns 1 - sets @extended = 1 if the file is already encoded correctly
- ; Failure - Returns 0 - sets @error
- ; | 1 - The file does not exist (requires $fCreate = False)
- ; | 2 - The file is not a text file
- ; | 3 - Reading the file failed
- ; | 4 - Opening the file with ANSI failed
- ; | 5 - Writing the file with ANSI failed
- ; Author .........: FichteFoll
- ; Modified........:
- ; Remarks ........: This is the oppsite of _IniConvertToUnicode. Characters that are Uincode-only will be converted to '?'.
- ; Related ........: FileGetEncoding, IniRead, IniWrite, IniReadSection, IniWriteSection, IniReadSectionNames
- ; Link ...........; See on top
- ; Example ........; _IniConvertToANSI("c:/file.ini")
- ; ===============================================================================================================================
- Func _IniConvertToANSI($szFile, $fCreate = True)
- If Not FileExists($szFile) And $fCreate = False Then Return SetError(1)
- Local $iEncoding, $szContent, $f
- $iEncoding = FileGetEncoding($szFile)
- Switch $iEncoding
- Case 0
- Return SetExtended(1, 1) ; Nothing to be done
- Case -1
- If FileExists($szFile) Then SetError(2)
- ContinueCase
- Case Else
- $szContent = FileRead($szFile)
- If @error And FileExists($szFile) Then Return SetError(3)
- $f = FileOpen($szFile, 2 + 8 + 0) ; delete, create, ansi
- If $f = -1 Then Return SetError(4)
- If FileWrite($f, $szContent) = 0 Then SetError(5)
- FileClose($f)
- Return 1
- EndSwitch
- EndFunc ;==>_IniConvertToANSI
- ; ###############################################################################################################################
- ;#Function# ============================================================================================================================================
- ; Name............: _IniReadToArray
- ; Description.....: Returns the whole ini file into one array with three dimensions
- ; Syntax..........: _IniReadToArray($szFile)
- ; Parameters......:
- ; $szFile - Path to the ini file
- ; Return values ..:
- ; Success - Returns an array containing all sections, keys and values (see Remarks)
- ; Failure - Returns 0 and sets @error = 1 if the section names could not be determined
- ; Author .........: FichteFoll
- ; Modified........:
- ; Remarks ........: On success the array has the following structure:
- ; [0][0][0] = section count
- ; [n][0][0] = nth Section name
- ; [n][0][1] = nth Section's key count
- ; [n][m][0] = nth Section's mth key's name (just like IniReadSection)
- ; [n][m][1] = nth Section's mth key's value (just like IniReadSection)
- ; If some sections could not be allocated, its key count is set to 0 which also happens if there is no key in the section.
- ; Check @extended for the total count of sections that could not be read or have 0 keys inside.
- ; Related ........: _IniWriteFromArray, IniReadSectionNames, IniReadSection
- ; Link ...........; See on top
- ; Example ........; $aArray = _IniReadToArray("c:\file.ini")
- ; For $i = 1 To $aArray[0][0][0]
- ; ConsoleWrite(StringFormat("! [%s]", $aArray[$i][0][0]) & @CRLF)
- ; For $j = 1 To $aArray[$i][0][1]
- ; ConsoleWrite(StringFormat("- %s=%s", $aArray[$i][$j][0], $aArray[$i][$j][1]) & @CRLF)
- ; Next
- ; Next
- ; ======================================================================================================================================================
- Func _IniReadToArray($szFile)
- Local $aszSections, $aReturn[1], $aszSection, $iMaxKeys = 1, $ext
- $aszSections = IniReadSectionNames($szFile)
- If @error Then Return SetError(1)
- ReDim $aReturn[$aszSections[0] + 1][$iMaxKeys + 1][2]
- $aReturn[0][0][0] = $aszSections[0]
- For $i = 1 To $aszSections[0]
- $aReturn[$i][0][0] = $aszSections[$i]
- $aszSection = IniReadSection($szFile, $aszSections[$i])
- If @error Then ; ususally no errors here, just go to next section in that case
- $aReturn[$i][0][1] = 0
- $ext += 1
- ContinueLoop
- EndIf
- $aReturn[$i][0][1] = $aszSection[0][0]
- If $aszSection[0][0] > $iMaxKeys Then
- $iMaxKeys = $aszSection[0][0]
- ReDim $aReturn[$aszSections[0] + 1][$iMaxKeys + 1][2]
- EndIf
- For $j = 1 To $aszSection[0][0]
- $aReturn[$i][$j][0] = $aszSection[$j][0]
- $aReturn[$i][$j][1] = $aszSection[$j][1]
- Next
- Next
- Return SetExtended($ext, $aReturn)
- EndFunc ;==>_IniReadToArray
- ;#Function# =====================================================================================================================
- ; Name............: _IniWriteFromArray
- ; Description.....: Writes or creates an Ini out of an array
- ; Syntax..........: _IniWriteFromArray($szFile, Const ByRef $aArray, $fUnicode = False, $fDelete = True)
- ; Parameters......:
- ; $szFile - Path to the ini file
- ; Const ByRef $aArray - The array containing the ini data; with three dimensions, 2 elements in the third and the following format:
- ; [0][0][0|1] - not relevant, can contain values from _IniReadToArray
- ; ![n][0][0] - nth section name
- ; [n][0][1] - not relevant, can contain value from _IniReadToArray
- ; ![n][m][0] - nth section's mth key name
- ; ![n][m][1] - nth section's mth key value
- ; $fUnicode - [optional] The ini will be encoded with Unicode using _IniConvertToUnicode
- ; $fDelete - [optional] The whole file gets deleted before the array will be written into it;
- ; sections will always be overwritten
- ; Return values ..:
- ; Success - Returns 1
- ; Failure - Returns 0 - sets @error
- ; | 1 - Array is badly formatted
- ; | 2 - Ini could not be converted to Unicode
- ; | 3 - Every section has failed to be written
- ; Author .........: FichteFoll
- ; Remarks ........: This function is the opposite of _IniReadToArray and compatible with its return value.
- ; If a section fails to be written @extended is set to the total count of failures.
- ; If @extended is going to be the total count of sections @error is set to 3 and 0 returned.
- ; Related ........: _IniReadFromArray, IniWriteSection
- ; Link ...........; See on top
- ; Example ........; $aArray = _IniReadToArray("c:\file.ini")
- ; $aArray[1][1][1] = "the first value of this ini has changed"
- ; _IniWriteFromArray("c:\file2.ini", $aArray, True)
- ; ===============================================================================================================================
- Func _IniWriteFromArray($szFile, Const ByRef $aArray, $fUnicode = False, $fDelete = True)
- If UBound($aArray, 0) <> 3 Or UBound($aArray, 3) <> 2 Then Return SetError(1) ; bad formatted
- If $fDelete Then FileDelete($szFile)
- If $fUnicode Then
- _IniConvertToUnicode($szFile)
- If @error Then Return SetError(2)
- EndIf
- Local $ext = 0
- For $i = 1 To UBound($aArray, 1) - 1
- Local $aszSection[1][2]
- For $j = 1 To UBound($aArray, 2) - 1
- If $aArray[$i][$j][0] = "" And $aArray[$i][$j][1] = "" Then ExitLoop ; empty entry
- ReDim $aszSection[$j+1][2]
- $aszSection[$j][0] = $aArray[$i][$j][0]
- $aszSection[$j][1] = $aArray[$i][$j][1]
- Next
- IniWriteSection($szFile, $aArray[$i][0][0], $aszSection)
- If @error Then $ext += 1
- Next
- If $ext = UBound($aArray, 1) Then Return SetError(3)
- Return SetExtended($ext, 1)
- EndFunc ;==>_IniWriteFromArray
- ; ###############################################################################################################################
- ;#Function# =====================================================================================================================
- ; Name............: _IniReadFromString
- ; Description.....: Returns the value of a key in a specific section of an ini-formatted string
- ; Syntax..........: _IniReadFromString($szInput, $szSection, $szKey, $Default)
- ; Parameters......:
- ; $szInput - The string that contains data in ini format
- ; $szSection - The sectionname (just as in IniRead)
- ; $szKey - The keyname (just as in IniRead)
- ; $Default - The default value if the key does not exist or reading failed (just as in IniRead)
- ; Return values ..:
- ; Success - Returns the read value
- ; Failure - Returns $Default
- ; Author .........: FichteFoll
- ; Remarks ........: Works for Unicode as well as for ANSI
- ; Related ........: IniRead, _IniReadSectionFromString
- ; Link ...........; See on top
- ; Example ........; $var = _IniReadFromString(StringFormat("[Sect]\r\nMyKey1=value1\r\nMyKey2=value2"), "Sect", "MyKey2", "no_value")
- ; ===============================================================================================================================
- Func _IniReadFromString($szInput, $szSection, $szKey, $Default)
- Local $szRegExpSection = "(?ix) (?<=\A)\s* \[ ([^\]]*)"
- Local $szRegExpNamedSection = "(?ix) (?<=\A)\s* \[" & __StringEscapeRegExp($szSection)
- Local $szRegExpNamedLine = "(?ix) (?<=\A)\s*(?!;) " & __StringEscapeRegExp($szKey) & " \s* = \s* (.*?) \s*(?=\Z)"
- $szInput = StringStripCR(StringRegExpReplace($szInput, "\r(?!\n)", "\r\n"))
- Local $aszLines = StringSplit($szInput, @LF), $fFound = False, $aRegMl
- For $i = 1 To $aszLines[0]
- If StringRegExp($aszLines[$i], $szRegExpNamedSection) Then
- $fFound = True
- ContinueLoop
- ElseIf $fFound Then
- If StringRegExp($aszLines[$i], $szRegExpSection) Then ExitLoop
- $aRegMl = StringRegExp($aszLines[$i], $szRegExpNamedLine, 1)
- If Not @error Then Return $aRegMl[0]
- EndIf
- Next
- Return SetError(1, 0, $Default) ; key not found
- EndFunc ;==>_IniReadFromString
- ;#Function# =====================================================================================================================
- ; Name............: _IniReadSectionNamesFromString
- ; Description.....: Returns all section names of an ini-formatted string
- ; Syntax..........: _IniReadSectionNamesFromString($szInput)
- ; Parameters......:
- ; $szInput - The string that contains data in ini format
- ; Return values ..:
- ; Success - Returns an array containing the section names; $result[0] contains the number of sections
- ; Failure - Returns 0 and sets @error = 1 which means that no sections were found, this can have several reasons
- ; Author .........: FichteFoll
- ; Remarks ........: A section does not have to contain keys
- ; Related ........: IniReadSectionNames, IniReadSection
- ; Link ...........; See on top
- ; Example ........; $result = _IniReadSectionNamesFromString(StringFormat("[Sect]\r\nMyKey1=value1\r\nMyKey2=value2"), "Sect", "MyKey2", "no_value")
- ; ===============================================================================================================================
- Func _IniReadSectionNamesFromString($szInput)
- Local $szRegExpSection = "(?ix) (?<=\n|\A)\s* \[ ([^\]]*)"
- $szInput = StringStripCR($szInput)
- Local $aRegMl = StringRegExp($szInput, $szRegExpSection, 3)
- If @error Then Return SetError(1) ; nothing found
- Local $iUBound = UBound($aRegMl), $aReturn[$iUBound + 1]
- $aReturn[0] = $iUBound
- For $i = 0 To $iUBound - 1
- $aReturn[$i + 1] = $aRegMl[$i]
- Next
- Return $aReturn
- EndFunc ;==>_IniReadSectionNamesFromString
- ;#Function# =====================================================================================================================
- ; Name............: _IniReadSectionFromString
- ; Description.....: Returns all keys and its values from a given section name of an ini-formatted string
- ; Syntax..........: _IniReadSectionFromString($szInput, $szSection)
- ; Parameters......:
- ; $szInput - The string that contains data in ini format
- ; $szSection - The section name
- ; Return values ..:
- ; Success - Returns an array containing the data;
- ; $result[0][0] will contain the number of sectins, [n][0] the key and [n][1] the value
- ; Failure - Returns 0 and sets @error = 1 meaning that the section was not found
- ; Author .........: FichteFoll
- ; Remarks ........: [0][0] can be 0 if the section has no keys, the array will not have any more elements
- ; Related ........: IniReadSection, IniWriteSection
- ; Link ...........; See on top
- ; Example ........; $result = _IniReadSectionFromString(StringFormat("[Sect]\r\nMyKey1=value1\r\nMyKey2=value2"), "Sect")
- ; ===============================================================================================================================
- Func _IniReadSectionFromString($szInput, $szSection)
- ; Using RegExp rarely does not work; using workaround by parsing the lines into an array instead
- Local $szRegExpSection = "(?ix) (?<=\A)\s* \[ ([^\]]*)"
- Local $szRegExpNamedSection = "(?ix) (?<=\A)\s* \[" & __StringEscapeRegExp($szSection)
- Local $szRegExpLine = "(?ix) (?<=\A)\s*(?!;) (.*?) \s* = \s* (.*?) \s*\Z"
- $szInput = StringStripCR(StringRegExpReplace($szInput, "\r(?!\n)", "\r\n"))
- Local $aszLines = StringSplit($szInput, @LF), $aReturn[1][2] = [[0, 0]], $fFound = False, $aRegMl, $j = 0
- For $i = 1 To $aszLines[0]
- If StringRegExp($aszLines[$i], $szRegExpNamedSection) Then
- $fFound = True
- ContinueLoop
- ElseIf $fFound Then
- If StringRegExp($aszLines[$i], $szRegExpSection) Then ExitLoop
- $aRegMl = StringRegExp($aszLines[$i], $szRegExpLine, 1)
- If @error Then ContinueLoop
- $j += 1
- $aReturn[0][0] = $j
- ReDim $aReturn[$j + 1][2]
- $aReturn[$j][0] = $aRegMl[0]
- $aReturn[$j][1] = $aRegMl[1]
- EndIf
- Next
- If $fFound = False Then Return SetError(1)
- ; If $j = 0 Then Return SetError(2) ; return empty array instead
- Return $aReturn
- EndFunc ;==>_IniReadSectionFromString
- ;#Function# ============================================================================================================================================
- ; Name............: _IniReadToArrayFromString
- ; Description.....: Returns the whole ini file into one array with three dimensions
- ; Syntax..........: _IniReadToArrayFromString($szFile)
- ; Parameters......:
- ; $szInput - The string that contains data in ini format
- ; Return values ..:
- ; Success - Returns an array containing all sections, keys and values (see Remarks)
- ; Failure - Returns 0 and sets @error = 1 if the section names could not be determined
- ; Author .........: FichteFoll
- ; Modified........:
- ; Remarks ........: On success the array has the following structure:
- ; [0][0][0] = section count
- ; [n][0][0] = nth Section name
- ; [n][0][1] = nth Section's key count
- ; [n][m][0] = nth Section's mth key's name (just like IniReadSection)
- ; [n][m][1] = nth Section's mth key's value (just like IniReadSection)
- ; If some sections could not be allocated, its key count is set to 0 which also happens if there is no key in the section.
- ; Check @extended for the total count of sections that could not be read or have 0 keys inside.
- ; Related ........: _IniReadToArray, _IniWriteToArray, _IniReadSectionNamesFromString, _IniReadSectionFromString
- ; Link ...........; See on top
- ; Example ........; $aArray = _IniReadToArrayFromString(StringFormat("[Sect]\r\nMyKey1=value1\r\nMyKey2=value2\r\n[Sect_2]\r\nYourKey1=value1"))
- ; For $i = 1 To $aArray[0][0][0]
- ; ConsoleWrite(StringFormat("! [%s]", $aArray[$i][0][0]) & @CRLF)
- ; For $j = 1 To $aArray[$i][0][1]
- ; ConsoleWrite(StringFormat("- %s=%s", $aArray[$i][$j][0], $aArray[$i][$j][1]) & @CRLF)
- ; Next
- ; Next
- ; ======================================================================================================================================================
- Func _IniReadToArrayFromString($szInput)
- Local $aszSections, $aReturn[1], $aszSection, $iMaxKeys = 1, $ext
- $aszSections = _IniReadSectionNamesFromString($szInput)
- If @error Then Return SetError(1)
- ReDim $aReturn[$aszSections[0] + 1][$iMaxKeys + 1][2]
- $aReturn[0][0][0] = $aszSections[0]
- For $i = 1 To $aszSections[0]
- $aReturn[$i][0][0] = $aszSections[$i]
- $aszSection = _IniReadSectionFromString($szInput, $aszSections[$i])
- If @error Then ; ususally no errors here, just go to next section in that case
- $aReturn[$i][0][1] = 0
- $ext += 1
- ContinueLoop
- EndIf
- $aReturn[$i][0][1] = $aszSection[0][0]
- If $aszSection[0][0] > $iMaxKeys Then
- $iMaxKeys = $aszSection[0][0]
- ReDim $aReturn[$aszSections[0] + 1][$iMaxKeys + 1][2]
- EndIf
- For $j = 1 To $aszSection[0][0]
- $aReturn[$i][$j][0] = $aszSection[$j][0]
- $aReturn[$i][$j][1] = $aszSection[$j][1]
- Next
- Next
- Return SetExtended($ext, $aReturn)
- EndFunc ;==>_IniReadToArrayFromString
- ; ###############################################################################################################################
- ; ===============================================
- ; = Internal Use Only
- ; ===============================================
- Func __StringEscapeRegExp($szExp)
- $szExp = StringRegExpReplace($szExp, "([\(\)\[\]\{\}\\\/\?\.\\|\+])", "\\$1") ; ()[]{}\/?.|+
- Return StringRegExpReplace($szExp, "(\s)", "\\s")
- EndFunc ;==>__StringEscapeRegExp
Advertisement
Add Comment
Please, Sign In to add comment