comparison src/vbuf.c @ 151:cda7c812ec01

track character set individually for each mapi element
author Carl Byington <carl@five-ten-sg.com>
date Sun, 08 Mar 2009 14:35:26 -0700
parents 2189a6b8134e
children ab384fed78c5
comparison
equal deleted inserted replaced
150:06aa84023b48 151:cda7c812ec01
41 // UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals 41 // UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals
42 42
43 static int unicode_up = 0; 43 static int unicode_up = 0;
44 static iconv_t i16to8; 44 static iconv_t i16to8;
45 static const char *target_charset = NULL; 45 static const char *target_charset = NULL;
46 static int target_open = 0; 46 static int target_open_from = 0;
47 static iconv_t i8totarget; 47 static int target_open_to = 0;
48 static iconv_t i8totarget = (iconv_t)-1;
49 static iconv_t target2i8 = (iconv_t)-1;
48 50
49 51
50 void unicode_init() 52 void unicode_init()
51 { 53 {
52 if (unicode_up) unicode_close(); 54 if (unicode_up) unicode_close();
53 i16to8 = iconv_open("UTF-8", "UTF-16LE"); 55 i16to8 = iconv_open("utf-8", "utf-16le");
54 if (i16to8 == (iconv_t)-1) { 56 if (i16to8 == (iconv_t)-1) {
55 fprintf(stderr, "Couldn't open iconv descriptor for UTF-16LE to UTF-8.\n"); 57 WARN(("Couldn't open iconv descriptor for utf-16le to utf-8.\n"));
56 exit(1); 58 exit(1);
57 } 59 }
58 unicode_up = 1; 60 unicode_up = 1;
59 } 61 }
60 62
61 63
62 void unicode_close() 64 void unicode_close()
63 { 65 {
64 iconv_close(i16to8); 66 iconv_close(i16to8);
65 if (target_open) { 67 if (target_open_from) iconv_close(i8totarget);
66 iconv_close(i8totarget); 68 if (target_open_to) iconv_close(target2i8);
67 free((char *)target_charset); 69 if (target_charset) free((char *)target_charset);
68 target_charset = NULL; 70 target_charset = NULL;
69 target_open = 0; 71 target_open_from = 0;
70 } 72 target_open_to = 0;
71 unicode_up = 0; 73 unicode_up = 0;
72 } 74 }
73 75
74 76
75 int utf16_is_terminated(const char *str, int length) 77 int utf16_is_terminated(const char *str, int length)
123 } 125 }
124 return (icresult) ? (size_t)-1 : 0; 126 return (icresult) ? (size_t)-1 : 0;
125 } 127 }
126 128
127 129
128 size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset) 130 static void open_targets(const char* charset);
131 static void open_targets(const char* charset)
132 {
133 if (!target_charset || strcasecmp(target_charset, charset)) {
134 if (target_open_from) iconv_close(i8totarget);
135 if (target_open_to) iconv_close(target2i8);
136 if (target_charset) free((char *)target_charset);
137 target_charset = strdup(charset);
138 target_open_from = 1;
139 target_open_to = 1;
140 i8totarget = iconv_open(target_charset, "utf-8");
141 if (i8totarget == (iconv_t)-1) {
142 target_open_from = 0;
143 WARN(("Couldn't open iconv descriptor for utf-8 to %s.\n", target_charset));
144 }
145 target2i8 = iconv_open("utf-8", target_charset);
146 if (target2i8 == (iconv_t)-1) {
147 target_open_to = 0;
148 WARN(("Couldn't open iconv descriptor for %s to utf-8.\n", target_charset));
149 }
150 }
151 }
152
153
154 static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion);
155 static size_t sbcs_conversion(vbuf *dest, const char *inbuf, int iblen, iconv_t conversion)
129 { 156 {
130 size_t inbytesleft = iblen; 157 size_t inbytesleft = iblen;
131 size_t icresult = (size_t)-1; 158 size_t icresult = (size_t)-1;
132 size_t outbytesleft = 0; 159 size_t outbytesleft = 0;
133 char *outbuf = NULL; 160 char *outbuf = NULL;
134 161
135 if (!target_charset || strcasecmp(target_charset, charset)) { 162 vbresize(dest, 2*iblen);
136 if (target_open) {
137 iconv_close(i8totarget);
138 free((char *)target_charset);
139 }
140 target_charset = strdup(charset);
141 target_open = 1;
142 i8totarget = iconv_open(target_charset, "UTF-8");
143 if (i8totarget == (iconv_t)-1) {
144 target_open = 0;
145 fprintf(stderr, "Couldn't open iconv descriptor for UTF-8 to %s.\n", target_charset);
146 return (size_t)-1;
147 }
148 }
149
150 if (!target_open) return (size_t)-1; // previous failure to open the target
151
152 if (2 > dest->blen) vbresize(dest, 2);
153 dest->dlen = 0; 163 dest->dlen = 0;
154 164
155 do { 165 do {
156 outbytesleft = dest->blen - dest->dlen; 166 outbytesleft = dest->blen - dest->dlen;
157 outbuf = dest->b + dest->dlen; 167 outbuf = dest->b + dest->dlen;
158 icresult = iconv(i8totarget, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft); 168 icresult = iconv(conversion, (ICONV_CONST char**)&inbuf, &inbytesleft, &outbuf, &outbytesleft);
159 dest->dlen = outbuf - dest->b; 169 dest->dlen = outbuf - dest->b;
160 vbgrow(dest, 20); 170 if (inbytesleft) vbgrow(dest, 2*inbytesleft);
161 } while ((size_t)-1 == icresult && E2BIG == errno); 171 } while ((size_t)-1 == icresult && E2BIG == errno);
162 172
163 if (icresult == (size_t)-1) { 173 if (icresult == (size_t)-1) {
164 WARN(("iconv failure: %s\n", strerror(errno))); 174 WARN(("iconv failure: %s\n", strerror(errno)));
165 unicode_init(); 175 unicode_init();
166 return (size_t)-1; 176 return (size_t)-1;
167 } 177 }
168 return (icresult) ? (size_t)-1 : 0; 178 return (icresult) ? (size_t)-1 : 0;
179 }
180
181
182 size_t vb_utf8to8bit(vbuf *dest, const char *inbuf, int iblen, const char* charset)
183 {
184 open_targets(charset);
185 if (!target_open_from) return (size_t)-1; // failure to open the target
186 return sbcs_conversion(dest, inbuf, iblen, i8totarget);
187 }
188
189
190 size_t vb_8bit2utf8(vbuf *dest, const char *inbuf, int iblen, const char* charset)
191 {
192 open_targets(charset);
193 if (!target_open_to) return (size_t)-1; // failure to open the target
194 return sbcs_conversion(dest, inbuf, iblen, target2i8);
169 } 195 }
170 196
171 197
172 vbuf *vballoc(size_t len) 198 vbuf *vballoc(size_t len)
173 { 199 {
222 248
223 size_t vbavail(vbuf * vb) 249 size_t vbavail(vbuf * vb)
224 { 250 {
225 return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf); 251 return vb->blen - vb->dlen - (size_t)(vb->b - vb->buf);
226 } 252 }
227
228
229 //void vbdump( vbuf *vb ) // TODO: to stdout? Yuck
230 //{
231 // printf("vb dump-------------\n");
232 // printf("dlen: %d\n", vb->dlen );
233 // printf("blen: %d\n", vb->blen );
234 // printf("b - buf: %d\n", vb->b - vb->buf );
235 // printf("buf:\n");
236 // hexdump( vb->buf, 0, vb->blen, 1 );
237 // printf("b:\n");
238 // hexdump( vb->b, 0, vb->dlen, 1 );
239 // printf("^^^^^^^^^^^^^^^^^^^^\n");
240 //}
241 253
242 254
243 void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved 255 void vbgrow(struct varbuf *vb, size_t len) // out: vbavail(vb) >= len, data are preserved
244 { 256 {
245 if (0 == len) 257 if (0 == len)