836888e49fbb91da14fc49d14638785bd4aab361
3 IMPORT S
:= SYSTEM
, Kernel
, stdlib
:= C99stdlib
, locale
:= C99locale
,
4 iconv
:= C99iconv
, errno
:= C99errno
, macro
:= C99macro
;
10 lang
-, country
-, encoding
-: ARRAY maxLen
OF CHAR;
11 c2sc
, sc2c
, invalid
: iconv
.iconv_t
;
15 PROCEDURE StringToHost
* (IN in
: ARRAY OF CHAR; OUT out
: ARRAY OF SHORTCHAR
; low
: BOOLEAN; OUT res
: INTEGER);
16 VAR i
, j
, err
: INTEGER; maxlen
, len
, count
: iconv
.size_t
; inadr
, outadr
: Kernel
.ADDRESS
; ch
: SHORTCHAR
;
18 ASSERT(c2sc
# invalid
, 100);
20 outadr
:= S
.ADR(out
[0]);
21 maxlen
:= LEN(out
) - 1;
22 WHILE (err
= 0) & (in
[i
] # 0X
) DO
24 WHILE (in
[i
] # 0X
) & ((in
[i
] < 0D800X
) OR (in
[i
] > 0D8FFX
)) DO INC(i
) END;
26 WHILE (err
= 0) & (len
> 0) & (maxlen
> 0) DO
27 inadr
:= S
.ADR(in
[j
]);
28 count
:= iconv
.iconv(c2sc
, inadr
, len
, outadr
, maxlen
);
32 (* !!! HALT(101)*) (* invalid input char *)
37 S
.PUT(outadr
, ch
); INC(outadr
); DEC(maxlen
);
40 | errno
.E2BIG
: err
:= 1 (* unexpected end of out *)
41 | errno
.EINVAL
: HALT(102) (* unexpected end of input *)
42 | errno
.EBADF
: HALT(103) (* invalid iconv descriptor *)
43 ELSE HALT(104) (* unknown error *)
47 WHILE (err
= 0) & (in
[i
] >= 0D800X
) & (in
[i
] <= 0D8FFX
) DO
51 ch
:= SHORT(CHR(ORD(in
[i
]) MOD 256));
52 IF low
OR (ch
> 7FX
) THEN
53 S
.PUT(outadr
, ch
); INC(outadr
); DEC(maxlen
);
56 err
:= 3 (* invalid char *)
66 PROCEDURE HostToString
* (IN in
: ARRAY OF SHORTCHAR
; OUT out
: ARRAY OF CHAR; low
: BOOLEAN; OUT res
: INTEGER);
67 VAR err
: INTEGER; maxin
, maxout
, count
: iconv
.size_t
; inadr
, outadr
: Kernel
.ADDRESS
; sch
: SHORTCHAR
; ch
: CHAR;
69 ASSERT(sc2c
# invalid
, 100);
71 inadr
:= S
.ADR(in
[0]);
72 outadr
:= S
.ADR(out
[0]);
73 maxin
:= LEN(in$
); maxout
:= LEN(out
) * 2 - 2;
74 WHILE (err
= 0) & (maxout
> 1) & (maxin
> 0) DO
75 count
:= iconv
.iconv(sc2c
, inadr
, maxin
, outadr
, maxout
);
78 | errno
.EILSEQ
, errno
.EINVAL
, errno
.E2BIG
:
80 err
:= 1 (* unexpected end of output buffer *)
82 err
:= 2 (* unexpected end of input buffer *)
84 S
.GET(inadr
, sch
); INC(inadr
); DEC(maxin
);
85 ch
:= CHR(0D800H
+ ORD(sch
));
86 IF low
OR (ch
> 7FX
) THEN
87 S
.PUT(outadr
, ch
); INC(outadr
, 2); DEC(maxout
, 2)
89 err
:= 3 (* invalid char *)
92 | errno
.EBADF
: HALT(101)
103 VAR p
: POINTER TO ARRAY [untagged
] OF SHORTCHAR
; i
, j
: INTEGER; enc
: ARRAY 32 OF SHORTCHAR
;
105 invalid
:= S
.VAL(iconv
.iconv_t
, -1);
106 p
:= locale
.setlocale(locale
.LC_ALL
, "");
108 p
:= stdlib
.getenv("LANG");
114 WHILE (p
[i
] # 0X
) & (p
[i
] # "_") & (p
[i
] # ".") DO
121 WHILE (p
[i
] # 0X
) & (p
[i
] # ".") DO
136 IF (lang
= "C") OR (lang
= "POSIX") THEN
139 sc2c
:= invalid
; c2sc
:= invalid
;
140 IF Kernel
.littleEndian
THEN sc2c
:= iconv
.iconv_open("UCS-2LE", enc
)
141 ELSE sc2c
:= iconv
.iconv_open("UCS-2BE", enc
)
143 IF sc2c
= invalid
THEN enc
:= "ASCII";
144 IF Kernel
.littleEndian
THEN sc2c
:= iconv
.iconv_open("UCS-2LE", enc
)
145 ELSE sc2c
:= iconv
.iconv_open("UCS-2BE", enc
)
147 ASSERT(c2sc
# invalid
, 100) (* ascii to ucs2 not supported? *)
149 IF Kernel
.littleEndian
THEN c2sc
:= iconv
.iconv_open(enc
, "UCS-2LE")
150 ELSE c2sc
:= iconv
.iconv_open(enc
, "UCS-2BE");
152 ASSERT(c2sc
# invalid
, 101); (* ucs2 to ascii not supported? *)
159 res
:= iconv
.iconv_close(sc2c
); sc2c
:= invalid
;
160 res
:= iconv
.iconv_close(c2sc
); c2sc
:= invalid