2 * Copyright (c) 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
13 static const char sccsid
[] = "$Id: conv.c,v 1.11 2001/05/06 21:10:27 skimo Exp $ (Berkeley) $Date: 2001/05/06 21:10:27 $";
16 #include <sys/types.h>
17 #include <sys/queue.h>
20 #include <bitstring.h>
38 raw2int(SCR
*sp
, const char * str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
41 CHAR_T
**tostr
= (CHAR_T
**)&cw
->bp1
;
42 size_t *blen
= &cw
->blen1
;
44 BINC_RETW(NULL
, *tostr
, *blen
, len
);
47 for (i
= 0; i
< len
; ++i
)
48 (*tostr
)[i
] = (u_char
) str
[i
];
53 #define CONV_BUFFER_SIZE 512
54 /* fill the buffer with codeset encoding of string pointed to by str
55 * left has the number of bytes left in str and is adjusted
56 * len contains the number of bytes put in the buffer
58 #define CONVERT(str, left, src, len) \
62 outleft = CONV_BUFFER_SIZE; \
64 if (iconv(id, (char **)&str, &left, &bp, &outleft) == -1 && \
67 len = CONV_BUFFER_SIZE - outleft; \
72 default_char2int(SCR
*sp
, const char * str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
75 CHAR_T
**tostr
= (CHAR_T
**)&cw
->bp1
;
76 size_t *blen
= &cw
->blen1
;
80 char *src
= (char *)str
;
81 iconv_t id
= (iconv_t
)-1;
82 char *enc
= O_STR(sp
, O_FILEENCODING
);
83 char buffer
[CONV_BUFFER_SIZE
];
87 BINC_RETW(NULL
, *tostr
, *blen
, nlen
);
89 if (strcmp(nl_langinfo(CODESET
), enc
)) {
90 id
= iconv_open(nl_langinfo(CODESET
), enc
);
91 if (id
== (iconv_t
)-1)
93 CONVERT(str
, left
, src
, len
);
96 for (i
= 0, j
= 0; j
< len
; ) {
97 n
= mbrtowc((*tostr
)+i
, src
+j
, len
-j
, &mbs
);
98 /* NULL character converted */
99 if (n
== -1 || n
== -2) goto err
;
104 BINC_RETW(NULL
, *tostr
, *blen
, nlen
);
106 if (id
!= (iconv_t
)-1 && j
== len
&& left
) {
107 CONVERT(str
, left
, src
, len
);
113 if (id
!= (iconv_t
)-1)
119 if (id
!= (iconv_t
)-1)
125 int2raw(SCR
*sp
, const CHAR_T
* str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
128 char **tostr
= (char **)&cw
->bp1
;
129 size_t *blen
= &cw
->blen1
;
131 BINC_RET(NULL
, *tostr
, *blen
, len
);
134 for (i
= 0; i
< len
; ++i
)
135 (*tostr
)[i
] = str
[i
];
141 default_int2char(SCR
*sp
, const CHAR_T
* str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
143 int i
, j
, offset
= 0;
144 char **tostr
= (char **)&cw
->bp1
;
145 size_t *blen
= &cw
->blen1
;
148 ssize_t nlen
= len
+ MB_CUR_MAX
;
151 char buffer
[CONV_BUFFER_SIZE
];
152 iconv_t id
= (iconv_t
)-1;
153 char *enc
= O_STR(sp
, O_FILEENCODING
);
155 /* convert first len bytes of buffer and append it to cw->bp
156 * len is adjusted => 0
157 * offset contains the offset in cw->bp and is adjusted
158 * cw->bp is grown as required
160 #define CONVERT2(len, cw, offset) \
164 size_t outleft = cw->blen1 - offset; \
165 char *obp = cw->bp1 + offset; \
166 if (cw->blen1 < offset + MB_CUR_MAX) { \
168 BINC_RET(NULL, cw->bp1, cw->blen1, nlen); \
171 if (iconv(id, &bp, &len, &obp, &outleft) == -1 && \
174 offset = cw->blen1 - outleft; \
180 BINC_RET(NULL
, *tostr
, *blen
, nlen
);
181 dst
= *tostr
; buflen
= *blen
;
183 if (strcmp(nl_langinfo(CODESET
), enc
)) {
184 id
= iconv_open(enc
, nl_langinfo(CODESET
));
185 if (id
== (iconv_t
)-1)
187 dst
= buffer
; buflen
= CONV_BUFFER_SIZE
;
190 for (i
= 0, j
= 0; i
< len
; ++i
) {
191 n
= wcrtomb(dst
+j
, str
[i
], &mbs
);
192 if (n
== -1) goto err
;
194 if (buflen
< j
+ MB_CUR_MAX
) {
195 if (id
!= (iconv_t
)-1) {
196 CONVERT2(j
, cw
, offset
);
199 BINC_RET(NULL
, *tostr
, *blen
, nlen
);
200 dst
= *tostr
; buflen
= *blen
;
205 n
= wcrtomb(dst
+j
, L
'\0', &mbs
);
206 j
+= n
- 1; /* don't count NUL at the end */
209 if (id
!= (iconv_t
)-1) {
210 CONVERT2(j
, cw
, offset
);
220 //#ifdef HAVE_NCURSESW
223 default_int2disp (SCR
*sp
, const CHAR_T
* str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
227 char **tostr
= (char **)&cw
->bp1
;
228 size_t *blen
= &cw
->blen1
;
230 BINC_RET(NULL
, *tostr
, *blen
, len
* sizeof(chtype
));
234 for (i
= 0, j
= 0; i
< len
; ++i
)
235 if (str
[i
] > 0xffff) {
247 default_int2disp (SCR
*sp
, const CHAR_T
* str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
250 char **tostr
= (char **)&cw
->bp1
;
251 size_t *blen
= &cw
->blen1
;
253 BINC_RET(NULL
, *tostr
, *blen
, len
* 2);
255 for (i
= 0, j
= 0; i
< len
; ++i
)
256 if (CHAR_WIDTH(NULL
, str
[i
]) > 1) {
260 (*tostr
)[j
++] = str
[i
];
268 gb2int (SCR
*sp
, const char * str
, ssize_t len
, CONVWIN
*cw
, size_t *tolen
)
271 CHAR_T
**tostr
= (CHAR_T
**)&cw
->bp1
;
272 size_t *blen
= &cw
->blen1
;
274 BINC_RETW(NULL
, *tostr
, *blen
, len
);
276 for (i
= 0, j
= 0; i
< len
; ++i
) {
278 if (i
+1 < len
&& str
[i
+1] & 0x80) {
279 (*tostr
)[j
++] = INT9494(F_GB
,str
[i
]&0x7F,str
[i
+1]&0x7F);
282 (*tostr
)[j
++] = INTILL(str
[i
]);
285 (*tostr
)[j
++] = str
[i
];
292 CONV raw_conv
= { raw2int
, int2raw
,
293 raw2int
, int2raw
, default_int2disp
};
294 CONV default_conv
= { raw2int
, int2raw
,
295 default_char2int
, default_int2char
, default_int2disp
};
298 conv_init (SCR
*orig
, SCR
*sp
)
301 sp
->conv
= orig
->conv
;
303 setlocale(LC_ALL
, "");
304 sp
->conv
= &default_conv
;
305 o_set(sp
, O_FILEENCODING
, OS_STRDUP
, nl_langinfo(CODESET
), 0);
310 conv_enc (SCR
*sp
, char *enc
)
315 sp
->conv
= &raw_conv
;
318 id
= iconv_open(enc
, nl_langinfo(CODESET
));
319 if (id
== (iconv_t
)-1)
322 id
= iconv_open(nl_langinfo(CODESET
), enc
);
323 if (id
== (iconv_t
)-1)
330 "321|File encoding conversion not supported");