MODULE CyrillicUtilities;
IMPORT
KernelLog, Codecs, Streams, Texts, Commands;
CONST
PRIME = 977;
CP1251 = 0;
KOI8R = CP1251 + 1;
KOI8U = KOI8R + 1;
CP866 = KOI8U + 1;
ISO88595 = CP866 + 1;
ENCODINGS_HIGH = ISO88595;
CR = 0DX; LF = 0AX;
TYPE
Char32 = Texts.Char32;
StaticTable = ARRAY 256 OF Char32;
HashTable = ARRAY PRIME OF
RECORD
ucs32: Char32;
encodings: SET;
ch: ARRAY ENCODINGS_HIGH + 1 OF CHAR;
END;
LowBound = ARRAY ENCODINGS_HIGH + 1 OF INTEGER;
CP1251Decoder = OBJECT(Codecs.TextDecoder)
VAR errors : BOOLEAN;
in : Streams.Reader;
text : Texts.Text;
PROCEDURE Error(CONST x : ARRAY OF CHAR);
BEGIN
KernelLog.String("CP1251 Decoder Error: ");
KernelLog.String(x); KernelLog.Ln;
errors := TRUE
END Error;
PROCEDURE Open*(in : Streams.Reader; VAR res : LONGINT);
VAR i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Char32;
ch, last : CHAR;
BEGIN
errors := FALSE;
res := Codecs.ResFailed;
IF in = NIL THEN Error("Input Stream is NIL"); RETURN; END;
SELF.in := in;
NEW(text);
text.AcquireWrite;
m := LEN(tempUCS32) - 1;
i := 0;
REPEAT
in.Char(ch);
IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
IF (last # CR) OR (ch # LF) THEN
IF ch = CR THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := cp1251[ORD(ch)]
END;
INC(i)
END;
last := ch
UNTIL (in.res # Streams.Ok);
tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
res := Codecs.ResOk;
text.ReleaseWrite
END Open;
PROCEDURE GetText*() : Texts.Text;
BEGIN
RETURN text
END GetText;
END CP1251Decoder;
CP1251Encoder = OBJECT(Codecs.TextEncoder)
VAR out: Streams.Writer;
PROCEDURE Open*(out : Streams.Writer);
BEGIN
IF out = NIL THEN KernelLog.String("CP1251 Encoder Error: output stream is NIL");
ELSE SELF.out := out
END
END Open;
PROCEDURE WriteText*(text : Texts.Text; VAR res : LONGINT);
VAR r : Texts.TextReader; ch : Texts.Char32; i : LONGINT;
c: CHAR;
BEGIN
res := -1;
text.AcquireRead;
NEW(r, text);
FOR i := 0 TO text.GetLength() - 1 DO
r.ReadCh(ch);
IF ch < aLowBound[CP1251] THEN
out.Char(CHR(ch))
ELSIF hashSearch(CP1251, FALSE, ch, c) THEN
out.Char(c)
END;
END;
out.Update;
text.ReleaseRead;
res := Codecs.ResOk
END WriteText;
END CP1251Encoder;
KOI8RDecoder = OBJECT(Codecs.TextDecoder)
VAR errors : BOOLEAN;
in : Streams.Reader;
text : Texts.Text;
PROCEDURE Error(CONST x : ARRAY OF CHAR);
BEGIN
KernelLog.String("KOI8-R Decoder Error: ");
KernelLog.String(x); KernelLog.Ln;
errors := TRUE
END Error;
PROCEDURE Open*(in : Streams.Reader; VAR res : LONGINT);
VAR i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Char32;
ch, last : CHAR;
BEGIN
errors := FALSE;
res := Codecs.ResFailed;
IF in = NIL THEN Error("Input Stream is NIL"); RETURN; END;
SELF.in := in;
NEW(text);
text.AcquireWrite;
m := LEN(tempUCS32) - 1;
i := 0;
REPEAT
in.Char(ch);
IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
IF (last # CR) OR (ch # LF) THEN
IF ch = CR THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := koi8r[ORD(ch)]
END;
INC(i)
END;
last := ch
UNTIL (in.res # Streams.Ok);
tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
res := Codecs.ResOk;
text.ReleaseWrite
END Open;
PROCEDURE GetText*() : Texts.Text;
BEGIN
RETURN text;
END GetText;
END KOI8RDecoder;
KOI8REncoder = OBJECT(Codecs.TextEncoder)
VAR out: Streams.Writer;
PROCEDURE Open*(out : Streams.Writer);
BEGIN
IF out = NIL THEN KernelLog.String("KOI8-R Encoder Error: output stream is NIL")
ELSE SELF.out := out
END;
END Open;
PROCEDURE WriteText*(text : Texts.Text; VAR res : LONGINT);
VAR r : Texts.TextReader; ch : Texts.Char32; i : LONGINT;
c: CHAR;
BEGIN
res := -1;
text.AcquireRead;
NEW(r, text);
FOR i := 0 TO text.GetLength() - 1 DO
r.ReadCh(ch);
IF ch < aLowBound[KOI8R] THEN
out.Char(CHR(ch))
ELSIF hashSearch(KOI8R, FALSE, ch, c) THEN
out.Char(c)
END;
END;
out.Update;
text.ReleaseRead;
res := Codecs.ResOk
END WriteText;
END KOI8REncoder;
KOI8UDecoder = OBJECT(Codecs.TextDecoder)
VAR errors : BOOLEAN;
in : Streams.Reader;
text : Texts.Text;
PROCEDURE Error(CONST x : ARRAY OF CHAR);
BEGIN
KernelLog.String("KOI8-U Decoder Error: ");
KernelLog.String(x); KernelLog.Ln;
errors := TRUE
END Error;
PROCEDURE Open*(in : Streams.Reader; VAR res : LONGINT);
VAR i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Char32;
ch, last : CHAR;
BEGIN
errors := FALSE;
res := Codecs.ResFailed;
IF in = NIL THEN Error("Input Stream is NIL"); RETURN; END;
SELF.in := in;
NEW(text);
text.AcquireWrite;
m := LEN(tempUCS32) - 1;
i := 0;
REPEAT
in.Char(ch);
IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
IF (last # CR) OR (ch # LF) THEN
IF ch = CR THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := koi8u[ORD(ch)]
END;
INC(i)
END;
last := ch
UNTIL (in.res # Streams.Ok);
tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
res := Codecs.ResOk;
text.ReleaseWrite
END Open;
PROCEDURE GetText*() : Texts.Text;
BEGIN
RETURN text
END GetText;
END KOI8UDecoder;
KOI8UEncoder = OBJECT(Codecs.TextEncoder)
VAR out: Streams.Writer;
PROCEDURE Open*(out : Streams.Writer);
BEGIN
IF out = NIL THEN KernelLog.String("KOI8-U Encoder Error: output stream is NIL")
ELSE SELF.out := out
END
END Open;
PROCEDURE WriteText*(text : Texts.Text; VAR res : LONGINT);
VAR r : Texts.TextReader; ch : Texts.Char32; i : LONGINT;
c: CHAR;
BEGIN
res := -1;
text.AcquireRead;
NEW(r, text);
FOR i := 0 TO text.GetLength() - 1 DO
r.ReadCh(ch);
IF ch < aLowBound[KOI8U] THEN
out.Char(CHR(ch))
ELSIF hashSearch(KOI8U, FALSE, ch, c) THEN
out.Char(c)
END;
END;
out.Update;
text.ReleaseRead;
res := Codecs.ResOk
END WriteText;
END KOI8UEncoder;
CP866Decoder = OBJECT(Codecs.TextDecoder)
VAR errors : BOOLEAN;
in : Streams.Reader;
text : Texts.Text;
PROCEDURE Error(CONST x : ARRAY OF CHAR);
BEGIN
KernelLog.String("CP-866 Decoder Error: ");
KernelLog.String(x); KernelLog.Ln;
errors := TRUE
END Error;
PROCEDURE Open*(in : Streams.Reader; VAR res : LONGINT);
VAR i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Char32;
ch, last : CHAR;
BEGIN
errors := FALSE;
res := Codecs.ResFailed;
IF in = NIL THEN Error("Input Stream is NIL"); RETURN; END;
SELF.in := in;
NEW(text);
text.AcquireWrite;
m := LEN(tempUCS32) - 1;
i := 0;
REPEAT
in.Char(ch);
IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
IF (last # CR) OR (ch # LF) THEN
IF ch = CR THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := cp866[ORD(ch)]
END;
INC(i)
END;
last := ch
UNTIL (in.res # Streams.Ok);
tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
res := Codecs.ResOk;
text.ReleaseWrite
END Open;
PROCEDURE GetText*() : Texts.Text;
BEGIN
RETURN text
END GetText;
END CP866Decoder;
CP866Encoder = OBJECT(Codecs.TextEncoder)
VAR out: Streams.Writer;
PROCEDURE Open*(out : Streams.Writer);
BEGIN
IF out = NIL THEN KernelLog.String("CP-866 Encoder Error: output stream is NIL")
ELSE SELF.out := out
END;
END Open;
PROCEDURE WriteText*(text : Texts.Text; VAR res : LONGINT);
VAR r : Texts.TextReader; ch : Texts.Char32; i : LONGINT;
c: CHAR;
BEGIN
res := -1;
text.AcquireRead;
NEW(r, text);
FOR i := 0 TO text.GetLength() - 1 DO
r.ReadCh(ch);
IF ch < aLowBound[CP866] THEN
out.Char(CHR(ch))
ELSIF hashSearch(CP866, FALSE, ch, c) THEN
out.Char(c)
END
END;
out.Update;
text.ReleaseRead;
res := Codecs.ResOk
END WriteText;
END CP866Encoder;
ISO88595Decoder = OBJECT(Codecs.TextDecoder)
VAR errors : BOOLEAN;
in : Streams.Reader;
text : Texts.Text;
PROCEDURE Error(CONST x : ARRAY OF CHAR);
BEGIN
KernelLog.String("ISO-8859-5 Decoder Error: ");
KernelLog.String(x); KernelLog.Ln;
errors := TRUE
END Error;
PROCEDURE Open*(in : Streams.Reader; VAR res : LONGINT);
VAR i, m: LONGINT;
tempUCS32 : ARRAY 1024 OF Char32;
ch, last : CHAR;
BEGIN
errors := FALSE;
res := Codecs.ResFailed;
IF in = NIL THEN Error("Input Stream is NIL"); RETURN; END;
SELF.in := in;
NEW(text);
text.AcquireWrite;
m := LEN(tempUCS32) - 1;
i := 0;
REPEAT
in.Char(ch);
IF i = m THEN tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32); i := 0 END;
IF (last # CR) OR (ch # LF) THEN
IF ch = CR THEN tempUCS32[i] := ORD(LF)
ELSE tempUCS32[i] := iso88595[ORD(ch)]
END;
INC(i)
END;
last := ch
UNTIL (in.res # Streams.Ok);
tempUCS32[i] := 0; text.InsertUCS32(text.GetLength(), tempUCS32);
res := Codecs.ResOk;
text.ReleaseWrite
END Open;
PROCEDURE GetText*() : Texts.Text;
BEGIN
RETURN text
END GetText;
END ISO88595Decoder;
ISO88595Encoder = OBJECT(Codecs.TextEncoder)
VAR out: Streams.Writer;
PROCEDURE Open*(out : Streams.Writer);
BEGIN
IF out = NIL THEN KernelLog.String("ISO-8859-5 Encoder Error: output stream is NIL")
ELSE SELF.out := out
END
END Open;
PROCEDURE WriteText*(text : Texts.Text; VAR res : LONGINT);
VAR r : Texts.TextReader; ch : Texts.Char32; i : LONGINT;
c: CHAR;
BEGIN
res := -1;
text.AcquireRead;
NEW(r, text);
FOR i := 0 TO text.GetLength() - 1 DO
r.ReadCh(ch);
IF ch < aLowBound[ISO88595] THEN
out.Char(CHR(ch))
ELSIF hashSearch(ISO88595, FALSE, ch, c) THEN
out.Char(c)
END;
END;
out.Update;
text.ReleaseRead;
res := Codecs.ResOk
END WriteText;
END ISO88595Encoder;
VAR
aLowBound: LowBound;
koi8r, koi8u, cp1251, cp866, iso88595: StaticTable;
hash: HashTable;
bFirst: BOOLEAN;
setInitDone: SET;
nCollisions: LONGINT;
ucs32Min, ucs32Max: Char32;
PROCEDURE hashSearch(encoding: SHORTINT; bAddAllowed: BOOLEAN; ucs32: Char32; VAR ch: CHAR): BOOLEAN;
VAR
d: INTEGER;
h: LONGINT;
bFound, bExit: BOOLEAN;
BEGIN
bExit := FALSE;
bFound := FALSE;
d := 1;
h := ucs32 MOD PRIME;
IF bAddAllowed THEN
IF bFirst THEN
bFirst := FALSE;
ucs32Min := ucs32;
ucs32Max := ucs32
ELSE
ucs32Min := MIN(ucs32Min, ucs32);
ucs32Max := MAX(ucs32Max, ucs32)
END
ELSIF (ucs32 < ucs32Min) OR (ucs32 > ucs32Max) THEN
bExit := TRUE
END;
WHILE ~(bFound OR bExit) DO
IF hash[h].ucs32 = ucs32 THEN
IF encoding IN hash[h].encodings THEN
bFound := TRUE;
ch := hash[h].ch[encoding]
ELSIF bAddAllowed THEN
bExit := TRUE;
hash[h].ch[encoding] := ch;
hash[h].encodings := hash[h].encodings + {encoding}
ELSE
bExit := TRUE
END
ELSIF hash[h].ucs32 = 0 THEN
bExit := TRUE;
IF bAddAllowed THEN
hash[h].ucs32 := ucs32;
hash[h].ch[encoding] := ch;
hash[h].encodings := hash[h].encodings + {encoding}
END
ELSE
INC(nCollisions);
h := h + d; d := d + 2;
IF h >= PRIME THEN h := h - PRIME END;
IF d = PRIME THEN
bExit := TRUE;
ASSERT(d # PRIME)
END
END
END;
RETURN bFound
END hashSearch;
PROCEDURE koi8rInit;
VAR
i: INTEGER; b: BOOLEAN;
c: CHAR;
BEGIN
IF ~(KOI8R IN setInitDone) THEN
setInitDone := setInitDone + {KOI8R};
FOR i := 0 TO aLowBound[KOI8R] - 1 DO
koi8r[i] := i
END;
koi8r[080H] := 02500H;
koi8r[081H] := 02502H;
koi8r[082H] := 0250CH;
koi8r[083H] := 02510H;
koi8r[084H] := 02514H;
koi8r[085H] := 02518H;
koi8r[086H] := 0251CH;
koi8r[087H] := 02524H;
koi8r[088H] := 0252CH;
koi8r[089H] := 02534H;
koi8r[08AH] := 0253CH;
koi8r[08BH] := 02580H;
koi8r[08CH] := 02584H;
koi8r[08DH] := 02588H;
koi8r[08EH] := 0258CH;
koi8r[08FH] := 02590H;
koi8r[090H] := 02591H;
koi8r[091H] := 02592H;
koi8r[092H] := 02593H;
koi8r[093H] := 02320H;
koi8r[094H] := 025A0H;
koi8r[095H] := 02022H;
koi8r[096H] := 0221AH;
koi8r[097H] := 02248H;
koi8r[098H] := 02264H;
koi8r[099H] := 02265H;
koi8r[09AH] := 000A0H;
koi8r[09BH] := 02321H;
koi8r[09CH] := 000B0H;
koi8r[09DH] := 000B2H;
koi8r[09EH] := 000B7H;
koi8r[09FH] := 000F7H;
koi8r[0A0H] := 02550H;
koi8r[0A1H] := 02551H;
koi8r[0A2H] := 02552H;
koi8r[0A3H] := 00451H;
koi8r[0A4H] := 02553H;
koi8r[0A5H] := 02554H;
koi8r[0A6H] := 02555H;
koi8r[0A7H] := 02556H;
koi8r[0A8H] := 02557H;
koi8r[0A9H] := 02558H;
koi8r[0AAH] := 02559H;
koi8r[0ABH] := 0255AH;
koi8r[0ACH] := 0255BH;
koi8r[0ADH] := 0255CH;
koi8r[0AEH] := 0255DH;
koi8r[0AFH] := 0255EH;
koi8r[0B0H] := 0255FH;
koi8r[0B1H] := 02560H;
koi8r[0B2H] := 02561H;
koi8r[0B3H] := 00401H;
koi8r[0B4H] := 02562H;
koi8r[0B5H] := 02563H;
koi8r[0B6H] := 02564H;
koi8r[0B7H] := 02565H;
koi8r[0B8H] := 02566H;
koi8r[0B9H] := 02567H;
koi8r[0BAH] := 02568H;
koi8r[0BBH] := 02569H;
koi8r[0BCH] := 0256AH;
koi8r[0BDH] := 0256BH;
koi8r[0BEH] := 0256CH;
koi8r[0BFH] := 000A9H;
koi8r[0C0H] := 0044EH;
koi8r[0C1H] := 00430H;
koi8r[0C2H] := 00431H;
koi8r[0C3H] := 00446H;
koi8r[0C4H] := 00434H;
koi8r[0C5H] := 00435H;
koi8r[0C6H] := 00444H;
koi8r[0C7H] := 00433H;
koi8r[0C8H] := 00445H;
koi8r[0C9H] := 00438H;
koi8r[0CAH] := 00439H;
koi8r[0CBH] := 0043AH;
koi8r[0CCH] := 0043BH;
koi8r[0CDH] := 0043CH;
koi8r[0CEH] := 0043DH;
koi8r[0CFH] := 0043EH;
koi8r[0D0H] := 0043FH;
koi8r[0D1H] := 0044FH;
koi8r[0D2H] := 00440H;
koi8r[0D3H] := 00441H;
koi8r[0D4H] := 00442H;
koi8r[0D5H] := 00443H;
koi8r[0D6H] := 00436H;
koi8r[0D7H] := 00432H;
koi8r[0D8H] := 0044CH;
koi8r[0D9H] := 0044BH;
koi8r[0DAH] := 00437H;
koi8r[0DBH] := 00448H;
koi8r[0DCH] := 0044DH;
koi8r[0DDH] := 00449H;
koi8r[0DEH] := 00447H;
koi8r[0DFH] := 0044AH;
koi8r[0E0H] := 0042EH;
koi8r[0E1H] := 00410H;
koi8r[0E2H] := 00411H;
koi8r[0E3H] := 00426H;
koi8r[0E4H] := 00414H;
koi8r[0E5H] := 00415H;
koi8r[0E6H] := 00424H;
koi8r[0E7H] := 00413H;
koi8r[0E8H] := 00425H;
koi8r[0E9H] := 00418H;
koi8r[0EAH] := 00419H;
koi8r[0EBH] := 0041AH;
koi8r[0ECH] := 0041BH;
koi8r[0EDH] := 0041CH;
koi8r[0EEH] := 0041DH;
koi8r[0EFH] := 0041EH;
koi8r[0F0H] := 0041FH;
koi8r[0F1H] := 0042FH;
koi8r[0F2H] := 00420H;
koi8r[0F3H] := 00421H;
koi8r[0F4H] := 00422H;
koi8r[0F5H] := 00423H;
koi8r[0F6H] := 00416H;
koi8r[0F7H] := 00412H;
koi8r[0F8H] := 0042CH;
koi8r[0F9H] := 0042BH;
koi8r[0FAH] := 00417H;
koi8r[0FBH] := 00428H;
koi8r[0FCH] := 0042DH;
koi8r[0FDH] := 00429H;
koi8r[0FEH] := 00427H;
koi8r[0FFH] := 0042AH;
FOR i := aLowBound[KOI8R] TO 255 DO
c := CHR(i);
b := hashSearch(KOI8R, TRUE, koi8r[i], c)
END
END
END koi8rInit;
PROCEDURE koi8uInit;
VAR
i: INTEGER; b: BOOLEAN;
c: CHAR;
BEGIN
IF ~(KOI8U IN setInitDone) THEN
setInitDone := setInitDone + {KOI8U};
FOR i := 0 TO aLowBound[KOI8U] - 1 DO
koi8u[i] := i
END;
koi8u[080H] := 02500H;
koi8u[081H] := 02502H;
koi8u[082H] := 0250CH;
koi8u[083H] := 02510H;
koi8u[084H] := 02514H;
koi8u[085H] := 02518H;
koi8u[086H] := 0251CH;
koi8u[087H] := 02524H;
koi8u[088H] := 0252CH;
koi8u[089H] := 02534H;
koi8u[08AH] := 0253CH;
koi8u[08BH] := 02580H;
koi8u[08CH] := 02584H;
koi8u[08DH] := 02588H;
koi8u[08EH] := 0258CH;
koi8u[08FH] := 02590H;
koi8u[090H] := 02591H;
koi8u[091H] := 02592H;
koi8u[092H] := 02593H;
koi8u[093H] := 02320H;
koi8u[094H] := 025A0H;
koi8u[095H] := 02022H;
koi8u[096H] := 0221AH;
koi8u[097H] := 02248H;
koi8u[098H] := 02264H;
koi8u[099H] := 02265H;
koi8u[09AH] := 000A0H;
koi8u[09BH] := 02321H;
koi8u[09CH] := 000B0H;
koi8u[09DH] := 000B2H;
koi8u[09EH] := 000B7H;
koi8u[09FH] := 000F7H;
koi8u[0A0H] := 02550H;
koi8u[0A1H] := 02551H;
koi8u[0A2H] := 02552H;
koi8u[0A3H] := 00451H;
koi8u[0A4H] := 00454H;
koi8u[0A5H] := 02554H;
koi8u[0A6H] := 00456H;
koi8u[0A7H] := 00457H;
koi8u[0A8H] := 02557H;
koi8u[0A9H] := 02558H;
koi8u[0AAH] := 02559H;
koi8u[0ABH] := 0255AH;
koi8u[0ACH] := 0255BH;
koi8u[0ADH] := 00491H;
koi8u[0AEH] := 0255DH;
koi8u[0AFH] := 0255EH;
koi8u[0B0H] := 0255FH;
koi8u[0B1H] := 02560H;
koi8u[0B2H] := 02561H;
koi8u[0B3H] := 00401H;
koi8u[0B4H] := 00404H;
koi8u[0B5H] := 02563H;
koi8u[0B6H] := 00406H;
koi8u[0B7H] := 00407H;
koi8u[0B8H] := 02566H;
koi8u[0B9H] := 02567H;
koi8u[0BAH] := 02568H;
koi8u[0BBH] := 02569H;
koi8u[0BCH] := 0256AH;
koi8u[0BDH] := 00490H;
koi8u[0BEH] := 0256CH;
koi8u[0BFH] := 000A9H;
koi8u[0C0H] := 0044EH;
koi8u[0C1H] := 00430H;
koi8u[0C2H] := 00431H;
koi8u[0C3H] := 00446H;
koi8u[0C4H] := 00434H;
koi8u[0C5H] := 00435H;
koi8u[0C6H] := 00444H;
koi8u[0C7H] := 00433H;
koi8u[0C8H] := 00445H;
koi8u[0C9H] := 00438H;
koi8u[0CAH] := 00439H;
koi8u[0CBH] := 0043AH;
koi8u[0CCH] := 0043BH;
koi8u[0CDH] := 0043CH;
koi8u[0CEH] := 0043DH;
koi8u[0CFH] := 0043EH;
koi8u[0D0H] := 0043FH;
koi8u[0D1H] := 0044FH;
koi8u[0D2H] := 00440H;
koi8u[0D3H] := 00441H;
koi8u[0D4H] := 00442H;
koi8u[0D5H] := 00443H;
koi8u[0D6H] := 00436H;
koi8u[0D7H] := 00432H;
koi8u[0D8H] := 0044CH;
koi8u[0D9H] := 0044BH;
koi8u[0DAH] := 00437H;
koi8u[0DBH] := 00448H;
koi8u[0DCH] := 0044DH;
koi8u[0DDH] := 00449H;
koi8u[0DEH] := 00447H;
koi8u[0DFH] := 0044AH;
koi8u[0E0H] := 0042EH;
koi8u[0E1H] := 00410H;
koi8u[0E2H] := 00411H;
koi8u[0E3H] := 00426H;
koi8u[0E4H] := 00414H;
koi8u[0E5H] := 00415H;
koi8u[0E6H] := 00424H;
koi8u[0E7H] := 00413H;
koi8u[0E8H] := 00425H;
koi8u[0E9H] := 00418H;
koi8u[0EAH] := 00419H;
koi8u[0EBH] := 0041AH;
koi8u[0ECH] := 0041BH;
koi8u[0EDH] := 0041CH;
koi8u[0EEH] := 0041DH;
koi8u[0EFH] := 0041EH;
koi8u[0F0H] := 0041FH;
koi8u[0F1H] := 0042FH;
koi8u[0F2H] := 00420H;
koi8u[0F3H] := 00421H;
koi8u[0F4H] := 00422H;
koi8u[0F5H] := 00423H;
koi8u[0F6H] := 00416H;
koi8u[0F7H] := 00412H;
koi8u[0F8H] := 0042CH;
koi8u[0F9H] := 0042BH;
koi8u[0FAH] := 00417H;
koi8u[0FBH] := 00428H;
koi8u[0FCH] := 0042DH;
koi8u[0FDH] := 00429H;
koi8u[0FEH] := 00427H;
koi8u[0FFH] := 0042AH;
FOR i := aLowBound[KOI8U] TO 255 DO
c := CHR(i);
b := hashSearch(KOI8U, TRUE, koi8u[i], c)
END
END
END koi8uInit;
PROCEDURE cp1251Init;
VAR
i: INTEGER; b: BOOLEAN;
c: CHAR;
BEGIN
IF ~(CP1251 IN setInitDone) THEN
setInitDone := setInitDone + {CP1251};
FOR i := 0 TO aLowBound[CP1251] - 1 DO
cp1251[i] := i
END;
cp1251[080H] := 00402H;
cp1251[081H] := 00403H;
cp1251[082H] := 0201AH;
cp1251[083H] := 00453H;
cp1251[084H] := 0201EH;
cp1251[085H] := 02026H;
cp1251[086H] := 02020H;
cp1251[087H] := 02021H;
cp1251[088H] := 020ACH;
cp1251[089H] := 02030H;
cp1251[08AH] := 00409H;
cp1251[08BH] := 02039H;
cp1251[08CH] := 0040AH;
cp1251[08DH] := 0040CH;
cp1251[08EH] := 0040BH;
cp1251[08FH] := 0040FH;
cp1251[090H] := 00452H;
cp1251[091H] := 02018H;
cp1251[092H] := 02019H;
cp1251[093H] := 0201CH;
cp1251[094H] := 0201DH;
cp1251[095H] := 02022H;
cp1251[096H] := 02013H;
cp1251[097H] := 02014H;
cp1251[098H] := 098H;
cp1251[099H] := 02122H;
cp1251[09AH] := 00459H;
cp1251[09BH] := 0203AH;
cp1251[09CH] := 0045AH;
cp1251[09DH] := 0045CH;
cp1251[09EH] := 0045BH;
cp1251[09FH] := 0045FH;
cp1251[0A0H] := 000A0H;
cp1251[0A1H] := 0040EH;
cp1251[0A2H] := 0045EH;
cp1251[0A3H] := 00408H;
cp1251[0A4H] := 000A4H;
cp1251[0A5H] := 00490H;
cp1251[0A6H] := 000A6H;
cp1251[0A7H] := 000A7H;
cp1251[0A8H] := 00401H;
cp1251[0A9H] := 000A9H;
cp1251[0AAH] := 00404H;
cp1251[0ABH] := 000ABH;
cp1251[0ACH] := 000ACH;
cp1251[0ADH] := 000ADH;
cp1251[0AEH] := 000AEH;
cp1251[0AFH] := 00407H;
cp1251[0B0H] := 000B0H;
cp1251[0B1H] := 000B1H;
cp1251[0B2H] := 00406H;
cp1251[0B3H] := 00456H;
cp1251[0B4H] := 00491H;
cp1251[0B5H] := 000B5H;
cp1251[0B6H] := 000B6H;
cp1251[0B7H] := 000B7H;
cp1251[0B8H] := 00451H;
cp1251[0B9H] := 02116H;
cp1251[0BAH] := 00454H;
cp1251[0BBH] := 000BBH;
cp1251[0BCH] := 00458H;
cp1251[0BDH] := 00405H;
cp1251[0BEH] := 00455H;
cp1251[0BFH] := 00457H;
cp1251[0C0H] := 00410H;
cp1251[0C1H] := 00411H;
cp1251[0C2H] := 00412H;
cp1251[0C3H] := 00413H;
cp1251[0C4H] := 00414H;
cp1251[0C5H] := 00415H;
cp1251[0C6H] := 00416H;
cp1251[0C7H] := 00417H;
cp1251[0C8H] := 00418H;
cp1251[0C9H] := 00419H;
cp1251[0CAH] := 0041AH;
cp1251[0CBH] := 0041BH;
cp1251[0CCH] := 0041CH;
cp1251[0CDH] := 0041DH;
cp1251[0CEH] := 0041EH;
cp1251[0CFH] := 0041FH;
cp1251[0D0H] := 00420H;
cp1251[0D1H] := 00421H;
cp1251[0D2H] := 00422H;
cp1251[0D3H] := 00423H;
cp1251[0D4H] := 00424H;
cp1251[0D5H] := 00425H;
cp1251[0D6H] := 00426H;
cp1251[0D7H] := 00427H;
cp1251[0D8H] := 00428H;
cp1251[0D9H] := 00429H;
cp1251[0DAH] := 0042AH;
cp1251[0DBH] := 0042BH;
cp1251[0DCH] := 0042CH;
cp1251[0DDH] := 0042DH;
cp1251[0DEH] := 0042EH;
cp1251[0DFH] := 0042FH;
cp1251[0E0H] := 00430H;
cp1251[0E1H] := 00431H;
cp1251[0E2H] := 00432H;
cp1251[0E3H] := 00433H;
cp1251[0E4H] := 00434H;
cp1251[0E5H] := 00435H;
cp1251[0E6H] := 00436H;
cp1251[0E7H] := 00437H;
cp1251[0E8H] := 00438H;
cp1251[0E9H] := 00439H;
cp1251[0EAH] := 0043AH;
cp1251[0EBH] := 0043BH;
cp1251[0ECH] := 0043CH;
cp1251[0EDH] := 0043DH;
cp1251[0EEH] := 0043EH;
cp1251[0EFH] := 0043FH;
cp1251[0F0H] := 00440H;
cp1251[0F1H] := 00441H;
cp1251[0F2H] := 00442H;
cp1251[0F3H] := 00443H;
cp1251[0F4H] := 00444H;
cp1251[0F5H] := 00445H;
cp1251[0F6H] := 00446H;
cp1251[0F7H] := 00447H;
cp1251[0F8H] := 00448H;
cp1251[0F9H] := 00449H;
cp1251[0FAH] := 0044AH;
cp1251[0FBH] := 0044BH;
cp1251[0FCH] := 0044CH;
cp1251[0FDH] := 0044DH;
cp1251[0FEH] := 0044EH;
cp1251[0FFH] := 0044FH;
FOR i := aLowBound[CP1251] TO 255 DO
c := CHR(i);
b := hashSearch(CP1251, TRUE, cp1251[i], c)
END
END
END cp1251Init;
PROCEDURE cp866Init;
VAR
i: INTEGER; b: BOOLEAN;
c: CHAR;
BEGIN
IF ~(CP866 IN setInitDone) THEN
setInitDone := setInitDone + {CP866};
FOR i := 0 TO aLowBound[CP866] - 1 DO
cp866[i] := i
END;
cp866[080H] := 00410H;
cp866[081H] := 00411H;
cp866[082H] := 00412H;
cp866[083H] := 00413H;
cp866[084H] := 00414H;
cp866[085H] := 00415H;
cp866[086H] := 00416H;
cp866[087H] := 00417H;
cp866[088H] := 00418H;
cp866[089H] := 00419H;
cp866[08AH] := 0041AH;
cp866[08BH] := 0041BH;
cp866[08CH] := 0041CH;
cp866[08DH] := 0041DH;
cp866[08EH] := 0041EH;
cp866[08FH] := 0041FH;
cp866[090H] := 00420H;
cp866[091H] := 00421H;
cp866[092H] := 00422H;
cp866[093H] := 00423H;
cp866[094H] := 00424H;
cp866[095H] := 00425H;
cp866[096H] := 00426H;
cp866[097H] := 00427H;
cp866[098H] := 00428H;
cp866[099H] := 00429H;
cp866[09AH] := 0042AH;
cp866[09BH] := 0042BH;
cp866[09CH] := 0042CH;
cp866[09DH] := 0042DH;
cp866[09EH] := 0042EH;
cp866[09FH] := 0042FH;
cp866[0A0H] := 00430H;
cp866[0A1H] := 00431H;
cp866[0A2H] := 00432H;
cp866[0A3H] := 00433H;
cp866[0A4H] := 00434H;
cp866[0A5H] := 00435H;
cp866[0A6H] := 00436H;
cp866[0A7H] := 00437H;
cp866[0A8H] := 00438H;
cp866[0A9H] := 00439H;
cp866[0AAH] := 0043AH;
cp866[0ABH] := 0043BH;
cp866[0ACH] := 0043CH;
cp866[0ADH] := 0043DH;
cp866[0AEH] := 0043EH;
cp866[0AFH] := 0043FH;
cp866[0B0H] := 02591H;
cp866[0B1H] := 02592H;
cp866[0B2H] := 02593H;
cp866[0B3H] := 02502H;
cp866[0B4H] := 02524H;
cp866[0B5H] := 02561H;
cp866[0B6H] := 02562H;
cp866[0B7H] := 02556H;
cp866[0B8H] := 02555H;
cp866[0B9H] := 02563H;
cp866[0BAH] := 02551H;
cp866[0BBH] := 02557H;
cp866[0BCH] := 0255DH;
cp866[0BDH] := 0255CH;
cp866[0BEH] := 0255BH;
cp866[0BFH] := 02510H;
cp866[0C0H] := 02514H;
cp866[0C1H] := 02534H;
cp866[0C2H] := 0252CH;
cp866[0C3H] := 0251CH;
cp866[0C4H] := 02500H;
cp866[0C5H] := 0253CH;
cp866[0C6H] := 0255EH;
cp866[0C7H] := 0255FH;
cp866[0C8H] := 0255AH;
cp866[0C9H] := 02554H;
cp866[0CAH] := 02569H;
cp866[0CBH] := 02566H;
cp866[0CCH] := 02560H;
cp866[0CDH] := 02550H;
cp866[0CEH] := 0256CH;
cp866[0CFH] := 02567H;
cp866[0D0H] := 02568H;
cp866[0D1H] := 02564H;
cp866[0D2H] := 02565H;
cp866[0D3H] := 02559H;
cp866[0D4H] := 02558H;
cp866[0D5H] := 02552H;
cp866[0D6H] := 02553H;
cp866[0D7H] := 0256BH;
cp866[0D8H] := 0256AH;
cp866[0D9H] := 02518H;
cp866[0DAH] := 0250CH;
cp866[0DBH] := 02588H;
cp866[0DCH] := 02584H;
cp866[0DDH] := 0258CH;
cp866[0DEH] := 02590H;
cp866[0DFH] := 02580H;
cp866[0E0H] := 00440H;
cp866[0E1H] := 00441H;
cp866[0E2H] := 00442H;
cp866[0E3H] := 00443H;
cp866[0E4H] := 00444H;
cp866[0E5H] := 00445H;
cp866[0E6H] := 00446H;
cp866[0E7H] := 00447H;
cp866[0E8H] := 00448H;
cp866[0E9H] := 00449H;
cp866[0EAH] := 0044AH;
cp866[0EBH] := 0044BH;
cp866[0ECH] := 0044CH;
cp866[0EDH] := 0044DH;
cp866[0EEH] := 0044EH;
cp866[0EFH] := 0044FH;
cp866[0F0H] := 00401H;
cp866[0F1H] := 00451H;
cp866[0F2H] := 00404H;
cp866[0F3H] := 00454H;
cp866[0F4H] := 00407H;
cp866[0F5H] := 00457H;
cp866[0F6H] := 0040EH;
cp866[0F7H] := 0045EH;
cp866[0F8H] := 000B0H;
cp866[0F9H] := 02022H;
cp866[0FAH] := 000B7H;
cp866[0FBH] := 0221AH;
cp866[0FCH] := 02116H;
cp866[0FDH] := 000A4H;
cp866[0FEH] := 025A0H;
cp866[0FFH] := 000A0H;
FOR i := aLowBound[CP866] TO 255 DO
c := CHR(i);
b := hashSearch(CP866, TRUE, cp866[i], c)
END
END
END cp866Init;
PROCEDURE iso88595Init;
VAR
i: INTEGER; b: BOOLEAN;
c: CHAR;
BEGIN
IF ~(ISO88595 IN setInitDone) THEN
setInitDone := setInitDone + {ISO88595};
FOR i := 0 TO aLowBound[ISO88595] - 1 DO
iso88595[i] := i
END;
iso88595[0A0H] := 000A0H;
iso88595[0A1H] := 00401H;
iso88595[0A2H] := 00402H;
iso88595[0A3H] := 00403H;
iso88595[0A4H] := 00404H;
iso88595[0A5H] := 00405H;
iso88595[0A6H] := 00406H;
iso88595[0A7H] := 00407H;
iso88595[0A8H] := 00408H;
iso88595[0A9H] := 00409H;
iso88595[0AAH] := 0040AH;
iso88595[0ABH] := 0040BH;
iso88595[0ACH] := 0040CH;
iso88595[0ADH] := 000ADH;
iso88595[0AEH] := 0040EH;
iso88595[0AFH] := 0040FH;
iso88595[0B0H] := 00410H;
iso88595[0B1H] := 00411H;
iso88595[0B2H] := 00412H;
iso88595[0B3H] := 00413H;
iso88595[0B4H] := 00414H;
iso88595[0B5H] := 00415H;
iso88595[0B6H] := 00416H;
iso88595[0B7H] := 00417H;
iso88595[0B8H] := 00418H;
iso88595[0B9H] := 00419H;
iso88595[0BAH] := 0041AH;
iso88595[0BBH] := 0041BH;
iso88595[0BCH] := 0041CH;
iso88595[0BDH] := 0041DH;
iso88595[0BEH] := 0041EH;
iso88595[0BFH] := 0041FH;
iso88595[0C0H] := 00420H;
iso88595[0C1H] := 00421H;
iso88595[0C2H] := 00422H;
iso88595[0C3H] := 00423H;
iso88595[0C4H] := 00424H;
iso88595[0C5H] := 00425H;
iso88595[0C6H] := 00426H;
iso88595[0C7H] := 00427H;
iso88595[0C8H] := 00428H;
iso88595[0C9H] := 00429H;
iso88595[0CAH] := 0042AH;
iso88595[0CBH] := 0042BH;
iso88595[0CCH] := 0042CH;
iso88595[0CDH] := 0042DH;
iso88595[0CEH] := 0042EH;
iso88595[0CFH] := 0042FH;
iso88595[0D0H] := 00430H;
iso88595[0D1H] := 00431H;
iso88595[0D2H] := 00432H;
iso88595[0D3H] := 00433H;
iso88595[0D4H] := 00434H;
iso88595[0D5H] := 00435H;
iso88595[0D6H] := 00436H;
iso88595[0D7H] := 00437H;
iso88595[0D8H] := 00438H;
iso88595[0D9H] := 00439H;
iso88595[0DAH] := 0043AH;
iso88595[0DBH] := 0043BH;
iso88595[0DCH] := 0043CH;
iso88595[0DDH] := 0043DH;
iso88595[0DEH] := 0043EH;
iso88595[0DFH] := 0043FH;
iso88595[0E0H] := 00440H;
iso88595[0E1H] := 00441H;
iso88595[0E2H] := 00442H;
iso88595[0E3H] := 00443H;
iso88595[0E4H] := 00444H;
iso88595[0E5H] := 00445H;
iso88595[0E6H] := 00446H;
iso88595[0E7H] := 00447H;
iso88595[0E8H] := 00448H;
iso88595[0E9H] := 00449H;
iso88595[0EAH] := 0044AH;
iso88595[0EBH] := 0044BH;
iso88595[0ECH] := 0044CH;
iso88595[0EDH] := 0044DH;
iso88595[0EEH] := 0044EH;
iso88595[0EFH] := 0044FH;
iso88595[0F0H] := 02116H;
iso88595[0F1H] := 00451H;
iso88595[0F2H] := 00452H;
iso88595[0F3H] := 00453H;
iso88595[0F4H] := 00454H;
iso88595[0F5H] := 00455H;
iso88595[0F6H] := 00456H;
iso88595[0F7H] := 00457H;
iso88595[0F8H] := 00458H;
iso88595[0F9H] := 00459H;
iso88595[0FAH] := 0045AH;
iso88595[0FBH] := 0045BH;
iso88595[0FCH] := 0045CH;
iso88595[0FDH] := 000A7H;
iso88595[0FEH] := 0045EH;
iso88595[0FFH] := 0045FH;
FOR i := aLowBound[ISO88595] TO 255 DO
c := CHR(i);
b := hashSearch(ISO88595, TRUE, iso88595[i], c)
END
END
END iso88595Init;
PROCEDURE CP1251DecoderFactory*(): Codecs.TextDecoder;
VAR p: CP1251Decoder;
BEGIN
cp1251Init;
NEW(p);
RETURN p
END CP1251DecoderFactory;
PROCEDURE CP1251EncoderFactory*(): Codecs.TextEncoder;
VAR p: CP1251Encoder;
BEGIN
cp1251Init;
NEW(p);
RETURN p
END CP1251EncoderFactory;
PROCEDURE KOI8RDecoderFactory*(): Codecs.TextDecoder;
VAR p: KOI8RDecoder;
BEGIN
koi8rInit;
NEW(p);
RETURN p
END KOI8RDecoderFactory;
PROCEDURE KOI8REncoderFactory*(): Codecs.TextEncoder;
VAR p: KOI8REncoder;
BEGIN
koi8rInit;
NEW(p);
RETURN p
END KOI8REncoderFactory;
PROCEDURE KOI8UDecoderFactory*(): Codecs.TextDecoder;
VAR p: KOI8UDecoder;
BEGIN
koi8uInit;
NEW(p);
RETURN p
END KOI8UDecoderFactory;
PROCEDURE KOI8UEncoderFactory*(): Codecs.TextEncoder;
VAR p: KOI8UEncoder;
BEGIN
koi8uInit;
NEW(p);
RETURN p
END KOI8UEncoderFactory;
PROCEDURE CP866DecoderFactory*(): Codecs.TextDecoder;
VAR p: CP866Decoder;
BEGIN
cp866Init;
NEW(p);
RETURN p
END CP866DecoderFactory;
PROCEDURE CP866EncoderFactory*(): Codecs.TextEncoder;
VAR p : CP866Encoder;
BEGIN
cp866Init;
NEW(p);
RETURN p
END CP866EncoderFactory;
PROCEDURE ISO88595DecoderFactory*(): Codecs.TextDecoder;
VAR p: ISO88595Decoder;
BEGIN
iso88595Init;
NEW(p);
RETURN p
END ISO88595DecoderFactory;
PROCEDURE ISO88595EncoderFactory*(): Codecs.TextEncoder;
VAR p: ISO88595Encoder;
BEGIN
iso88595Init;
NEW(p);
RETURN p
END ISO88595EncoderFactory;
PROCEDURE Init;
VAR
i: INTEGER;
BEGIN
FOR i := 0 TO PRIME - 1 DO
hash[i].ucs32 := 0;
hash[i].encodings := {}
END;
aLowBound[CP1251] := 080H;
aLowBound[KOI8R] := 080H;
aLowBound[KOI8U] := 080H;
aLowBound[CP866] := 080H;
aLowBound[ISO88595] := 0A0H;
setInitDone := {};
nCollisions := 0;
bFirst := TRUE;
END Init;
PROCEDURE HashStat*(context: Commands.Context);
VAR
i, n: INTEGER;
BEGIN
n := 0;
FOR i := 0 TO PRIME - 1 DO
IF hash[i].ucs32 # 0 THEN
INC(n)
END
END;
IF n = 0 THEN
context.out.Ln;
context.out.String("Hash table not yet initialized.");
context.out.Ln
ELSE
context.out.Ln;
context.out.Int(n, 1);
context.out.String(" of ");
context.out.Int(PRIME, 1);
context.out.String(" hash table cells used. Ratio: ");
context.out.Float(n / PRIME, 20);
context.out.Ln;
context.out.String("Number of collisions: ");
context.out.Int(nCollisions, 1);
context.out.Ln
END
END HashStat;
BEGIN
Init
END CyrillicUtilities.
SystemTools.Free CyrillicUtilities~
CyrillicUtilities.HashStat ~