Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
FromUtf8 PROCEDURE(STRING StrIn)
DATE
outStr &STRING, AUTO ! ссылка на выходная строка
inStr &STRING, AUTO ! ссылка на входная строка
i SIGNED, AUTO ! индекс-позиция входной строки =0
j SIGNED, AUTO ! индекс-позиция выходной строки =0
! он же счётчик сконвертированных символов
in3b STRING(17) ! для 3-х байтовых символов Utf-8 последний байт
out3b STRING(17) ! символы 1251 соответственно
in2b STRING(13) ! для 2-х байтовых символов Utf-8 последний байт
out2b STRING(13) ! символы 1251 соответственно
CODE
inStr &= StrIn ! укажем ссылку-реферал на строку UTF-8 откуда
outStr &= NEW STRING(SIZE(inStr)) ! конструктор выходной строки
! или указать ссылку на строку вывода - куда
! пара массивов для 3-х байтовых символов Utf-8 последний байт
in3b = '<147><147><152><153><154><156><157><158><160><161><162><166><176><185><186><172><150>'
out3b= '<150><151><145><146><130><147><148><132><134><135><149><133><137><139><155><136><185>'
in2b = '<146><147><148><149><150><151><152><153><154><155><156><158><159>'
out2b= '<144><131><186><190><179><191><188><154><156><158><157><162><159>'
LOOP i = 1 TO SIZE(inStr) ! цикл по входной строке
j += 1 ! счётчик сконвертированных символов
IF VAL(inStr[i]) <= 07FH ! номер символа меньше 127 -Latin
outStr[j] = inStr[i] ! без конвертации в позицию новой строки
cycle ! нашли - в начало цикла
end
IF VAL(inStr[i]) = 194 ! номер след. символа 1251
i += 1 ! след символ
outStr[j] = inStr[i]
cycle ! нашли - в начало цикла
end
IF VAL(inStr[i]) = 208 ! русские символы из 2-х байт
i += 1 ! след символ
IF VAL(inStr[i]) = 129 ! буква Ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
cycle ! нашли - в начало цикла
else
IF VAL(inStr[i]) >143
outStr[j] = CHR(VAL(inStr[i]) + 48)
cycle ! нашли - в начало цикла
end
END
END
IF VAL(inStr[i]) = 209 ! русские символы
i += 1 ! след символ
IF VAL(inStr[i]) = 145 ! буква ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
cycle ! нашли - в начало цикла
else
IF VAL(inStr[i]) < 144
outStr[j] = CHR(VAL(inStr[i]) + 112)
cycle ! нашли - в начало цикла
end
END
END ! русские символы 209
! здесь проверка символов кириллицы - не русских 15 штук 2-байтовые 209,210>143
IF VAL(inStr[i]) = 209 ! НЕрусские символы 209
i += 1 ! след символ
LOOP s# = 1 TO 13 ! SIZE(in2b)
IF VAL(in3b[s#]) = VAL(inStr[i]) ! 2-байтовые
outStr[j] = out3b[s#]
break ! нашли-искать не надо
end
end ! LOOP s# = 1 TO SIZE(in2b)
END ! НЕрусские символы 209
IF VAL(inStr[i]) = 210 ! НЕрусские символы 210
i += 1 ! след символ
IF VAL(inStr[i]) = 145 !
outStr[j] = 180
cycle ! нашли - в начало цикла
end
IF VAL(inStr[i]) = 144 !
outStr[j] = 165
cycle ! нашли - в начало цикла
end
END ! НЕрусские символы 210
! ищем знаки 3-байтовые, типа номер №, многоточие... евро
IF VAL(inStr[i]) = 226 ! 3-байтовые 226 - достаточно для проверки
IF VAL(inStr[i+1]) = 132 ! 3-байтовые 132
IF VAL(inStr[i+2]) = 162 ! дублирован 162, поэтому отдельно
outStr[j] = '<153>' ! товарныйзнак
i += 2 ! след байт перескакиваем на символ
cycle ! нашли - в начало цикла
end
end ! 3-байтовые 132
i += 2 ! след байт перескакиваем на символ
LOOP s# = 1 TO 17 ! SIZE(in3b)
IF VAL(in3b[s#]) = VAL(inStr[i]) ! 3-байтовые 128,130,132
outStr[j] = out3b[s#]
break ! нашли-искать не надо
end
end ! LOOP s# = 1 TO SIZE(in3b)
end ! IF VAL(inStr[i]) = 226
END ! LOOP i = 1 TO SIZE(inStr)
! вариант возврата результата
V = CLIP (outStr) ! пробелы в конце убираем
DISPOSE (outStr) ! Освободить память в куче
RETURN V ! вернём строку
MEMBER('gar.clw') ! Это MEMBER module
FromUtf8 PROCEDURE (STRING StrIn, STRING StrOut) ! Объявление Процедуры/Функции (не прототипа)
!====================================================
! Перед точкой Врезки: %DataSection) DESC(Data Section) ARG()
outStr &STRING, AUTO ! ссылка на выходная строка
inStr &STRING, AUTO ! ссылка на входная строка
!inStrLng Long ! длина входной строки - ускорить-без SIZE(inStr) RTL
i SIGNED, AUTO ! индекс-позиция входной строки =0
j SIGNED, AUTO ! индекс-позиция выходной строки =0
! он же счётчик сконвертированных символов
!in3b STRING(17) ! для 3-х байтовых символов Utf-8 последний байт
!out3b STRING(17) ! символы 1251 соответственно
!in2b STRING(13) ! для 2-х байтовых символов Utf-8 последний байт
!out2b STRING(13) ! символы 1251 соответственно
! инициализация в обьявлении строковой константы
! должна определить СТАТИЧЕСКУЮ память -ускорить работу
in3b STRING('<147><147><152><153><154><156><157><158><160><161><162><166><176><185><186><172><150>')
out3b STRING('<150><151><145><146><130><147><148><132><134><135><149><133><137><139><155><136><185>')
in2b STRING('<146><147><148><149><150><151><152><153><154><155><156><158><159>')
out2b STRING('<144><131><186><190><179><191><188><154><156><158><157><162><159>')
! После точки Врезки: %DataSection) DESC(Data Section) ARG()
!===========================================================================
CODE ! Начало кода обработки
! Перед точкой Врезки: %ProcessedCode) DESC(Код обработки) ARG()
! строки параметры по адресу+длина
inStr &= StrIn ! укажем ссылку-реферал на строку UTF-8 откуда
outStr &= StrOut ! указать ссылку на строку вывода - куда
!Stop(StrIn)
!Stop(SIZE(StrIn))
!Stop(StrOut)
!Stop(SIZE(StrOut))
outStr &= NEW STRING(SIZE(inStr)) ! конструктор выходной строки
!Stop(SIZE(outStr))
! пара массивов для 3-х байтовых символов Utf-8 последний байт
!in3b = '<147><147><152><153><154><156><157><158><160><161><162><166><176><185><186><172><150>'
!out3b= '<150><151><145><146><130><147><148><132><134><135><149><133><137><139><155><136><185>'
!in2b = '<146><147><148><149><150><151><152><153><154><155><156><158><159>'
!out2b= '<144><131><186><190><179><191><188><154><156><158><157><162><159>'
j = 0
LOOP i = 1 TO SIZE(StrIn) ! цикл по входной строке
j += 1 ! счётчик сконвертированных символов
IF VAL(StrIn[i]) <= 07FH ! номер символа меньше 127 -Latin
!Stop(StrIn[i] &' i=' &i)
outStr[j] = StrIn[i] ! без конвертации в позицию новой строки
!Stop(outStr[j] &' j=' &j)
cycle ! нашли - в начало цикла
end
IF VAL(StrIn[i]) = 194 ! номер след. символа 1251
i += 1 ! след символ
outStr[j] = StrIn[i]
!Stop(outStr[j] &' 194j=' &j)
cycle ! нашли - в начало цикла
end
IF VAL(StrIn[i]) = 208 ! русские символы из 2-х байт
i += 1 ! след символ
IF VAL(StrIn[i]) = 129 ! буква Ё
outStr[j] = CHR(VAL(StrIn[i]) + 39)
!Stop(outStr[j] &' 208j=' &j)
cycle ! нашли - в начало цикла
else
IF VAL(StrIn[i]) >143
outStr[j] = CHR(VAL(StrIn[i]) + 48)
!Stop(outStr[j] &' 143j=' &j)
cycle ! нашли - в начало цикла
end
END
END
IF VAL(StrIn[i]) = 209 ! русские символы
i += 1 ! след символ
IF VAL(StrIn[i]) = 145 ! буква ё
outStr[j] = CHR(VAL(StrIn[i]) + 39)
!Stop(outStr[j] &' 209j=' &j)
cycle ! нашли - в начало цикла
else
IF VAL(StrIn[i]) < 144
outStr[j] = CHR(VAL(StrIn[i]) + 112)
!Stop(outStr[j] &' <144j=' &j)
cycle ! нашли - в начало цикла
end
END
END ! русские символы 209
! здесь проверка символов кириллицы - не русских 15 штук 2-байтовые 209,210>143
IF VAL(StrIn[i]) = 209 ! НЕрусские символы 209
i += 1 ! след символ
LOOP s# = 1 TO 13 ! SIZE(in2b)
IF VAL(in3b[s#]) = VAL(StrIn[i]) ! 2-байтовые
outStr[j] = out3b[s#]
!Stop(outStr[j] &' 209j=' &j)
break ! нашли-искать не надо
end
end ! LOOP s# = 1 TO SIZE(in2b)
END ! НЕрусские символы 209
IF VAL(StrIn[i]) = 210 ! НЕрусские символы 210
i += 1 ! след символ
IF VAL(StrIn[i]) = 145 !
outStr[j] = 180
!Stop(outStr[j] &' 210j=' &j)
cycle ! нашли - в начало цикла
end
IF VAL(StrIn[i]) = 144 !
outStr[j] = 165
!Stop(outStr[j] &' 210j=' &j)
cycle ! нашли - в начало цикла
end
END ! НЕрусские символы 210
! ищем знаки 3-байтовые, типа номер №, многоточие... евро
IF VAL(StrIn[i]) = 226 ! 3-байтовые 226 - достаточно для проверки
IF VAL(StrIn[i+1]) = 132 ! 3-байтовые 132
IF VAL(StrIn[i+2]) = 162 ! дублирован 162, поэтому отдельно
outStr[j] = '<153>' ! товарныйзнак
!Stop(outStr[j] &' 226j=' &j)
i += 2 ! след байт перескакиваем на символ
cycle ! нашли - в начало цикла
end
end ! 3-байтовые 132
i += 2 ! след байт перескакиваем на символ
LOOP s# = 1 TO 17 ! SIZE(in3b)
IF VAL(in3b[s#]) = VAL(StrIn[i]) ! 3-байтовые 128,130,132
outStr[j] = out3b[s#]
!Stop(outStr[j] &' 226j=' &j)
break ! нашли-искать не надо
end
end ! LOOP s# = 1 TO SIZE(in3b)
end ! IF VAL(StrIn[i]) = 226
END ! LOOP i = 1 TO SIZE(StrIn)
!Stop('Utf8 ' &outStr)
Qt:ValueA = outStr
! вариант возврата результата
! После точки Врезки: %ProcessedCode) DESC(Код обработки) ARG()
Процедура не возвращает значения как обычно.
Отказался от процедуры - сделал "рутинку" подпрограмму
Ведь даже доли процента при больших файлах - это время...
Отсюда варианты - ищу самый быстрый вариант.
! ------ Start utf-8 Decoding --------
utf8UseUString = false
if self._LoadEncodingIsUTF8 and self.DontUTF8Decode = 0
if self.NoUTF8Before = 1
! Check for a double byte UTF-8 character
if OkayToCopy ! Normal Copy
loop utf8X = DataStartPos to DataEndPos
if self.BinData[utf8X] >= '<192>'
self.NoUTF8Before = false ! utf-8 found
break
end
end
else ! Use Decoded copy
loop utf8X = DataStartPos to (cx-1)
if self.BinData[utf8X] >= '<192>'
self.NoUTF8Before = false ! utf-8 found
break
end
end
if self.NoUTF8Before = 1
loop utf8X = 1 to cs
if t[utf8X] >= '<192>'
self.NoUTF8Before = false ! utf-8 found
break
end
end
end
end
end
if self.NoUTF8Before = 0 ! i.e. utf-8 found before
! Copy data to u and then utf-8 decode this string
Do CopyDataToU
! ------ Start UTF-8 Decode --------
! TODO: use the MultiByteToWideChar/WideCharToMultiByte APIs to correctly handle all Unicode text, code pages
! and conversion to an from ANSI. The _NetUnicode class would be ideal for this
! see http://www1.tip.nl/~t876506/utf8tbl.html
loop utf8x = 1 to utf8size
case Val(u[utf8x]) ! May08: Changed this to use val and do integer comparisons, which fixed a decoding bug
! ----------------
of 192 to 223 ! 2 byte utf-8, May08: Changed to using integers and Val() rather than a string comparison.
! ----------------
if utf8x < utf8size
utf8UseUString = true
u[utf8x] = chr(bshift(val(u[utf8x])-192,6) + (val(u[utf8x+1])-128))
if utf8x+1 < utf8size
u[utf8x+1 : utf8size-1] = u[utf8x+2 : utf8size]
end
utf8size -= 1
end
! ----------------
!of 224 to 239 ! 3 byte utf-8 - not implemented
! ----------------
! ----------------
!of 240 to 247 ! 4 byte utf-8 - not implemented
! ----------------
! ----------------
!of 248 to 251 ! 5 byte utf-8 - not implemented
! ----------------
! ----------------
!of 252 to 253 ! 6 byte utf-8 - not implemented
! ----------------
! ----------------
!of 254 to 255 ! illegal utf-8 code
! ----------------
end ! end of case
end
! ------ End UTF-8 Decode --------
end
end
! ------ Finish utf-8 Decoding --------
!self.log('AssignField','xxx Finish utf-8 Decoding ')
Так понял битовые операторы как бы лучше присваивания