Jump to content

Ini+Ex Functions - exceed 32kb limit


SmOke_N
 Share

Recommended Posts

  • Moderators

Sometimes I see posts where people are complaining about the 32kb limit on IniReadSetion. I never did understand why you would have a section that was 32kb's...

One of my string parsing functions reads and writes to an ini, well for the first time ever, the section was 34.x kbs and I couldn't understand for the longest time (about 10 trials of re-writing different things) why I wasn't getting all the values... Just bits and pieces it seemed. I never check for anything other than if IniReadSection is an array... But then I thought to look at the size... and their lay the problem.

I wrote a really slow IniReadSection for someone else 2 or so months ago that had this problem, and to be honest, it was 2000 times slower than the current released one that Valik wrote...

This didn't suite my needs either, as every second counts :P ... So I wrote another one, This one isn't near as fast as Valiks for obvious reasons, but it did the trick 20x's faster than the last one I wrote.

Hope it helps someone...

Update: - 2011/05/18 - SmOke_N

Changed: _IniReadSectionEx() - Changed all existing functions; hopefully more proficient; thanks llewxam

Old Code:

Func _IniDeleteEx($hFile, $vSection, $vKey = '')
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniDelete($hFile, $vSection, $vKey)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If $vKey = '' Then
        $sString = StringRegExpReplace($sString, '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*(\r\n)+' & StringReplace($aData[0], '\', '\\'), @LF & @CRLF)
    Else
        $sString = StringRegExpReplace($aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=.*?(?m:\r\n|$)', @LF)
    EndIf
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|(\r\n)+$|\[$', '')
    $sString = StringRegExpReplace($sString, '(\r\n){3}', @CRLF)
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFunc

Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
    If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then
        If StringRegExp($sString, '(?s)\r\n$') = 0 Then
            $sString &= @CRLF & '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        Else
            $sString &= '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        EndIf
        FileClose(FileOpen($hFile, 2))
        Return FileWrite($hFile, $sString)
    EndIf
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
        Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
            '(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
        $aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
    Else
        $aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
    EndIf
    $sString = StringRegExpReplace(@LF & $sString & _
        '[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFunc

Func _IniReadSectionNamesEx($hFile)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then
        Local $aNameRead = IniReadSectionNames($hFile)
        If @error Then Return SetError(@error, 0, '')
        Return $aNameRead
    EndIf
    Local $aSectionNames = StringRegExp(@CRLF & FileRead($hFile) & @CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
    If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
    Local $nUbound = UBound($aSectionNames)
    Local $aNameReturn[$nUbound + 1]
    $aNameReturn[0] = $nUbound
    For $iCC = 0 To $nUBound - 1
        $aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
    Next
    Return $aNameReturn
EndFunc

Func _IniReadSectionEx($hFile, $vSection)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then 
        Local $aSecRead = IniReadSection($hFile, $vSection)
        If @error Then Return SetError(@error, 0, '')
        Return $aSecRead
    EndIf
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
    Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
    Local $aSection[$nUBound +1][2]
    $aSection[0][0] = $nUBound
    For $iCC = 0 To $nUBound - 1
        $aSection[$iCC + 1][0] = $aKey[$iCC]
        $aSection[$iCC + 1][1] = $aValue[$iCC]
    Next
    Return $aSection
EndFunc

Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
    If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
    If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
    Return $aRead[0]
EndFunc

; New code with changes, be sure to test if you have doubts. I only moderately tested.

; The IniRead* functions now accept a passed string ( like from a FileRead() or ClipPut() etc... )

; change added - SmOke_N - 2011/05/18
Func _IniDeleteEx($s_file, $s_section, $s_key = "")

    If Not FileExists($s_file) Then Return SetError(-1, 0, 0)

    Local $i_size = FileGetSize($s_file)

    Local $i_delete = 0
    If $i_size < 31 Then
        $i_delete = IniDelete($s_file, $s_section, $s_key)
        Return SetError(@error, 0, $i_delete)
    EndIf

    ; is file read only
    If StringInStr(FileGetAttrib($s_file), "R") Then
        Return SetError(-2, 0, 0)
    EndIf

    Local $s_fread = FileRead($s_file)

    ; find out if section exist, if so get data
    Local $s_secpatt = "(?si)(?:^|\v)(\h*\[\h*\Q"
    $s_secpatt &= $s_section
    $s_secpatt &= "\E\h*\].*?)(?:\z|\v\v?\[)"
    Local $a_data = StringRegExp($s_fread, $s_secpatt, 1)
    Local $f_dataexists = Not @error

    If Not $f_dataexists Then Return 1

    Local $h_open, $i_write = 0
    If $s_key = "" Then
        If $s_fread = $a_data[0] Then
            $h_open = FileOpen($s_file, 2)
            If $h_open = -1 Then Return SetError(-3, 0, 0)
            FileClose($h_open)
            Return 1
        EndIf
        $s_fread = StringReplace($s_fread, $a_data[0], "", 1, 1)
        $h_open = FileOpen($s_file, 2)
        If $h_open = -1 Then Return SetError(-3, 0, 0)
        $i_write = FileWrite($h_open, $s_fread)
        FileClose($h_open)
        If Not $i_write Then Return SetError(-4, 0, 0)
        Return 1
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    Local $a_key, $f_found = False, $s_write
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="

    For $iline = 1 To $a_lines[0]

        If $a_lines[$iline] = "" Then ContinueLoop

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Or $s_key <> $a_key[0] Then
            $s_write &= $a_lines[$iline] & @CRLF
            ContinueLoop
        EndIf

        $f_found = True
    Next

    If Not $f_found Then Return 1

    $s_fread = StringReplace($s_fread, $a_data[0], $s_write)

    Local $h_open = FileOpen($s_file, 2)
    $i_write = FileWrite($h_open, $s_fread)
    FileClose($h_open)

    Return $i_write
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniWriteEx($s_file, $s_section, $s_key, $s_value)

    If Not $s_file Then Return SetError(-1, 0, 0)

    Local $f_exists = FileExists($s_file)
    If Not $f_exists Then
        FileClose(FileOpen($s_file, 2))
    EndIf

    Local $i_write = 0
    Local $i_size = FileGetSize($s_file) / 1024

    ; if the file is smaller than 32kb, no need for regex
    If $i_size <= 31 Then
        $i_write = IniWrite($s_file, $s_section, $s_key, $s_value)
        Return SetError(@error, 0, $i_write)
    EndIf

    ; is file read only
    If $f_exists Then
        If StringInStr(FileGetAttrib($s_file), "R") Then
            Return SetError(-2, 0, 0)
        EndIf
    EndIf

    Local $s_fread = FileRead($s_file)
    Local $s_write = ""

    ; find out if section exist, if so get data
    Local $s_secpatt = "(?si)(?:^|\v)(\h*\[\h*\Q"
    $s_secpatt &= $s_section
    $s_secpatt &= "\E\h*\].*?)(?:\z|\v\v?\[)"
    Local $a_data = StringRegExp($s_fread, $s_secpatt, 1)
    Local $f_dataexists = Not @error

    Local $s_write = ""

    ; if section doesn't exist; append
    If Not $f_dataexists Then
        If $s_fread Then
            If StringRight($s_fread, 2) <> @CRLF Then
                $s_write &= @CRLF
            EndIf
        EndIf

        $s_write &= "[" & $s_section & "]" & @CRLF
        $s_write &= $s_key & "=" & $s_value & @CRLF

        Return FileWrite($s_file, $s_write)
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    Local $a_key, $f_changed = False
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="

    For $iline = 1 To $a_lines[0]

        If $a_lines[$iline] = "" Then ContinueLoop

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Or $s_key <> $a_key[0] Then
            $s_write &= $a_lines[$iline] & @CRLF
            ContinueLoop
        EndIf

        $f_changed = True
        $s_write &= $s_key & "=" & $s_value & @CRLF

    Next

    If Not $f_changed Then
        If StringRight($s_fread, 2) <> @CRLF Then
            $s_write &= @CRLF
        EndIf
        $s_write &= $s_key & "=" & $s_value & @CRLF
    EndIf

    $s_fread = StringReplace($s_fread, $a_data[0], $s_write)

    Local $h_open = FileOpen($s_file, 2)
    $i_write = FileWrite($h_open, $s_fread)
    FileClose($h_open)

    Return $i_write
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniReadSectionNamesEx($v_file)

    If Not $v_file Then Return SetError(-1, 0, 0)

    Local $f_exists = FileExists($v_file)

    Local $i_size, $a_secs

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $a_secs = IniReadSectionNames($v_file)
            If @error Then Return SetError(@error, 0, 0)
            If Not IsArray($a_secs) Then Return SetError(-2, 0, 0)
            Return $a_secs
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

    Local $s_secpatt = "(?m)(?:^|\v)\h*\[\h*(.*?)\h*\]"
    Local $a_secsre = StringRegExp($s_fread, $s_secpatt, 3)
    If @error Then Return SetError(-3, 0, 0)

    Local $i_ub = UBound($a_secsre)
    Local $a_secret[$i_ub + 1] = [$i_ub]

    For $isec = 0 To $i_ub - 1
        $a_secret[$isec + 1] = $a_secsre[$isec]
    Next

    Return $a_secret
EndFunc

; change added - SmOke_N - 2011/05/17
Func _IniReadSectionEx($v_file, $s_section)

    If Not $v_file Then Return SetError(-1, 0, 0)

    Local $f_exists = FileExists($v_file)

    Local $i_size, $a_secread

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $a_secread = IniReadSection($v_file, $s_section)
            If @error Then Return SetError(@error, 0, 0)
            If Not IsArray($a_secread) Then Return SetError(-2, 0, 0)
            Return $a_secread
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

    ; data between sections or till end of file
    Local $s_datapatt = "(?is)(?:^|\v)(?!;|#)\h*\[\h*\Q"
    $s_datapatt &= $s_section
    $s_datapatt &= "\E\h*\]\h*\v+(.*?)(?:\z|\v\h*\[)"
    Local $a_data = StringRegExp($s_fread, $s_datapatt, 1)
    If @error Then Return SetError(-3, 0, 0)

    ; sanity check for inf people
    If Not StringInStr($a_data[0], "=", 1, 1) Then
        Return SetError(-4, 0, 0)
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    ; prevent capturing commented keys
    Local $a_key, $a_value
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="
    Local $s_valpatt = "\h*=\h*(.*)"
    Local $a_secs[$a_lines[0] + 1][2], $i_add = 0

    For $iline = 1 To $a_lines[0]

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Then ContinueLoop

        $s_valpatt = "\h*=\h*(.*)"

        $a_value = StringRegExp($a_lines[$iline], $s_valpatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_key[0], 1) = '"' And StringRight($a_key[0], 1) = '"' Then
            $a_key[0] = StringTrimLeft(StringTrimRight($a_key[0], 1), 1)
        EndIf
        If StringLeft($a_value[0], 1) = '"' And StringRight($a_value[0], 1) = '"' Then
            $a_value[0] = StringTrimLeft(StringTrimRight($a_value[0], 1), 1)
        EndIf

        $i_add += 1
        $a_secs[$i_add][0] = $a_key[0]
        $a_secs[$i_add][1] = $a_value[0]
    Next

    If Not $i_add Then Return SetError(-5, 0, 0)

    ; cleanup return array
    ReDim $a_secs[$i_add + 1][2]
    $a_secs[0][0] = $i_add

    Return $a_secs
EndFunc

; change added - SmOke_N - 2011/05/18
Func _IniReadEx($v_file, $s_section, $s_key, $v_default = -1)

    If Not $v_file Then Return SetError(-1, 0, 0)

    If $v_default = -1 Or $v_default = Default Then
        $v_default = ""
    EndIf

    Local $f_exists = FileExists($v_file)

    Local $i_size, $s_read

    If $f_exists Then
        $i_size = FileGetSize($v_file) / 1024

        ; if the file is smaller than 32kb, no need for regex
        If $i_size <= 31 Then
            $s_read = IniRead($v_file, $s_section, $s_key, $v_default)
            Return $s_read
        EndIf
    EndIf

    Local $s_fread
    If Not $f_exists Then
        ; string of data was passed
        $s_fread = $v_file
    Else
        $s_fread = FileRead($v_file)
    EndIf

    ; data between sections or till end of file
    Local $s_datapatt = "(?is)(?:^|\v)(?!;|#)\h*\[\h*\Q"
    $s_datapatt &= $s_section
    $s_datapatt &= "\E\h*\]\h*\v+(.*?)(?:\z|\v\h*\[)"
    Local $a_data = StringRegExp($s_fread, $s_datapatt, 1)
    If @error Then Return SetError(-2, 0, 0)

    ; sanity check for inf people
    If Not StringInStr($a_data[0], "=", 1, 1) Then
        Return SetError(-3, 0, 0)
    EndIf

    ; since we stop at cr/lf then lets just split
    Local $a_lines
    If StringInStr($a_data[0], @CRLF, 1, 1) Then
        $a_lines = StringSplit(StringStripCR($a_data[0]), @LF)
    ElseIf StringInStr($a_data[0], @LF, 1, 1) Then
        $a_lines = StringSplit($a_data[0], @LF)
    Else
        $a_lines = StringSplit($a_data[0], @CR)
    EndIf

    ; prevent capturing commented keys
    Local $a_key, $a_value, $s_ret
    Local $s_keypatt = "\h*(?!;|#)(.*?)\h*="
    Local $s_valpatt = "\h*=\h*(.*)"

    For $iline = 1 To $a_lines[0]

        $a_key = StringRegExp($a_lines[$iline], $s_keypatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_key[0], 1) = '"' And StringRight($a_key[0], 1) = '"' Then
            $a_key[0] = StringTrimLeft(StringTrimRight($a_key[0], 1), 1)
        EndIf

        If $a_key[0] <> $s_key Then ContinueLoop

        $s_valpatt = "\h*=\h*(.*)"

        $a_value = StringRegExp($a_lines[$iline], $s_valpatt, 1)
        If @error Then ContinueLoop

        If StringLeft($a_value[0], 1) = '"' And StringRight($a_value[0], 1) = '"' Then
            $a_value[0] = StringTrimLeft(StringTrimRight($a_value[0], 1), 1)
        EndIf

        $s_ret = $a_value[0]
        ExitLoop
    Next

    If Not $s_ret Then Return $v_default

    Return $s_ret
EndFunc

If you're interested in Ini encryption, you might take a look at this thread:

I might integrate these with the IniCrypt.au3 at some future time if I don't get bug feedback from the above.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Good work, it works very well :P

I made my own version of the ini functions as well some time ago, for the exact same reason.

Don't take my pic to serious...~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~You Looked, but you did not see!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Link to comment
Share on other sites

While you were playing in Chat, btw I saw that post :P

I was playing around with my version of the _Ini functions

Might need some fine tuning, but here ya go (formats the same as the built in for params)

Edit: Fixed the _IniWrite so that if the ini file doesn't exist then it is created

Edit: Fixed _IniReadSection value may contain "="

Edit: Fixed _IniWrite, if adding new key and last line in section is CRLF the CRLF line is remove

Edit: Fixed _IniReadSection return error when no "=" found

Func _IniWrite($FileName, $Section, $KeyName, $Value)
    Local $INIContents, $PosSection, $PosEndSection
    If FileExists($FileName) Then
        $INIContents = FileRead($FileName)
        If @error Then Return SetError(@error, @error, @error)

        ;Find section
        $PosSection = StringInStr($INIContents, "[" & $Section & "]")
        If $PosSection > 0 Then
            ;Section exists. Find end of section
            $PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
            ;?Is this last section?
            If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

            ;Separate section contents
            Local $OldsContents, $NewsContents, $Line
            Local $sKeyName, $Found = False
            $OldsContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
            $OldsContents = StringSplit($OldsContents, @CRLF, 1)
            ;Temp variable To find a Key
            $sKeyName = StringLower($KeyName & "=")

            ;Enumerate section lines
            For $x = 1 To $OldsContents[0]
                If StringLower(StringMid($OldsContents[$x], 1, StringLen($sKeyName))) = $sKeyName Then
                    $OldsContents[$x] = $KeyName & "=" & $Value
                    $Found = True
                EndIf
                If StringLen($OldsContents[$x]) Then $NewsContents = $NewsContents & $OldsContents[$x] & @CRLF
            Next
            If $Found Then
                ;remove last CRLF - the CRLF is at PosEndSection
                If StringRight($NewsContents, 2) = @CRLF Then $NewsContents = StringMid($NewsContents, 1, StringLen($NewsContents) - 2)
            Else
                ;key Not found - add it at the end of section
                $NewsContents = $NewsContents & $KeyName & "=" & $Value
            EndIf

            ;Combine pre-section, new section And post-section data.
            $INIContents = StringMid($INIContents, 1, $PosSection - 1) & $NewsContents & StringMid($INIContents, $PosEndSection)
        Else
            ;Section Not found. Add section data at the end of file contents.
            If StringRight($INIContents, 2) <> @CRLF And StringLen($INIContents) > 0 Then $INIContents = $INIContents & @CRLF
            $INIContents = $INIContents & "[" & $Section & "]" & @LF & $KeyName & "=" & $Value
        EndIf   ;if PosSection>0 Then
    Else
        $INIContents = "[" & $Section & "]" & @CRLF & $KeyName & "=" & $Value & @CRLF
    EndIf
    $file = FileOpen($FileName, 2)
    FileWrite($FileName, $INIContents)
    FileClose($file)
EndFunc   ;==>_IniWrite

Func _IniRead($FileName, $Section, $KeyName, $Default)
    Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

    $INIContents = FileRead($FileName)
    If @error Then Return SetError(@error, @error, @error)

    ;Find section
    $PosSection = StringInStr($INIContents, "[" & $Section & "]")
    If $PosSection > 0 Then
        ;Section exists. Find end of section
        $PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
        ;?Is this last section?
        If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

        ;Separate section contents
        $sContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
        Local $Found = False
        If StringInStr($sContents, $KeyName & "=") > 0 Then
            $Found = True
            ;Separate value of a key.
            $Value = _SeparateField($sContents, $KeyName & "=", @CRLF)
        EndIf
    EndIf
    If Not $Found Then $Value = $Default
    Return $Value
EndFunc   ;==>_IniRead

Func _IniReadSection($FileName, $Section)
    Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

    $INIContents = FileRead($FileName)
    If @error Then Return SetError(@error, @error, @error)

    ;Find section
    $PosSection = StringInStr($INIContents, "[" & $Section & "]")
    If $PosSection > 0 Then
        ;Section exists. Find end of section
        $PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
        ;?Is this last section?
        If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1
        Local $INISection = StringSplit(StringMid($INIContents, $PosSection, $PosEndSection), @CRLF)
        Local $a_Section[1][2]
        For $x = 2 To UBound($INISection) - 1
            $INISection[$x] = StringReplace($INISection[$x], @CRLF, "")
            If StringLen($INISection[$x]) Then
                ReDim $a_Section[UBound($a_Section) + 1][2]
                $a_Section[0][0] += 1
                Local $PosSep = StringInStr($INISection[$x], "=")
                If Not $PosSep Then Return SetError(-1,-1,-1)
                $a_Section[UBound($a_Section) - 1][0] = StringMid($INISection[$x], 1, $PosSep - 1)
                $a_Section[UBound($a_Section) - 1][1] = StringMid($INISection[$x], $PosSep + 1)
            EndIf
        Next
        Return $a_Section
    EndIf
    Return SetError(-1, -1, "")
EndFunc   ;==>_IniReadSection

Func _IniReadSectionNames($FileName)
    Local $INIContents, $PosSection, $PosEndSection, $sContents, $Value, $Found

    $INIContents = FileRead($FileName)
    If @error Then Return SetError(@error, @error, @error)
    $INIContents = StringSplit($INIContents, @CRLF)
    Local $a_SectionNames[1]
    For $x = 1 To $INIContents[0]
        If StringLeft($INIContents[$x], 1) = "[" And StringRight($INIContents[$x], 1) = "]" Then
            ReDim $a_SectionNames[UBound($a_SectionNames) + 1]
            $a_SectionNames[0] += 1
            $a_SectionNames[UBound($a_SectionNames) - 1] = StringMid($INIContents[$x], 2, StringLen($INIContents[$x]) - 2)
        EndIf
    Next
    Return $a_SectionNames
EndFunc   ;==>_IniReadSectionNames

Func _IniDelete($FileName, $Section, $KeyName = "")
    Local $INIContents, $PosSection, $PosEndSection
    
    $INIContents = FileRead($FileName)
    If @error Then Return SetError(@error, @error, @error)

    ;Find section
    $PosSection = StringInStr($INIContents, "[" & $Section & "]")
    If $PosSection > 0 Then
        ;Section exists. Find end of section
        $PosEndSection = StringInStr(StringMid($INIContents, $PosSection + 1), "[") + ($PosSection - 2)
        ;?Is this last section?
        If $PosEndSection = 0 Then $PosEndSection = StringLen($INIContents) + 1

        ;Separate section contents
        Local $OldsContents, $NewsContents, $Line
        Local $sKeyName, $Found = False
        $OldsContents = StringMid($INIContents, $PosSection, $PosEndSection - $PosSection)
        If Not StringLen($KeyName) Then
            $INIContents = StringReplace($INIContents, $OldsContents, "")
            _WriteStringAsIni($FileName, $INIContents)
            Return 1
        EndIf

        ;Temp variable To find a Key
        $sKeyName = StringLower($KeyName & "=")
        $OldsContents = StringSplit($OldsContents, @CRLF, 1)
        Local $Found = False
        ;Enumerate section lines
        For $x = 1 To $OldsContents[0]
            If StringLower(StringMid($OldsContents[$x], 1, StringLen($sKeyName))) = $sKeyName Then
                $Found = True
                ContinueLoop
            EndIf
            $NewsContents = $NewsContents & $OldsContents[$x] & @CRLF
        Next
        If $Found Then
            ;remove last CRLF - the CRLF is at PosEndSection
            If StringRight($NewsContents, 2) = @CRLF Then $NewsContents = StringMid($NewsContents, 1, StringLen($NewsContents) - 2)
        EndIf

        ;Combine pre-section, new section And post-section data.
        $INIContents = StringMid($INIContents, 1, $PosSection - 1) & $NewsContents & StringMid($INIContents, $PosEndSection)
        _WriteStringAsIni($FileName, $INIContents)
        Return 1
    EndIf
    Return 0
EndFunc   ;==>_IniDelete

;Separates one field between sStart And sEnd
Func _SeparateField($sFrom, $sStart, $sEnd)
    Local $PosB = StringInStr($sFrom, $sStart)
    If $PosB > 0 Then
        $PosB = $PosB + StringLen($sStart)
        Local $PosE = (StringInStr(StringMid($sFrom, $PosB), $sEnd))
        If $PosE Then $PosE += $PosB
        If $PosE = 0 Then $PosE = StringInStr($sFrom, @CRLF)
        If $PosE = 0 Then $PosE = StringLen($sFrom) + 1
        Return StringMid($sFrom, $PosB, $PosE - $PosB)
    EndIf

EndFunc   ;==>_SeparateField

Func _WriteStringAsIni($FileName, $INIContents)
    $file = FileOpen($FileName, 2)
    FileWrite($FileName, $INIContents)
    FileClose($file)
EndFunc   ;==>_WriteStringAsIni
Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

  • Moderators

Nice work... Quick question on your IniReadSection... what happens when the value on your section has an "=" in it, my original one I did right before this one (not the one that was 2000 x's slower) was real similar to what you did, but when I tested it, I had some value strings that had "=" in it?

Also... IniWrite Creates the file now if the file doesn't exist, on the newer releases for me...(noticed this the other day) (XP-Pro SP2)...

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Nice work... Quick question on your IniReadSection... what happens when the value on your section has an "=" in it, my original one I did right before this one (not the one that was 2000 x's slower) was real similar to what you did, but when I tested it, I had some value strings that had "=" in it?

Also... IniWrite Creates the file now if the file doesn't exist, on the newer releases for me...(noticed this the other day) (XP-Pro SP2)...

Fixed

Was alread Fixed before you replied.

Gary

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

  • Moderators

The file creation has always existed, AFAIK.

I haven't used the functions much... Just recently.

Fixed

Was alread Fixed before you replied.

Gary

:P

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 2 months later...

While you were playing in Chat, btw I saw that post ;)

I was playing around with my version of the _Ini functions

Might need some fine tuning, but here ya go (formats the same as the built in for params)

Edit: Fixed the _IniWrite so that if the ini file doesn't exist then it is created

Edit: Fixed _IniReadSection value may contain "="

Edit: Fixed _IniWrite, if adding new key and last line in section is CRLF the CRLF line is remove

Edit: Fixed _IniReadSection return error when no "=" found

I'm trying to make a _IniWriteLine($FileName, $Section, $TextLine, $Append_Or_Prepend)

Can you help me ?

Link to comment
Share on other sites

  • Moderators

I'm trying to make a _IniWriteLine($FileName, $Section, $TextLine, $Append_Or_Prepend)

Can you help me ?

Who are you asking for help?

What are you trying to do (in detail)?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Who are you asking for help?

What are you trying to do (in detail)?

I'm working in project WinBuilder (www.boot-land.net/)

I use AutoIt for making script for WinBuilder (MakeScript.script)

There is allready a command IniWriteTextLine in winBuilder but i need to to use it in AutoIt

The script in Winbuilder is like a Ini file with section

So i need a command for writing line of code in section like IniWrite

Link to comment
Share on other sites

  • Moderators

I'm working in project WinBuilder (www.boot-land.net/)

I use AutoIt for making script for WinBuilder (MakeScript.script)

There is allready a command IniWriteTextLine in winBuilder but i need to to use it in AutoIt

The script in Winbuilder is like a Ini file with section

So i need a command for writing line of code in section like IniWrite

turtle

Edit...

That explains nothing... if it's help you want, I would suggest post what you have been working on, in the support forum. If it's someone writing it for you, I'd suggest you start working on something, and if you get stuck post for help in the search forum. If it's something different you want, I suggest you explain yourself better, and post for help in the support forum. This is the scripts and scraps forum, not a can you make me forum.

Thanks for hijacking my thread ;)

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 5 months later...

I tried your script, but when I pasted in notepad I can see character (1) between ab and cd. Run the script below and look at the help file appendix ASCII characters.

MsgBox(0, 'ASCII', 'ASCII Character Code: ' & Asc(_IniRead("testIni.ini","sectionName","DaKey","")))
AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line
Link to comment
Share on other sites

I tried your script, but when I pasted in notepad I can see character (1) between ab and cd. Run the script below and look at the help file appendix ASCII characters.

and it now correctly returns "" when it's blank, and it still returns the entire string if there's actually data associated with the key in the .ini file. Is this what this line should actually have been coded as? I don't want to break anything else, though _IniRead seems to be working with the line change, and I'm certainly loathe to assume that Gary made a mistake like that...others have tested these functions and not had problems with them. I also don't know if I can test with certainty that this change in code didn't break another _ini function somewhere else in his UDF... :)

Can someone else confirm if this line was/wasn't coded incorrectly or if I'm still being dense?

Thanks

Edited by Jon
"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110
Link to comment
Share on other sites

  • 2 months later...
  • Moderators

This one may seems to be much faster:

Func _IniReadSectionEx($hFile, $vSection)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    FileWrite(@TempDir & '\IniReadSectionTemp.ini', '[' & $vSection & ']' & @CRLF & $aData[0])
    Local $aSection = IniReadSection(@TempDir & '\IniReadSectionTemp.ini', $vSection)
    FileDelete(@TempDir & '\IniReadSectionTemp.ini')
    Return $aSection
EndFunc

Leaving the first post up in case someone finds something wrong with this one.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

Damn...

Had to update it again, just noticed I didn't test to see if the new files were smaller than 32kb :whistle:

This one doesn't use anything but StringRegExp() unless the file is less than 31 kbs.

Func _IniReadSectionEx($hFile, $vSection)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 1)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
    Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
    Local $aSection[$nUBound +1][$nUBound +1]
    $aSection[0][0] = $nUBound
    For $iCC = 0 To $nUBound - 1
        $aSection[$iCC + 1][0] = $aKey[$iCC]
        $aSection[$iCC + 1][1] = $aValue[$iCC]
    Next
    Return $aSection
EndFunc

My test showed almost 3 times faster than the one in post #1.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

_IniReadEx... Same params as IniRead(), but the default param is optional

Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
    If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 1)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
    If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
    Return $aRead[0]
EndFunc

If anyone is wondering, I obviously ran into a need for them :whistle: ...

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • Moderators

I re-wrote all the others that Gary had up there as well... these don't require making a temp folder, and "should" be faster than the others...

I'm still not deleting the original post code in case someone finds bugs with these, I spent most of the time writing them not testing them...

Func _IniDeleteEx($hFile, $vSection, $vKey = '')
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniDelete($hFile, $vSection, $vKey)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If $vKey = '' Then
        $sString = StringRegExpReplace($sString, '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*(\r\n)+' & StringReplace($aData[0], '\', '\\'), @LF & @CRLF)
    Else
        $sString = StringRegExpReplace($aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=.*?(?m:\r\n|$)', @LF)
    EndIf
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|(\r\n)+$|\[$', '')
    $sString = StringRegExpReplace($sString, '(\r\n){3}', @CRLF)
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
    If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
        Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
            '(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
        $aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
    Else
        $aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
    EndIf
    $sString = StringRegExpReplace(@LF & $sString & _
        '[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadSectionNamesEx($hFile)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniReadSectionNames($hFile)
    Local $aSectionNames = StringRegExp(@CRLF & FileRead($hFile) & @CRLF, '(?s)\n\s*\[(.*?)\]s*\r', 3)
    If IsArray($aSectionNames) = 0 Then Return SetError(1, 0, 0)
    Local $nUbound = UBound($aSectionNames)
    Local $aNameReturn[$nUbound + 1]
    $aNameReturn[0] = $nUbound
    For $iCC = 0 To $nUBound - 1
        $aNameReturn[$iCC + 1] = $aSectionNames[$iCC]
    Next
    Return $aNameReturn
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadEx($hFile, $vSection, $vKey, $vDefault = -1)
    If $vDefault = -1 Or $vDefault = Default Then $vDefault = ''
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniRead($hFile, $vSection, $vKey, $vDefault)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aRead = StringRegExp(@LF & $aData[0], '(?s)(?i)\n\s*' & $vKey & '\s*=(.*?)\r', 1)
    If IsArray($aRead) = 0 Then Return SetError(2, 0, 0)
    Return $aRead[0]
EndFuncoÝ÷ Û÷b½Êyº1jëh×6Func _IniReadSectionEx($hFile, $vSection)
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniReadSection($hFile, $vSection)
    Local $sFRead = @CRLF & FileRead($hFile) & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then Return SetError(1, 0, 0)
    Local $aKey = StringRegExp(@LF & $aData[0], '\n\s*(.*?)\s*=', 3)
    Local $aValue = StringRegExp(@LF & $aData[0], '\n\s*.*?\s*=(.*?)\r', 3)
    Local $nUbound = UBound($aKey)
    Local $aSection[$nUBound +1][$nUBound +1]
    $aSection[0][0] = $nUBound
    For $iCC = 0 To $nUBound - 1
        $aSection[$iCC + 1][0] = $aKey[$iCC]
        $aSection[$iCC + 1][1] = $aValue[$iCC]
    Next
    Return $aSection
EndFunc
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I re-wrote all the others that Gary had up there as well... these don't require making a temp folder, and "should" be faster than the others...

Excellent SmOke_N.

I have copied all these and I now have IniEx.au3 in my includes folder. Thanks.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

  • Moderators

Had to fix _IniWriteEx()

Func _IniWriteEx($hFile, $vSection, $vKey, $vValue)
    If FileExists($hFile) = 0 Then FileClose(FileOpen($hFile, 2))
    Local $iSize = FileGetSize($hFile) / 1024
    If $iSize <= 31 Then Return IniWrite($hFile, $vSection, $vKey, $vValue)
    Local $sString = FileRead($hFile)
    Local $sFRead = @CRLF & $sString & @CRLF & '['
    $vSection = StringStripWS($vSection, 7)
    Local $aData = StringRegExp($sFRead, '(?s)(?i)\n\s*\[\s*' & $vSection & '\s*\]\s*\r\n(.*?)\[', 3)
    If IsArray($aData) = 0 Then
        If StringRegExp($sString, '(?s)\r\n$') = 0 Then
            $sString &= @CRLF & '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        Else
            $sString &= '[' & $vSection & ']' & @CRLF & $vKey & '=' & $vValue
        EndIf
        FileClose(FileOpen($hFile, 2))
        Return FileWrite($hFile, $sString)
    EndIf
    $aData[0] = StringRegExpReplace($aData[0], '(\r\n)+$', '')
    If StringRegExp(@LF & $aData[0] & @CRLF, '(?s)(?i)\n\s*' & $vKey & '\s*=') Then
        Local $sTempReplace = StringRegExpReplace(@LF & $aData[0] & @CR, _
            '(?s)(?i)\n\s*' & $vKey & '=.*?\r', @LF & $vKey & '=' & StringReplace($vValue, '\', '\\') & @CR)
        $aData[0] = StringRegExpReplace($sTempReplace, '^\r\n|^\s*\n|^\s*\r|\r$', '')
    Else
        $aData[0] = StringReplace($aData[0] & @CRLF & $vKey & '=' & $vValue, '\', '\\')
    EndIf
    $sString = StringRegExpReplace(@LF & $sString & _
        '[', '(?s)(?i)(^|\n)\s*\[\s*' & $vSection & '\s*\]\s*\r\n.*?\s*\[', @LF & @CRLF & '\[' & $vSection & '\]' & @CRLF & $aData[0] & @CRLF & @CRLF & '\[')
    $sString = StringRegExpReplace($sString, '(^(\r\n)+)+|^\r+|^\n+|\[$|(\r\n)+$', '')
    FileClose(FileOpen($hFile, 2))
    Return FileWrite($hFile, $sString)
EndFunc
It wasn't adding the section if the section didn't exist.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...