Что нового

Кодировка для IniWrite

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
2 байта = FFFF = 65535
1 байт = FF = 255
Google даёт инфу 1112064. PureBasic почему-то пишет что некоторые символы не обрабатывает. Я пока не понимаю, что там за проблема. Прочти тут, там пишут что не обрабатываются суррогатные символы внутри диапазона D800 и DFFF, как видишь они внутри диапазона 0-FFFF.
Также в AutoIt3 в 2014 году когда я тестировал регулярные выражения при использовании шестнадцатеричного представления числа больше \0xFFFF регулярным выражением не воспринимались.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
581
Репутация
70
Прочти тут, там пишут что не обрабатываются суррогатные символы внутри диапазона D800 и DFFF, как видишь они внутри диапазона 0-FFFF.
В UTF-16 суррогатная пара состоит из двух символов по 2 байта каждый. В целом 4 байта.
То что библиотечная функция не поддерживает не значит что нельзя написать свою. https://www.purebasic.fr/english/viewtopic.php?p=618657#p618657
 

AZJIO

Меценат
Меценат
Сообщения
2,891
Репутация
1,195
Мне не понятен смысл суррогатной пары или не пары выше FFFF, если UTF-16 читается по 2 байта. Если однобайтовую кодировку читать как двухбайтовую, тоже что-то получится (китайские иероглифы), но она остаётся однобайтовой, в которой автор заложил какой то текст.
Нашёл описание. UCS-2 имеет ограничение FFFF, а UTF-16 имеет 6 начальных бит для идентификации, что это не двубайтный символ и на основе этого читается как 4 байта.
 
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,483
Попробуйте эти функции:

Код:
Func _IniWriteEx($sIniFile, $sSection, $sKey, $sValue, $iUTFMode = 128)
    If BitOR($iUTFMode, 16, 32, 64, 128) <> Number(16+32+64+128) Then
        $iUTFMode = 128
    EndIf
    
    Local $sData = ""
    Local $sCRLF = @CRLF
    Local $aSplitKeyValue
    Local $iValueWasWritten = False
    Local $sReadFile = FileRead($sIniFile)
    Local $aFileArr = StringSplit(StringStripCR($sReadFile), @LF)
    Local $hFile = FileOpen($sIniFile, 10 + $iUTFMode)
    
    If $hFile = -1 Then
        Return IniWrite($sIniFile, $sSection, $sKey, $sValue)
    EndIf
    
    If @error Then
        If $sReadFile <> "" Then $sReadFile &= @CRLF
        $sData &= $sReadFile & "[" & $sSection & "]" & @CRLF
        $sData &= $sKey & "=" & $sValue
        
        FileWrite($hFile, $sData)
        FileClose($hFile)
        
        Return SetError(0, 0, 1)
    EndIf
    
    For $i = 1 To $aFileArr[0]
        If $i = $aFileArr[0] Then
            $sCRLF = ""
        EndIf
        
        $sData &= $aFileArr[$i] & $sCRLF
        
        If $aFileArr[$i] = "[" & $sSection & "]" Then
            For $j = $i+1 To $aFileArr[0]
                If $j = $aFileArr[0] Then
                    $sCRLF = ""
                EndIf
                
                If Not $iValueWasWritten Then
                    If StringRegExp(StringRegExpReplace($aFileArr[$j], '\s+=', '='), $sKey & '=') Then
                        $aSplitKeyValue = StringSplit($aFileArr[$j], "=")
                        $sData &= $aSplitKeyValue[1] & "=" & $sValue & $sCRLF
                        $iValueWasWritten = True
                    ElseIf $aFileArr[$j] = "" Then
                        $sData &= $sKey & "=" & $sValue & $sCRLF
                    ElseIf StringLeft($aFileArr[$j], 1) = "[" Or $j = $aFileArr[0] Then
                        $sData &= $aFileArr[$j] & @CRLF & $sKey & "=" & $sValue & $sCRLF
                    Else
                        $sData &= $aFileArr[$j] & $sCRLF
                    EndIf
                Else
                    $sData &= $aFileArr[$j] & $sCRLF
                EndIf
            Next
            
            ExitLoop
        ElseIf $i = $aFileArr[0] Then
            $sData &= @CRLF & "[" & $sSection & "]" & @CRLF
            $sData &= $sKey & "=" & $sValue
        EndIf
    Next
    
    FileWrite($hFile, $sData)
    FileClose($hFile)
    
    Return SetError(0, 0, 1)
EndFunc

Func _IniReadEx($sIniFile, $sSection, $sKey, $sValue = '')
    Local $aFileArr = StringSplit(StringStripCR(FileRead($sIniFile)), @LF)
    
    If @error Then
        Return SetError(1, 0, "")
    EndIf
    
    Local $aSplitKeyValue
    
    For $i = 1 To $aFileArr[0]
        If $aFileArr[$i] = '[' & $sSection & ']' Then
            For $j = $i+1 To $aFileArr[0]
                If StringLeft($aFileArr[$j], 1) = '[' Then
                    ExitLoop 2
                EndIf
                
                $aFileArr[$j] = StringRegExpReplace(StringStripWS($aFileArr[$j], 3), '\s+=', '=')
                
                If StringLeft($aFileArr[$j], StringLen($sKey)+1) = $sKey & '=' Then
                    $aSplitKeyValue = StringSplit($aFileArr[$j], '=')
                    
                    If UBound($aSplitKeyValue)-1 >= 2 Then
                        $sValue = StringStripWS($aSplitKeyValue[2], 3)
                    EndIf
                    
                    Return $sValue
                EndIf
            Next
            
            ExitLoop
        EndIf
    Next
    
    Return $sValue
EndFunc

Func _IniReadSectionEx($sIniFile, $sSection)
    Local $aFileReadArr = StringSplit(StringStripCR(FileRead($sIniFile)), @LF)
    
    If @error Then
        Return SetError(1, 0, "")
    EndIf
    
    Local $aRetArr[1][1], $iUbound, $aSplitKeyValue, $sKey, $sValue
    
    For $i = 1 To $aFileReadArr[0]
        If $aFileReadArr[$i] = "[" & $sSection & "]" Then
            For $j = $i+1 To $aFileReadArr[0]
                If StringLeft($aFileReadArr[$j], 1) = "[" Then
                    ExitLoop 2
                EndIf
                
                $aSplitKeyValue = StringSplit($aFileReadArr[$j], "=")
                
                If Not @error Then
                    $sKey = $aSplitKeyValue[1]
                    $sValue = ""
                    
                    If UBound($aSplitKeyValue)-1 >= 2 Then
                        $sValue = $aSplitKeyValue[2]
                    EndIf
                    
                    $aRetArr[0][0] += 1
                    ReDim $aRetArr[$aRetArr[0][0]+1][2]
                    $aRetArr[$aRetArr[0][0]][0] = $sKey
                    $aRetArr[$aRetArr[0][0]][1] = $sValue
                EndIf
            Next
            
            ExitLoop
        EndIf
    Next
    
    Return $aRetArr
EndFunc


Тут при записи можно указать кодировку (по аналогии с FileOpen).
 
Верх