Utf8 Ansi Decoder

0 views
Skip to first unread message

Sergey Karakovskiy

unread,
Mar 25, 2008, 1:11:22 PM3/25/08
to Forth On TOP @ AMCP
Hello Forth,

Итак, сабж сделан. Архивчик UtfAnsiDecoder.rar должен быть прикреплён.
Комментим, плз. Комментим _все_. Те, кому всё кристально ясно и
очевидно, советуем, как улучшить статью (напоминаю, что программы на
языке Forth мы (и не только) называем статьями ;) ) -- улучшать там
есть чего: как минимум статья избыточна, т.е. определены слова,
которые можно было не определять, это моя привычка делать избыточные
typedefs в C++ для улучшения читаемости кода; может и не стоит это
рефакторить.

Те, кому какой-то фрагмент решения не очевиден, задаём вопросы и
все вместе на них отвечаем. Могу сказать, что после
написания конвертации из Utf-8>Ansi обратная конвертация пишется по имеющейся
структуре автоматически, не задумываясь. Приятно.

Known bugs:
Баги, с которыми я даже не пытался разбираться ввиду их полезных
особенностей :
1. Двухкратный вызов Utf-8>Ansi-file или Ansi>Utf-8-file
приводит к интересной ошибке, взгляните :-)
Наверняка, нужно просто обнулить хэндл файла, но я это не
смотрел.
2. Вызов подряд
s" W:\Projects\Forth\UtfAnsiDecoder\Data\Example-utf8.txt"
Utf-8>Ansi-file
s" W:\Projects\Forth\UtfAnsiDecoder\Data\Example-ansi.txt"
Ansi>Utf-8-file
приводит к неправильной работе второго слова, т.е. Ansi>Utf-8-file.
Я думаю, причина та же, что и в п.1.
3. Работают только захардкоженные пути к файлам, т.к. я не знаю, как
сделать относительные пути. Хотя знаю.. Есть слово chdir. Да,
можно.

How to use:

1. Распаковываете архив на диск цэ (в связи с Known bugs.3)

2. Подключаете файл c:\UtfAnsiDecoder\UftAnsiDecoder.ft
fload c:\UtfAnsiDecoder\UftAnsiDecoder.ft
или
include c:\UtfAnsiDecoder\UftAnsiDecoder.ft
3. выполняете слово main

Перед исполнением "активных действий" будет показан небольшой хелп
по юзанию обоих слов.

--
Best regards,
Sergey mailto:sergey.ka...@gmail.com

UtfAnsiDecoder.rar

Michael Gasanenko

unread,
Apr 2, 2008, 9:51:05 AM4/2/08
to Forth On TOP @ AMCP
Да так, по мелочи...

-- quote{ --
: fwrite-ansi-char ( ??? -- ??? )
208 pchar !
pchar 1 fout-write
c@ 48 - pchar !
pchar 1 fout-write
;
-- }quote --

create buf 0 c,
: wr ( c -- ) buf c! buf 1 fout-write ;
: wr-utf8 ( c -- ) 208 wr c@ 48 - wr ;
(или даже не по стандарту
: wr ( c -- ) SP@ 1 fout-write drop ;
SP@ -- слово нестандартное, и мы предполагаем, что младший байт --
первый)

Странные стековые эффекты и названия:

: ?utf8-pchar ( addr -- bool )
dup c@ ?utf8-char
;
во-первых, это ( addr -- addr flag ). Во-вторых, >127 -- это еще не
utf-8.

Что до главного цикла, есть хорошее слово /STRING ( addr len n -- addr
+n len-n ).
А переменная -- не нужна.

: AnsiStringSaveToUtf8File ( addr len -- )
begin ( addr len )
dup
while
over c@
dup 7-bit?
if wr
else wr-utf
then
1 /string
repeat
2drop
;

Вообще, вместо 7-bit? можно писать $80 AND, и так ясно, что бит
проверяем.

Ну, в общем где-то так...

Michael Gasanenko

unread,
Apr 2, 2008, 11:08:07 AM4/2/08
to Forth On TOP @ AMCP
Вот эти определения не нужны. Все эти слова выражают одну и ту же
идею. Нужно только одно слово. А dup c@ (или over c@ ;) надо писать
перед этим словом. По крайней мере для данной задачи.

: ?utf8-char ( n -- bool )
127 >
;

: ?ansi-char ( n -- bool )
?utf8-char not
;

: ?utf8-pchar ( addr -- bool )
dup c@ ?utf8-char
;

: ?ansi-pchar ( addr -- bool )
dup c@ ?ansi-char
;


Еще одна вещь.
Существует мнение, слово должно убирать со стека что все переданные
ему значения-параметры. Например, так работает READ-LINE. Я с этим
мнением не согласен, то есть, сам люблю возвращать нетронутые
значения, но не во всех случаях. В каких случаях это оправдано -- это
вовсе не тривиальный вопрос. Возможно, если значения образуют
осмысленный набор. Хотя чаще это мотивировано тем, что значений много,
а дублировать значения в глбине стека -- неудобно.

Но в любом случае, если вы хотите вернуть неизмененное значение, стоит
подумать, а действительно ли это надо.



Reply all
Reply to author
Forward
0 new messages