Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
iso2022.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30
31#include <rw/_defs.h>
32
33#include <string.h> // for strxxx()
34#include <iosfwd> // for mbstate_t
35
36#include <loc/_codecvt.h>
37#include <loc/_localedef.h>
38
39#include "iso2022.h"
40#include "locale_body.h"
41
42
43#define CHSET_ANSI_X_3_4_1968 6
44#define CHSET_JIS_X_0201_KANA 13
45#define CHSET_JIS_X_0201_ROMAN 14
46#define CHSET_JIS_X_0208_1978 42
47#define CHSET_JIS_X_0208_1983 87
48#define CHSET_JIS_X_0212_1990 159
49#define CHSET_GB2312_1980 58
50#define CHSET_KSC_5601_1987 149
51#define CHSET_ISO_8859_1 100
52#define CHSET_ISO_8859_7 126
53
54#define DBIDX_ANSI_X_3_4_1968 1
55#define DBIDX_ISO_8859_1 2
56#define DBIDX_ISO_8859_2 3
57#define DBIDX_ISO_8859_3 4
58#define DBIDX_ISO_8859_4 5
59#define DBIDX_ISO_8859_5 6
60#define DBIDX_ISO_8859_6 7
61#define DBIDX_ISO_8859_7 8
62#define DBIDX_ISO_8859_8 9
63#define DBIDX_EUC_JP 10
64#define DBIDX_EUC_KR 11
65#define DBIDX_GB2312 12
66
67#define ISO_2022_JP_SET_ASCII "\x1B(B"
68#define ISO_2022_JP_SET_JIS201_ROMAN "\x1B(J"
69#define ISO_2022_JP_SET_JIS201_KANA "\x1B(I"
70#define ISO_2022_JP_SET_JIS208_78 "\x1B$@"
71#define ISO_2022_JP_SET_JIS208_83 "\x1B$B"
72#define ISO_2022_JP_SET_GB2312_80 "\x1B$A"
73#define ISO_2022_JP_SET_KSC5601_87 "\x1B$(C"
74#define ISO_2022_JP_SET_JIS212_90 "\x1B$(D"
75#define ISO_2022_JP_SET_ISO_8859_1 "\x1B.A"
76#define ISO_2022_JP_SET_ISO_8859_7 "\x1B.F"
77#define ISO_2022_JP_SET_SS2 "\x1BN"
78
79
80#define ASCII_CHAR_LEN 1
81
82#define EUCJP_ASCII_CHAR_LEN 1
83#define EUCJP_JISX0201_ROMAN_CHAR_LEN 1
84#define EUCJP_JISX0201_KANA_CHAR_LEN 2
85#define EUCJP_JISX0208_CHAR_LEN 2
86#define EUCJP_JISX0212_CHAR_LEN 3
87
88#define GB2312_CHAR_LEN 2
89#define KSC5601_CHAR_LEN 2
90
91#define ISO_8859_1_CHAR_LEN 1
92#define ISO_8859_7_CHAR_LEN 1
93
94
95#define ISO_2022_SET_SB94_G0 0x28
96#define ISO_2022_SET_SB94_G1 0x29
97#define ISO_2022_SET_SB94_G2 0x2A
98#define ISO_2022_SET_SB94_G3 0x2B
99
100#define ISO_2022_SET_SB96_G1 0x2D
101#define ISO_2022_SET_SB96_G2 0x2E
102#define ISO_2022_SET_SB96_G3 0x2F
103
104#define ISO_2022_SET_MB 0x24
105
106#define ISO_2022_SET_MB94_G0 0x28
107#define ISO_2022_SET_MB94_G1 0x29
108#define ISO_2022_SET_MB94_G2 0x2A
109#define ISO_2022_SET_MB94_G3 0x2B
110
111#define ISO_2022_SET_MB96_G1 0x2D
112#define ISO_2022_SET_MB96_G2 0x2E
113#define ISO_2022_SET_MB96_G3 0x2F
114
115#define ISO_2022_SET_SS2 0x4E
116
117#define ESCAPE_CHAR 0x1B
118
119#if !defined (_UTF8_MB_CUR_MAX)
120# define _UTF8_MB_CUR_MAX 6
121#endif
122
123
124#define CODECVT_ERROR _STD::codecvt_base::error
125#define CODECVT_OK _STD::codecvt_base::ok
126#define CODECVT_PARTIAL _STD::codecvt_base::partial
127
128
130
131
132enum __rw_codeset_type_t {
133 sb94 = 0, sb96, mb94, mb96
134};
135
136// State of the ISO-2022 conversions
137struct __rw_iso2022_state_t {
138 // 0 - unused, 1 - used, default 0
139 unsigned used:1;
140
141 // invoked code elements: valid values 1-4, invalid 0, default 0
142 unsigned gl_map:3;
143 unsigned gr_map:3;
144
145 // shift state: 0 - one character, 1 - two characters, default 0
146 unsigned shift_state:1;
147
148 // single-shift 2 and 3 functions
149 unsigned sshift2:1;
150 unsigned sshift3:1;
151
152 // equivalent of G0-G3 code elements
153 unsigned char g_map [4]; // default 0
154};
155
156// Mapping between the code of the character set and the name
157struct __rw_chset_map_t
158{
159 const char* name; // codeset canonical name
160 unsigned char index; // database index
161 unsigned char width; // encoding width
162 const char* seq; // designating sequence
163 unsigned int seqlen; // designating sequence length
164};
165
166// Database file mappings
167struct __rw_db_map_t
168{
169 const void* pv; // pointer to mapping
170 _RWSTD_SIZE_T size; // size of mapping
171 const char* name; // canonical name
172};
173
174
175// make sure there is just one copy of the empty string used
176// in the table below (space optimization in case the compiler
177// doesn't collapse them automatically
178static const char __rw_empty[] = "";
179
180
181// Array of mappings: code registration number to name
182static const __rw_chset_map_t __rw_chset_map [256] = {
183
184#define EMPTY __rw_empty, 0, 0, 0, 0
185
186 {/* 0x00 */ EMPTY }, {/* 0x01 */ EMPTY }, {/* 0x02 */ EMPTY },
187 {/* 0x03 */ EMPTY }, {/* 0x04 */ EMPTY }, {/* 0x05 */ EMPTY },
188
189 {
190 /* 0x06 */ "ANSI_X3.4-1968", DBIDX_ANSI_X_3_4_1968, 0,
192 sizeof (ISO_2022_JP_SET_ASCII) - 1U
193 },
194
195 {/* 0x07 */ EMPTY }, {/* 0x08 */ EMPTY }, {/* 0x09 */ EMPTY },
196 {/* 0x0a */ EMPTY }, {/* 0x0b */ EMPTY }, {/* 0x0c */ EMPTY },
197
198 {
199 /* 0x0d */ "EUC-JP", DBIDX_EUC_JP, 0,
201 sizeof (ISO_2022_JP_SET_JIS201_KANA) - 1U
202 },
203
204 {
205 /* 0x0e */ "EUC-JP", DBIDX_EUC_JP, 0,
207 sizeof (ISO_2022_JP_SET_JIS201_ROMAN) - 1U
208 },
209
210 {/* 0x0f */ EMPTY }, {/* 0x10 */ EMPTY }, {/* 0x11 */ EMPTY },
211 {/* 0x12 */ EMPTY }, {/* 0x13 */ EMPTY }, {/* 0x14 */ EMPTY },
212 {/* 0x15 */ EMPTY }, {/* 0x16 */ EMPTY }, {/* 0x17 */ EMPTY },
213 {/* 0x18 */ EMPTY }, {/* 0x19 */ EMPTY }, {/* 0x1a */ EMPTY },
214 {/* 0x1b */ EMPTY }, {/* 0x1c */ EMPTY }, {/* 0x1d */ EMPTY },
215 {/* 0x1e */ EMPTY }, {/* 0x1f */ EMPTY }, {/* 0x20 */ EMPTY },
216 {/* 0x21 */ EMPTY }, {/* 0x22 */ EMPTY }, {/* 0x23 */ EMPTY },
217 {/* 0x24 */ EMPTY }, {/* 0x25 */ EMPTY }, {/* 0x26 */ EMPTY },
218 {/* 0x27 */ EMPTY }, {/* 0x28 */ EMPTY }, {/* 0x29 */ EMPTY },
219
220 {
221 /* 0x2a */ "EUC-JP", DBIDX_EUC_JP, 1,
223 sizeof (ISO_2022_JP_SET_JIS208_78) - 1U
224 },
225
226 {/* 0x2b */ EMPTY }, {/* 0x2c */ EMPTY }, {/* 0x2d */ EMPTY },
227 {/* 0x2e */ EMPTY }, {/* 0x2f */ EMPTY }, {/* 0x30 */ EMPTY },
228 {/* 0x31 */ EMPTY }, {/* 0x32 */ EMPTY }, {/* 0x33 */ EMPTY },
229 {/* 0x34 */ EMPTY }, {/* 0x35 */ EMPTY }, {/* 0x36 */ EMPTY },
230 {/* 0x37 */ EMPTY }, {/* 0x38 */ EMPTY }, {/* 0x39 */ EMPTY },
231
232 {
233 /* 0x3a */ "GB2312", DBIDX_GB2312, 1,
235 sizeof (ISO_2022_JP_SET_GB2312_80) - 1U
236 },
237
238 {/* 0x3b */ EMPTY },
239 {/* 0x3c */ EMPTY }, {/* 0x3d */ EMPTY }, {/* 0x3e */ EMPTY },
240 {/* 0x3f */ EMPTY }, {/* 0x40 */ EMPTY }, {/* 0x41 */ EMPTY },
241 {/* 0x42 */ EMPTY }, {/* 0x43 */ EMPTY }, {/* 0x44 */ EMPTY },
242 {/* 0x45 */ EMPTY }, {/* 0x46 */ EMPTY }, {/* 0x47 */ EMPTY },
243 {/* 0x48 */ EMPTY }, {/* 0x49 */ EMPTY }, {/* 0x4a */ EMPTY },
244 {/* 0x4b */ EMPTY }, {/* 0x4c */ EMPTY }, {/* 0x4d */ EMPTY },
245 {/* 0x4e */ EMPTY }, {/* 0x4f */ EMPTY }, {/* 0x50 */ EMPTY },
246 {/* 0x51 */ EMPTY }, {/* 0x52 */ EMPTY }, {/* 0x53 */ EMPTY },
247 {/* 0x54 */ EMPTY }, {/* 0x55 */ EMPTY }, {/* 0x56 */ EMPTY },
248
249 {
250 /* 0x57 */ "EUC-JP", DBIDX_EUC_JP, 1,
252 sizeof (ISO_2022_JP_SET_JIS208_83) - 1U
253 },
254
255 {/* 0x58 */ EMPTY }, {/* 0x59 */ EMPTY }, {/* 0x5a */ EMPTY },
256 {/* 0x5b */ EMPTY }, {/* 0x5c */ EMPTY }, {/* 0x5d */ EMPTY },
257 {/* 0x5e */ EMPTY }, {/* 0x5f */ EMPTY }, {/* 0x60 */ EMPTY },
258 {/* 0x61 */ EMPTY }, {/* 0x62 */ EMPTY }, {/* 0x63 */ EMPTY },
259
260 {
261 /* 0x64 */ "ISO-8859-1", DBIDX_ISO_8859_1, 0,
263 sizeof (ISO_2022_JP_SET_ISO_8859_1) - 1U
264 },
265
266 {/* 0x65 */ EMPTY }, {/* 0x66 */ EMPTY }, {/* 0x67 */ EMPTY },
267 {/* 0x68 */ EMPTY }, {/* 0x69 */ EMPTY }, {/* 0x6a */ EMPTY },
268 {/* 0x6b */ EMPTY }, {/* 0x6c */ EMPTY }, {/* 0x6d */ EMPTY },
269 {/* 0x6e */ EMPTY }, {/* 0x6f */ EMPTY }, {/* 0x70 */ EMPTY },
270 {/* 0x71 */ EMPTY }, {/* 0x72 */ EMPTY }, {/* 0x73 */ EMPTY },
271 {/* 0x74 */ EMPTY }, {/* 0x75 */ EMPTY }, {/* 0x76 */ EMPTY },
272 {/* 0x77 */ EMPTY }, {/* 0x78 */ EMPTY }, {/* 0x79 */ EMPTY },
273 {/* 0x7a */ EMPTY }, {/* 0x7b */ EMPTY }, {/* 0x7c */ EMPTY },
274 {/* 0x7d */ EMPTY },
275
276 {
277 /* 0x7e */ "ISO-8859-7", DBIDX_ISO_8859_7, 0,
279 sizeof (ISO_2022_JP_SET_ISO_8859_7) - 1U
280 },
281
282 {/* 0x7f */ EMPTY }, {/* 0x80 */ EMPTY }, {/* 0x81 */ EMPTY },
283 {/* 0x82 */ EMPTY }, {/* 0x83 */ EMPTY }, {/* 0x84 */ EMPTY },
284 {/* 0x85 */ EMPTY }, {/* 0x86 */ EMPTY }, {/* 0x87 */ EMPTY },
285 {/* 0x88 */ EMPTY }, {/* 0x89 */ EMPTY }, {/* 0x8a */ EMPTY },
286 {/* 0x8b */ EMPTY }, {/* 0x8c */ EMPTY }, {/* 0x8d */ EMPTY },
287 {/* 0x8e */ EMPTY }, {/* 0x8f */ EMPTY }, {/* 0x90 */ EMPTY },
288 {/* 0x91 */ EMPTY }, {/* 0x92 */ EMPTY }, {/* 0x93 */ EMPTY },
289 {/* 0x94 */ EMPTY },
290
291 {
292 /* 0x95 */ "EUC-KR", DBIDX_EUC_KR, 1,
294 sizeof (ISO_2022_JP_SET_KSC5601_87) - 1U
295 },
296
297 {/* 0x96 */ EMPTY }, {/* 0x97 */ EMPTY }, {/* 0x98 */ EMPTY },
298 {/* 0x99 */ EMPTY }, {/* 0x9a */ EMPTY }, {/* 0x9b */ EMPTY },
299 {/* 0x9c */ EMPTY }, {/* 0x9d */ EMPTY }, {/* 0x9e */ EMPTY },
300
301 {
302 /* 0x9f */ "EUC-JP", DBIDX_EUC_JP, 1,
304 sizeof (ISO_2022_JP_SET_JIS212_90) - 1U
305 },
306
307 {/* 0xa0 */ EMPTY }, {/* 0xa1 */ EMPTY }, {/* 0xa2 */ EMPTY },
308 {/* 0xa3 */ EMPTY }, {/* 0xa4 */ EMPTY }, {/* 0xa5 */ EMPTY },
309 {/* 0xa6 */ EMPTY }, {/* 0xa7 */ EMPTY }, {/* 0xa8 */ EMPTY },
310 {/* 0xa9 */ EMPTY }, {/* 0xaa */ EMPTY }, {/* 0xab */ EMPTY },
311 {/* 0xac */ EMPTY }, {/* 0xad */ EMPTY }, {/* 0xae */ EMPTY },
312 {/* 0xaf */ EMPTY }, {/* 0xb0 */ EMPTY }, {/* 0xb1 */ EMPTY },
313 {/* 0xb2 */ EMPTY }, {/* 0xb3 */ EMPTY }, {/* 0xb4 */ EMPTY },
314 {/* 0xb5 */ EMPTY }, {/* 0xb6 */ EMPTY }, {/* 0xb7 */ EMPTY },
315 {/* 0xb8 */ EMPTY }, {/* 0xb9 */ EMPTY }, {/* 0xba */ EMPTY },
316 {/* 0xbb */ EMPTY }, {/* 0xbc */ EMPTY }, {/* 0xbd */ EMPTY },
317 {/* 0xbe */ EMPTY }, {/* 0xbf */ EMPTY }, {/* 0xc0 */ EMPTY },
318 {/* 0xc1 */ EMPTY }, {/* 0xc2 */ EMPTY }, {/* 0xc3 */ EMPTY },
319 {/* 0xc4 */ EMPTY }, {/* 0xc5 */ EMPTY }, {/* 0xc6 */ EMPTY },
320 {/* 0xc7 */ EMPTY }, {/* 0xc8 */ EMPTY }, {/* 0xc9 */ EMPTY },
321 {/* 0xca */ EMPTY }, {/* 0xcb */ EMPTY }, {/* 0xcc */ EMPTY },
322 {/* 0xcd */ EMPTY }, {/* 0xce */ EMPTY }, {/* 0xcf */ EMPTY },
323 {/* 0xd0 */ EMPTY }, {/* 0xd1 */ EMPTY }, {/* 0xd2 */ EMPTY },
324 {/* 0xd3 */ EMPTY }, {/* 0xd4 */ EMPTY }, {/* 0xd5 */ EMPTY },
325 {/* 0xd6 */ EMPTY }, {/* 0xd7 */ EMPTY }, {/* 0xd8 */ EMPTY },
326 {/* 0xd9 */ EMPTY }, {/* 0xda */ EMPTY }, {/* 0xdb */ EMPTY },
327 {/* 0xdc */ EMPTY }, {/* 0xdd */ EMPTY }, {/* 0xde */ EMPTY },
328 {/* 0xdf */ EMPTY }, {/* 0xe0 */ EMPTY }, {/* 0xe1 */ EMPTY },
329 {/* 0xe2 */ EMPTY }, {/* 0xe3 */ EMPTY }, {/* 0xe4 */ EMPTY },
330 {/* 0xe5 */ EMPTY }, {/* 0xe6 */ EMPTY }, {/* 0xe7 */ EMPTY },
331 {/* 0xe8 */ EMPTY }, {/* 0xe9 */ EMPTY }, {/* 0xea */ EMPTY },
332 {/* 0xeb */ EMPTY }, {/* 0xec */ EMPTY }, {/* 0xed */ EMPTY },
333 {/* 0xee */ EMPTY }, {/* 0xef */ EMPTY }, {/* 0xf0 */ EMPTY },
334 {/* 0xf1 */ EMPTY }, {/* 0xf2 */ EMPTY }, {/* 0xf3 */ EMPTY },
335 {/* 0xf4 */ EMPTY }, {/* 0xf5 */ EMPTY }, {/* 0xf6 */ EMPTY },
336 {/* 0xf7 */ EMPTY }, {/* 0xf8 */ EMPTY }, {/* 0xf9 */ EMPTY },
337 {/* 0xfa */ EMPTY }, {/* 0xfb */ EMPTY }, {/* 0xfc */ EMPTY },
338 {/* 0xfd */ EMPTY }, {/* 0xfe */ EMPTY }, {/* 0xff */ EMPTY }
339};
340
341
342// Mapping pointer - size of mapping - canonical name
343static __rw_db_map_t __rw_db_map [32] = {
344 { 0, 0, __rw_empty }, { 0, 0, "ANSI_X3.4-1968" },
345 { 0, 0, "ISO-8859-1" }, { 0, 0, "ISO-8859-2" },
346 { 0, 0, "ISO-8859-3" }, { 0, 0, "ISO-8859-4" },
347 { 0, 0, "ISO-8859-5" }, { 0, 0, "ISO-8859-6" },
348 { 0, 0, "ISO-8859-7" }, { 0, 0, "ISO-8859-8" },
349 { 0, 0, "EUC-JP" }, { 0, 0, "EUC-KR" },
350 { 0, 0, "GB2312" }, { 0, 0, __rw_empty },
351 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
352 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
353 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
354 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
355 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
356 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
357 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
358 { 0, 0, __rw_empty }, { 0, 0, __rw_empty },
359 { 0, 0, __rw_empty }, { 0, 0, __rw_empty }
360};
361
362
363// Retrieves the type of the encoding as indicated by the name
364int __rw_encoding_from_name (const char* name)
365{
366 _RWSTD_ASSERT (0 != name);
367
368 static const char pfx [] = "ISO-2022-";
369
370 if (0 != strncmp (pfx, name, sizeof pfx - 1U))
371 return stateless;
372
373 name += sizeof pfx - 1U;
374
375 if (0 == strcmp (name, "JP-2")) {
376 return iso2022_jp2;
377 }
378 if (0 == strcmp (name, "JP")) {
379 return iso2022_jp;
380 }
381 if (0 == strcmp (name, "KR")) {
382 return iso2022_kr;
383 }
384 if (0 == strcmp (name, "CN")) {
385 return iso2022_cn;
386 }
387 return stateless;
388}
389
390
391// Array of ISO-2022 encoding states; the array has a default size of 256
392// entries; the declaration of the array is guarded for size
393//
394// The usage of the structs in the array:
395// - the struct "allocated" are marked as used;
396// - the index of the struct in the array is stored in the std::mbstate_t
397// struct used in codecvt facet;
398// - the std::mbstate_t values are shifted from the real iso2022_state
399// struct index by one so that a value of zero in an std::mbstate_t
400// variable indicates a new conversion for which a state has to be
401// allocated
402#if _RWSTD_MBSTATE_T_SIZE == 1
403# define ISO_2022_ARRAY_SIZE 255
404# define ISO_2022_STATE_INDEX_T unsigned char
405#else
406# define ISO_2022_ARRAY_SIZE 511
407# define ISO_2022_STATE_INDEX_T unsigned short
408#endif
409
410
411// array of available states (limits the number of distinct mbstate_t
412// objects with unique value that may be simultaneously valid)
413static __rw_iso2022_state_t __rw_iso2022_states [ISO_2022_ARRAY_SIZE];
414
415
416// returns an index in the array of state structures or -1 if none
417// is available; ISO-2022-JP and ISO-2022-JP-2 assume different
418// initializations
419static inline
420int __rw_allocate_state ()
421{
422 _RWSTD_MT_CLASS_GUARD (__rw_iso2022_state_t);
423
424 for (int i = 0; i < ISO_2022_ARRAY_SIZE; i++)
425 if (__rw_iso2022_states [i].used == 0) {
426 __rw_iso2022_states [i].used = 1;
427 return i;
428 }
429
430 return -1;
431}
432
433
434// deallocates state and makes it available for future conversions
435// if `initial_only' is non-zero suceeds only if the `iso_state'
436// argument represents an initial shift state
437static inline
438void __rw_deallocate_state (__rw_iso2022_state_t &iso_state,
439 _RWSTD_MBSTATE_T &state,
440 bool initial_only)
441{
442 _RWSTD_MT_CLASS_GUARD (__rw_iso2022_state_t);
443
444 if (initial_only) {
445 // test the state object for return to initial shift state
446 const int i = iso_state.gl_map - 1;
447 _RWSTD_ASSERT (i >= 0 && i < 4);
448
449 if ( iso_state.g_map [i] != CHSET_ANSI_X_3_4_1968
450 || iso_state.sshift2
451 || iso_state.sshift3)
452 return;
453
454 // proceed only if `iostate' is in an initial shift state
455 }
456
457 // zero out both structures
458 memset (&state, 0, sizeof state);
459 memset (&iso_state, 0, sizeof iso_state);
460}
461
462
463static __rw_iso2022_state_t*
464__rw_get_iso2022_state (_RWSTD_MBSTATE_T& state, int enc)
465{
466 __rw_iso2022_state_t* pstate = 0;
467
468 // retrieve the array index
471
472 int n = *pc;
473
475
476 // a value of zero in std::mbstate_t indicates conversion anew,
477 // calling for a state allocation
478 if (n == 0) {
479 n = __rw_allocate_state ();
480
481 // the case when the allocation was not possible
482 if (n == -1)
483 return pstate;
484
485 // store the state index
487 }
488 else
489 n--;
490
491 // store the pointer to the state object
492 pstate = &__rw_iso2022_states [n];
493
494 // initialize the state according to the encoding type
495 switch (enc) {
496 case iso2022_jp:
497 case iso2022_jp2:
498 pstate->g_map [0] = CHSET_ANSI_X_3_4_1968;
499 pstate->gl_map = 1;
500 break;
501 default:
502 break;
503 }
504
505 return pstate;
506}
507
508
509// Retrieval of the character set's registration number; the code
510// designator values overlap (they are, however, distinct in each category)
511static inline
512unsigned char __rw_sb94_encoding_reg (unsigned char c)
513{
514 unsigned char reg = 0;
515
516 switch (c) {
517 case 0x42:
518 reg = CHSET_ANSI_X_3_4_1968; /* ANSI X-3.4/1968 */
519 break;
520 case 0x49:
521 reg = CHSET_JIS_X_0201_KANA; /* JIS X 0201 Katakana */
522 break;
523 case 0x4a:
524 reg = CHSET_JIS_X_0201_ROMAN; /* JIS X 0201 Roman */
525 break;
526 }
527
528 return reg;
529}
530
531
532static inline
533unsigned char __rw_sb96_encoding_reg (unsigned char c)
534{
535 unsigned char reg = 0;
536
537 switch (c) {
538 case 0x41:
539 reg = CHSET_ISO_8859_1; /* ISO-8859-1 */
540 break;
541 case 0x46:
542 reg = CHSET_ISO_8859_7; /* ISO-8859-7 */
543 break;
544 }
545
546 return reg;
547}
548
549
550static inline
551unsigned char __rw_mb94_encoding_reg (unsigned char c)
552{
553 unsigned char reg = 0;
554
555 switch (c) {
556 case 0x40:
557 reg = CHSET_JIS_X_0208_1978; /* JIS X 0208-1978 */
558 break;
559 case 0x41:
560 reg = CHSET_GB2312_1980; /* GB 2312-80 */
561 break;
562 case 0x42:
563 reg = CHSET_JIS_X_0208_1983; /* JIS X 0208-1983 */
564 break;
565 case 0x43:
566 reg = CHSET_KSC_5601_1987; /* KSC 5601 Korean */
567 break;
568 case 0x44:
569 reg = CHSET_JIS_X_0212_1990; /* JIS X 0212-1990 */
570 break;
571 }
572
573 return reg;
574}
575
576
577static inline
578unsigned char __rw_mb96_encoding_reg (unsigned char)
579{
580 return 0;
581}
582
583
584// Retrieves the code registration associated with a particular encoding class
585// and a particular character set designator in that class
586static inline
587unsigned char __rw_get_encoding_reg (__rw_codeset_type_t type,
588 unsigned char code)
589{
590 switch (type) {
591 case sb94:
592 return __rw_sb94_encoding_reg (code);
593 case sb96:
594 return __rw_sb96_encoding_reg (code);
595 case mb94:
596 return __rw_mb94_encoding_reg (code);
597 case mb96:
598 return __rw_mb96_encoding_reg (code);
599 }
600
601 return 0;
602}
603
604
605#if 0 // unused
606
607// Retrieval of the character set's registration name
608static inline
609const char* __rw_get_encoding_name (unsigned char n)
610{
611 return (__rw_chset_map [n].name [0] == 0)?0:__rw_chset_map [n].name;
612}
613
614
615// A way of mapping a combination type-code to an index in the array of
616// codecvt databases mappings. The databases mappings are installed in
617// the array of mappings like this:
618// 1 - ANSI.X-3.4-1968
619// 2-9 - ISO-8859-1, 2, 3, 4, 5, 6, 7, 8
620// 10 - EUC-JP
621// 11 - EUC-KR
622// 12 - GB2312-1980
623static inline
624unsigned char __rw_get_encoding_dbindex (__rw_codeset_type_t t,
625 unsigned char code)
626{
627 unsigned char reg = __rw_get_encoding_reg (t, code);
628 if (reg == 0)
629 return 0;
630
631 return __rw_chset_map [reg].index;
632}
633
634#endif // 0/1
635
636
637static inline
638const void* __rw_get_encoding_database (unsigned char n)
639{
640 // if already mapped return it
641 if (__rw_db_map [n].pv)
642 return __rw_db_map [n].pv;
643
644 // a wrong index would point to a struct bearing no name
645 if (__rw_db_map [n].name [0] == 0)
646 return 0;
647
648 // if not, obtain it from __rw_get_facet_data
649 int cat = __rw_get_cat ((__rw_facet::_C_wcodecvt_byname + 1) / 2);
650 __rw_db_map [n].pv =
651 __rw_get_facet_data (cat, __rw_db_map[n].size, 0,
652 __rw_db_map [n].name);
653
654 return __rw_db_map [n].pv;
655}
656
657
658// Insert designating sequence in the destination buffer; the encoding is
659// given by the last parameter and is currently one of the following:
660// - ISO_2022-JP
661// - ISO_2022-JP2
662static _STD::codecvt_base::result
663__rw_iso2022jp_designate (__rw_iso2022_state_t& state,
664 char*& to,
665 char* to_end,
666 unsigned char reg,
667 int enc)
668{
669 // length of a designating sequence in ISO-2022-JP and
670 // ISO-2022-JP-2 is 3 or 4 elements
671 _RWSTD_SIZE_T len = sizeof (ISO_2022_JP_SET_ASCII) - 1U;
672 _RWSTD_SIZE_T sslen = 0;
673
674 // register designation
675 bool g2 = false;
676
677 const char* esc = 0;
678 const char* ss = 0;
679
680 switch (reg) {
683 break;
686 break;
689 break;
692 break;
694 esc = (enc == iso2022_jp)?0:ISO_2022_JP_SET_GB2312_80;
695 break;
696 case CHSET_ISO_8859_1:
697 esc = (enc == iso2022_jp)?0:ISO_2022_JP_SET_ISO_8859_1;
699 sslen = sizeof (ISO_2022_JP_SET_SS2) - 1U;
700 g2 = true;
701 break;
702 case CHSET_ISO_8859_7:
703 esc = (enc == iso2022_jp)?0:ISO_2022_JP_SET_ISO_8859_7;
705 sslen = sizeof (ISO_2022_JP_SET_SS2) - 1U;
706 g2 = true;
707 break;
708
709 // only JIS X 0212-1990 and KSC5601-1987 are 4 elements long
711 if (enc != iso2022_jp) {
713 len = sizeof (ISO_2022_JP_SET_JIS212_90) - 1U;
714 }
715 break;
716
718 if (enc != iso2022_jp) {
720 len = sizeof (ISO_2022_JP_SET_KSC5601_87) - 1U;
721 }
722 break;
723
724 default:
725 return CODECVT_ERROR;
726 }
727
728 if (g2) {
729 if (state.sshift2 == 1) {
730 // there is already a correct designation and a single
731 // shift function inserted in the destination buffer
732 return CODECVT_OK;
733 }
734
735 // insert the designation
736 if (reg != state.g_map [2]) {
737 // FIXME - check correctness
738 if (_RWSTD_STATIC_CAST (_RWSTD_SIZE_T, to_end - to) < len)
739 return CODECVT_PARTIAL;
740
741 if (len) {
742 _RWSTD_ASSERT (to && esc);
743
744 memcpy (to, esc, len);
745 to += len;
746 }
747
748 // adjust the state
749 state.g_map [2] = reg;
750 }
751
752 // insert the single shift function
753 // FIXME - check correctness
754 if (_RWSTD_STATIC_CAST (_RWSTD_SIZE_T, to_end - to) < len)
755 return CODECVT_PARTIAL;
756
757 if (sslen) {
758 _RWSTD_ASSERT (to && ss);
759
760 memcpy (to, ss, sslen);
761 to += sslen;
762 }
763
764 // adjust the single shift indicator
765 state.sshift2 = 1;
766 } else {
767
768 // FIXME - check correctness
769 if (_RWSTD_STATIC_CAST (_RWSTD_SIZE_T, to_end - to) < len)
770 return CODECVT_PARTIAL;
771
772 if (len) {
773 _RWSTD_ASSERT (to && esc);
774
775 memcpy (to, esc, len);
776 to += len;
777 }
778
779 // adjust the state
780 state.g_map [0] = reg;
781 state.gl_map = 1;
782 state.shift_state = __rw_chset_map [reg].width;
783 }
784 return CODECVT_OK;
785}
786
787// Process one escape sequence in an ISO-2022 stream;
788//
789// Upon entry:
790// - from - points to the first byte after the ESCAPE_CHAR indicator;
791// - enc - encoding type.
792static _STD::codecvt_base::result
793__rw_iso2022_escape (__rw_iso2022_state_t& state,
794 const char*& from,
795 const char* from_end,
796 int enc)
797{
798 // copy of source pointer
799 const char* ps = from + 1;
800
801 // test for end of sequence
802 if (from_end == ps)
803 return CODECVT_OK;
804
805
806 __rw_codeset_type_t type = sb94;
807 switch (*ps) {
808 case ISO_2022_SET_SS2:
809 // Single-Shift 2 invokes G2 in GL for one character;
810 // adjust the source pointer...
811 from = ++ps;
812
813 // ...and set the single-shift 2 flag in the state structure
814 state.sshift2 = 1;
815 return CODECVT_OK;
816
818 type = sb94;
819 break;
820
822 type = sb96;
823 break;
824
825 case ISO_2022_SET_MB:
826 type = mb94;
827
828 // test for end of sequence
829 if (from_end == ps + 1)
830 return CODECVT_OK;
831
832 // advance one more; this designation is 4 bytes long
833 if (*(ps + 1) == ISO_2022_SET_MB94_G0)
834 ps++;
835 break;
836
837 default:
838 return CODECVT_ERROR;
839 }
840
841 if (from_end == ++ps)
842 return CODECVT_OK;
843
844 // retrieve the registration code and store the state
845 const unsigned char reg = __rw_get_encoding_reg (type, *ps++);
846 if (!reg)
847 return CODECVT_ERROR;
848
849 // check the registration code returned by the function above
850 if (enc == iso2022_jp &&
851 (reg == CHSET_JIS_X_0212_1990 || reg == CHSET_GB2312_1980 ||
852 reg == CHSET_KSC_5601_1987 || reg == CHSET_ISO_8859_1 ||
853 reg == CHSET_ISO_8859_7)) {
854 return CODECVT_ERROR;
855 }
856
857 // designation is always in G0 unless the type is sb96
858 state.g_map [type == sb96 ? 2 : 0] = reg;
859
860 // however, the invocation is always in GL for ISO-2022-xxx!!
861 state.gl_map = 1;
862 state.shift_state = __rw_chset_map [reg].width;
863
864 // adjust the source pointer
865 from = ps;
866 return CODECVT_OK;
867}
868
869
871// ISO-2022-JP conversion from ANSI_X3.4-1968
872// Convert one character.
873// Returns:
874// std::codecvt_base::ok in case the conversion succeeded
875// std::codecvt_base::partial for partial conversions
876// std::codecvt_base::error erroneous sequence
877static _STD::codecvt_base::result
878__rw_ascii_to_iso2022 (__rw_iso2022_state_t& state,
879 const char*& from,
880 const char* from_end,
881 char*& to,
882 char* to_end,
883 int enc)
884{
885 // the registration
886 unsigned char reg = CHSET_ANSI_X_3_4_1968;
887 unsigned int width = __rw_chset_map [reg].width + 1;
888
889 _RWSTD_ASSERT (from_end-from >= int(width));
890 _RWSTD_UNUSED (from_end);
891
892 _STD::codecvt_base::result ret;
893
894 // check the designation sequence
895 if (state.g_map [0] != reg) {
896 char* pd = to;
897
898 // insert a designation sequence in this place
899 ret = __rw_iso2022jp_designate (state, pd, to_end, reg, enc);
900 if (ret != CODECVT_OK)
901 return ret;
902
903 state.gl_map = 1;
904 state.g_map [0] = reg;
905 state.shift_state = __rw_chset_map [reg].width;
906
907 // adjust destination pointer
908 to = pd;
909
910 if (to == to_end)
911 return ret;
912 }
913
914 // FIXME - check the validity of this test
915 if (to_end - to < int (width))
916 return CODECVT_PARTIAL;
917
918 *to++ = char (*from++ & 0x7f);
919 if (width > 1)
920 *to++ = char (*from++ & 0x7f);
921
922 return CODECVT_OK;
923}
924
925
926// ISO-2022-JP conversion from KSC5601-1987
927// Convert one character.
928// Returns:
929// std::codecvt_base::ok in case the conversion succeeded
930// std::codecvt_base::partial for partial conversions
931// std::codecvt_base::error erroneous sequence
932static _STD::codecvt_base::result
933__rw_ksc5601_to_iso2022 (__rw_iso2022_state_t& state,
934 const char*& from,
935 const char* from_end,
936 char*& to,
937 char* to_end,
938 int enc)
939{
940 // the registration
941 unsigned char reg = CHSET_KSC_5601_1987;
942 unsigned int width = __rw_chset_map [reg].width + 1;
943
944 _RWSTD_ASSERT(from_end-from >= int(width));
945 _RWSTD_UNUSED(from_end);
946
947 _STD::codecvt_base::result ret;
948
949 // check the designation sequence
950 if (state.g_map [0] != reg) {
951 char* pd = to;
952
953 // insert a designation sequence in this place
954 ret = __rw_iso2022jp_designate (state, pd, to_end, reg, enc);
955 if (ret != CODECVT_OK)
956 return ret;
957
958 state.gl_map = 1;
959 state.g_map [0] = reg;
960 state.shift_state = __rw_chset_map [reg].width;
961
962 // adjust destination pointer
963 to = pd;
964
965 if (to == to_end)
966 return ret;
967 }
968
969 // FIXME - check the validity of this test
970 if (to_end - to < int (width))
971 return CODECVT_PARTIAL;
972
973 *to++ = char (*from++ & 0x7f);
974 if (width > 1)
975 *to++ = char (*from++ & 0x7f);
976
977 return CODECVT_OK;
978}
979
980
981// ISO-2022-JP conversion from GB2312-1980
982// Convert one character.
983// Returns:
984// std::codecvt_base::ok in case the conversion succeeded
985// std::codecvt_base::partial for partial conversions
986// std::codecvt_base::error erroneous sequence
987static _STD::codecvt_base::result
988__rw_gb2312_to_iso2022 (__rw_iso2022_state_t& state,
989 const char*& from,
990 const char* from_end,
991 char*& to,
992 char* to_end,
993 int enc)
994{
995 // the registration
996 unsigned char reg = CHSET_GB2312_1980;
997 unsigned int width = __rw_chset_map [reg].width + 1;
998
999 _RWSTD_ASSERT(from_end-from >= int(width));
1000 _RWSTD_UNUSED(from_end);
1001
1002 _STD::codecvt_base::result ret;
1003
1004 // check the designation sequence
1005 if (state.g_map [0] != reg) {
1006 char* pd = to;
1007
1008 // insert a designation sequence in this place
1009 ret = __rw_iso2022jp_designate (state, pd, to_end, reg, enc);
1010 if (ret != CODECVT_OK)
1011 return ret;
1012
1013 state.gl_map = 1;
1014 state.g_map [0] = reg;
1015 state.shift_state = __rw_chset_map [reg].width;
1016
1017 // adjust destination pointer
1018 to = pd;
1019
1020 if (to == to_end)
1021 return ret;
1022 }
1023
1024 // FIXME - check the validity of this test
1025 if (to_end - to < int(width))
1026 return CODECVT_PARTIAL;
1027
1028 *to++ = char (*from++ & 0x7f);
1029 if (width > 1)
1030 *to++ = char (*from++ & 0x7f);
1031
1032 return CODECVT_OK;
1033}
1034
1035
1036// ISO-2022-JP conversion from ISO-8859-7
1037// Convert one character.
1038// Returns:
1039// std::codecvt_base::ok in case the conversion succeeded
1040// std::codecvt_base::partial for partial conversions
1041// std::codecvt_base::error erroneous sequence
1042static _STD::codecvt_base::result
1043__rw_iso88597_to_iso2022 (__rw_iso2022_state_t& state,
1044 const char*& from,
1045 const char* from_end,
1046 char*& to,
1047 char* to_end,
1048 int enc)
1049{
1050 // the registration
1051 unsigned char reg2 = CHSET_ISO_8859_7;
1052 unsigned int width2 = __rw_chset_map [reg2].width + 1;
1053
1054 _RWSTD_ASSERT(from_end-from >= int(width2));
1055 _RWSTD_UNUSED(from_end);
1056
1057 _STD::codecvt_base::result ret;
1058
1059 // always call designate for this one; designation will at least insert a
1060 // single shift function in the destination buffer
1061 ret = __rw_iso2022jp_designate (state, to, to_end, reg2, enc);
1062 if (ret != CODECVT_OK)
1063 return ret;
1064
1065 // adjust the G2 designation
1066 state.g_map [2] = reg2;
1067
1068 // FIXME - check the validity of this test
1069 if (to_end - to < int (width2))
1070 return CODECVT_PARTIAL;
1071
1072 *to++ = char (*from++ & 0x7f);
1073 if (width2 > 1)
1074 *to++ = char (*from++ & 0x7f);
1075
1076 // clear the single shift functions
1077 state.sshift2 = state.sshift3 = 0;
1078
1079 return CODECVT_OK;
1080}
1081
1082
1083// ISO-2022-JP conversion from ISO-8859-1
1084// Convert one character.
1085// Returns:
1086// std::codecvt_base::ok in case the conversion succeeded
1087// std::codecvt_base::partial for partial conversions
1088// std::codecvt_base::error erroneous sequence
1089static _STD::codecvt_base::result
1090__rw_iso88591_to_iso2022 (__rw_iso2022_state_t& state,
1091 const char*& from,
1092 const char* from_end,
1093 char*& to,
1094 char* to_end,
1095 int enc)
1096{
1097 // the registration
1098 unsigned char reg2 = CHSET_ISO_8859_1;
1099 unsigned int width2 = __rw_chset_map [reg2].width + 1;
1100
1101 _RWSTD_ASSERT(from_end-from >= int(width2));
1102 _RWSTD_UNUSED(from_end);
1103
1104 _STD::codecvt_base::result ret;
1105
1106 // always call designate for this one; designation will at least insert a
1107 // single shift function in the destination buffer
1108 ret = __rw_iso2022jp_designate (state, to, to_end, reg2, enc);
1109 if (ret != CODECVT_OK)
1110 return ret;
1111
1112 // adjust the G2 designation
1113 state.g_map [2] = reg2;
1114
1115 // FIXME - check the validity of this test
1116 if (to_end - to < int (width2))
1117 return CODECVT_PARTIAL;
1118
1119 *to++ = char (*from++ & 0x7f);
1120 if (width2 > 1)
1121 *to++ = char (*from++ & 0x7f);
1122
1123 // clear the single shift functions
1124 state.sshift2 = state.sshift3 = 0;
1125
1126 return CODECVT_OK;
1127}
1128
1129
1130// ISO-2022-JP conversion from packed EUC-JP
1131// Convert one character.
1132// Returns:
1133// std::codecvt_base::ok in case the conversion succeeded
1134// std::codecvt_base::partial for partial conversions
1135// std::codecvt_base::error erroneous sequence
1136static _STD::codecvt_base::result
1137__rw_eucjp_to_iso2022 (__rw_iso2022_state_t& state,
1138 const char*& from,
1139 const char* from_end,
1140 char*& to,
1141 char* to_end,
1142 int enc)
1143{
1144 int width = 0;
1145 unsigned char reg = 0;
1146
1147 _STD::codecvt_base::result ret;
1148
1149 // convert and store the encoding
1150 unsigned char c = *_RWSTD_REINTERPRET_CAST(const unsigned char*, from);
1151 switch (c) {
1152 case 0x8e:
1153 // JIS X 0201 Katakana
1155 from++;
1156 break;
1157
1158 case 0x8f:
1159 // JIS X 0212 1990
1161 from++;
1162 break;
1163
1164 default:
1165 if (c > 0x80) {
1166 // JIS X 0208-1978
1168 } else {
1169 // JIS X 0201 Roman/ANSI_X3.4-1968
1171 }
1172 break;
1173 }
1174
1175 // width in elements of the ISO-2022 output
1176 width = __rw_chset_map [reg].width + 1;
1177
1178 // check the designation sequence
1179 if (state.g_map [0] != reg) {
1180 char* pd = to;
1181
1182 // insert a designation sequence in this place
1183 ret = __rw_iso2022jp_designate (state, pd, to_end, reg, enc);
1184 if (ret != CODECVT_OK)
1185 return ret;
1186
1187 // adjust destination pointer
1188 to = pd;
1189
1190 state.gl_map = 1;
1191 state.g_map [0] = reg;
1192 state.shift_state = __rw_chset_map [reg].width;
1193
1194 if (to == to_end)
1195 return ret;
1196 }
1197
1198 // insert the character in the destination buffer
1199 if (width > from_end - from)
1200 return CODECVT_OK;
1201
1202 // FIXME - check the validity of this test
1203 if (to_end - to < __rw_chset_map[reg].width)
1204 return CODECVT_PARTIAL;
1205
1206 *to++ = char (*from++ & 0x7f);
1207 if (width > 1)
1208 *to++ = char (*from++ & 0x7f);
1209
1210 return CODECVT_OK;
1211}
1212
1213
1214// ISO-2022-JP conversion to GB2312-1980
1215// Converts one character.
1216// Returns:
1217// std::codecvt_base::ok in case the conversion succeeded
1218// std::codecvt_base::partial for partial conversions
1219// std::codecvt_base::error erroneous sequence
1220static inline
1221_STD::codecvt_base::result
1222__rw_iso2022_to_gb2312 (const char*& from,
1223 const char* from_end,
1224 char*& to,
1225 int /* reg */,
1226 int /* enc */)
1227{
1228 _STD::codecvt_base::result res = CODECVT_OK;
1229
1230 if (from_end - from < GB2312_CHAR_LEN)
1231 return res;
1232
1233 // store the destination bytes after setting the highest bit
1234 *to++ = char (*from++ | 0x80);
1235 *to++ = char (*from++ | 0x80);
1236
1237 return res;
1238}
1239
1240
1241// ISO-2022-JP conversion to KSC2312
1242// Converts one character.
1243// Returns:
1244// std::codecvt_base::ok in case the conversion succeeded
1245// std::codecvt_base::partial for partial conversions
1246// std::codecvt_base::error erroneous sequence
1247static inline
1248_STD::codecvt_base::result
1249__rw_iso2022_to_ksc5601 (const char*& from,
1250 const char* from_end,
1251 char*& to,
1252 int /* reg */,
1253 int /* enc */)
1254{
1255 _STD::codecvt_base::result res = CODECVT_OK;
1256
1257 if (from_end - from < KSC5601_CHAR_LEN)
1258 return res;
1259
1260 // store the destination bytes after setting the highest bit
1261 *to++ = char (*from++ | 0x80);
1262 *to++ = char (*from++ | 0x80);
1263
1264 return res;
1265}
1266
1267
1268// ISO-2022-JP conversion to ISO-8859-1
1269// Converts one character.
1270// Returns:
1271// std::codecvt_base::ok in case the conversion succeeded
1272// std::codecvt_base::partial for partial conversions
1273// std::codecvt_base::error erroneous sequence
1274static inline
1275_STD::codecvt_base::result
1276__rw_iso2022_to_iso88591 (const char*& from,
1277 const char* from_end,
1278 char*& to,
1279 int /* reg */,
1280 int /* enc */)
1281{
1282 _STD::codecvt_base::result res = CODECVT_OK;
1283
1284 if (from_end - from < ISO_8859_1_CHAR_LEN)
1285 return res;
1286
1287 // store the destination bytes after setting the highest bit
1288 *to++ = char (*from++ | 0x80);
1289
1290 return res;
1291}
1292
1293
1294// ISO-2022-JP conversion to ISO-8859-7
1295// Converts one character.
1296// Returns:
1297// std::codecvt_base::ok in case the conversion succeeded
1298// std::codecvt_base::partial for partial conversions
1299// std::codecvt_base::error erroneous sequence
1300static inline
1301_STD::codecvt_base::result
1302__rw_iso2022_to_iso88597 (const char*& from,
1303 const char* from_end,
1304 char*& to,
1305 int /* reg */,
1306 int /* enc */)
1307{
1308 _STD::codecvt_base::result res = CODECVT_OK;
1309
1310 if (from_end - from < ISO_8859_7_CHAR_LEN)
1311 return res;
1312
1313 // store the destination bytes after setting the highest bit
1314 *to++ = char (*from++ | 0x80);
1315
1316 return res;
1317}
1318
1319
1320// ISO-2022-JP conversion to packed EUC-JP
1321// Converts one character.
1322// Returns:
1323// std::codecvt_base::ok in case the conversion succeeded
1324// std::codecvt_base::partial for partial conversions
1325// std::codecvt_base::error erroneous sequence
1326static _STD::codecvt_base::result
1327__rw_iso2022_to_eucjp (const char*& from,
1328 const char* from_end,
1329 char*& to,
1330 int reg,
1331 int enc)
1332{
1333 // encoding registration number
1334 int width = __rw_chset_map [reg].width + 1;
1335
1336 // test the length of the input
1337 if (from_end - from < width)
1338 return CODECVT_OK;
1339
1340 _STD::codecvt_base::result res = CODECVT_OK;
1341
1342 // from either the ANSI_X3.4-1968 or JIS X 0201 Roman or JIS X 0201 Kana
1343 switch (reg) {
1346 // these character sets encode on one byte in EUC-JP
1347 *to++ = *from++;
1348
1349 break;
1350
1353 *to++ = char (*from++ | 0x80);
1354 *to++ = char (*from++ | 0x80);
1355
1356 break;
1357
1358 // The following belong to ISO-2022-JP-2
1360 if (enc == iso2022_jp) {
1362 break;
1363 }
1364
1365 // this character set encode on two bytes in EUC-JP
1366 *to++ = '\x8e';
1367 *to++ = char (*from++ | 0x80);
1368
1369 break;
1370
1372 if (enc == iso2022_jp) {
1374 break;
1375 }
1376
1377 *to++ = '\x8f';
1378 *to++ = char (*from++ | 0x80);
1379 *to++ = char (*from++ | 0x80);
1380
1381 break;
1382
1383 default:
1385 break;
1386 }
1387
1388 return res;
1389}
1390
1391
1392// Converts one character from the external representation to the
1393// intermediary encoding that is later used in retrieving the internal
1394// representation of that character
1395static _STD::codecvt_base::result
1396__rw_iso2022_to_interm (__rw_iso2022_state_t& state,
1397 const char*& from,
1398 const char* from_end,
1399 char*& to,
1400 unsigned char& reg,
1401 int enc)
1402{
1403 _STD::codecvt_base::result res = CODECVT_OK;
1404
1405 bool first = true;
1406 for (; *from == ESCAPE_CHAR; first = false) {
1407 // clear up the single shift functions set before
1408 if (first == false)
1409 state.sshift2 = state.sshift3 = 0;
1410
1411 const char* tmp = from;
1412 res = __rw_iso2022_escape (state, from, from_end, enc);
1413
1414 // the detected escape sequence has not been consumed because it
1415 // was incomplete or an error has been returned
1416 if (res != CODECVT_OK || tmp == from)
1417 return res;
1418 }
1419
1420 if (*from <= 0x20) {
1421 ;// FIXME - process control characters
1422 }
1423
1424 // if any single shift sequence has been selected, then clear up the
1425 // flag and adjust the registration code accordingly
1426 if (state.sshift2 == 1) {
1427 state.sshift2 = 0;
1428 // registration code switches to whatever code has been selected
1429 // in G2 (one of ISO-8859-1 and ISO-8859-7)
1430 reg = state.g_map [2];
1431 } else {
1432 // refresh the reg value
1433 reg = state.g_map [0];
1434 }
1435
1436 // ISO-2022-JP and ISO-2022-JP-2 use G0 exclusively
1437 switch (reg) {
1444 res = __rw_iso2022_to_eucjp (from, from_end, to, reg, enc);
1445 break;
1446
1447 case CHSET_GB2312_1980:
1448 res = __rw_iso2022_to_gb2312 (from, from_end, to, reg, enc);
1449 break;
1450
1452 res = __rw_iso2022_to_ksc5601 (from, from_end, to, reg, enc);
1453 break;
1454
1455 case CHSET_ISO_8859_1:
1456 res = __rw_iso2022_to_iso88591 (from, from_end, to, reg, enc);
1457 break;
1458
1459 case CHSET_ISO_8859_7:
1460 res = __rw_iso2022_to_iso88597 (from, from_end, to, reg, enc);
1461 break;
1462 }
1463
1464 // clear any single shift functions, if any
1465 state.sshift2 = state.sshift3 = 0;
1466
1467 return CODECVT_OK;
1468}
1469
1470
1471static _STD::codecvt_base::result
1472__rw_ucs4_to_eucjp (const wchar_t*& from,
1473 const wchar_t* from_end,
1474 char*& to,
1475 char* to_end,
1476 const _RW::__rw_codecvt_t* impl)
1477{
1478 typedef unsigned char UChar;
1479
1480 // "impl" as raw pointer to unsigned ints
1481 const char* impl_raw =
1482 _RWSTD_REINTERPRET_CAST(const char*,impl);
1483
1484 // utf8 temporary buffer
1485 char tmp [_UTF8_MB_CUR_MAX];
1486 char* ptmp = tmp;
1487
1488 // tbls will point to the first lookup table
1489 const unsigned int* tbls = impl->utf8_to_ext_tab ();;
1490 const unsigned int* tbl = tbls;
1491 _RWSTD_ASSERT(tbls);
1492
1493 if (from == from_end || to == to_end)
1494 return CODECVT_OK;
1495
1496 _RWSTD_SIZE_T ret = __rw_itoutf8 (*from, ptmp);
1497
1498 unsigned int wc = tbl [UChar (*ptmp)];
1499 while (wc & 0x80000000) {
1500 if (wc == _RWSTD_UINT_MAX)
1501 // FIXME - this is an error condition
1502 return CODECVT_ERROR;
1503
1504 if (ret-- == 0)
1505 // FIXME - this is an error condition
1506 return CODECVT_ERROR;
1507
1508 // get next table
1509 wc &= 0x7fffffff;
1510 tbl = tbls + 256 * wc;
1511 wc = tbl [UChar (*++ptmp)];
1512 }
1513
1514 // store the encoding sequence at destination
1515 _RWSTD_SIZE_T offset = wc + sizeof (_RW::__rw_codecvt_t);
1516 while (impl_raw [offset]) {
1517 if (to == to_end)
1518 return CODECVT_PARTIAL;
1519 else
1520 *to++ = impl_raw [offset++];
1521 }
1522
1523 from++;
1524 return CODECVT_OK;
1525}
1526
1527
1528static unsigned char /* registration code */
1529__rw_ucs4_to_interm ( const wchar_t*& from,
1530 char*& to)
1531{
1532 typedef unsigned char UChar;
1533
1534 static const struct {
1535 UChar db;
1536 UChar reg;
1537 } db_array [] = {
1544 };
1545
1546 // utf8 temporary buffer
1547 char tmp [_UTF8_MB_CUR_MAX];
1548
1549 for (size_t i = 0; i < sizeof db_array / sizeof *db_array; ++i) {
1550 char* ptmp = tmp;
1551
1552 // obtain the database mapping
1553 const void* pdb = __rw_get_encoding_database (db_array [i].db);
1554 if (pdb == 0)
1555 continue;
1556
1557 // cast the database map pointer to the correct type
1558 const _RW::__rw_codecvt_t* impl =
1559 _RWSTD_STATIC_CAST(const _RW::__rw_codecvt_t*, pdb);
1560
1561 // the "raw access" pointer used in finding the external repr.
1562 const char* impl_raw = _RWSTD_REINTERPRET_CAST(const char*,impl);
1563
1564 // tbls will point to the first lookup table
1565 const unsigned int* tbls = impl->utf8_to_ext_tab ();
1566 const unsigned int* tbl = tbls;
1567 _RWSTD_ASSERT(tbls);
1568
1569 _RWSTD_SIZE_T ret = __rw_itoutf8 (*from, ptmp);
1570
1571 bool success = true;
1572 unsigned int wc = tbl [UChar (*ptmp)];
1573 while (wc & 0x80000000) {
1574 if (wc == _RWSTD_UINT_MAX || ret-- == 0) {
1575 success = false;
1576 break;
1577 }
1578
1579 // get next table
1580 wc &= 0x7fffffff;
1581 tbl = tbls + 256 * wc;
1582 wc = tbl [UChar (*++ptmp)];
1583 }
1584
1585 // continue on the next lookup
1586 if (!success)
1587 continue;
1588
1589 // store the encoding sequence at destination
1590 _RWSTD_SIZE_T offset = wc + sizeof (_RW::__rw_codecvt_t);
1591 while (impl_raw [offset])
1592 *to++ = impl_raw [offset++];
1593
1594 // advance source pointer to next position
1595 from++;
1596
1597 // Find the registration code of the encoding and return it
1598 return db_array [i].reg;
1599 }
1600
1601 // invalid registration code
1602 return 0;
1603}
1604
1605
1606// does the conversion of one character to internal representation
1607static _STD::codecvt_base::result
1608__rw_iso2022_to_ucs4 (_RWSTD_MBSTATE_T& state,
1609 __rw_iso2022_state_t* iso_state,
1610 const char*& from,
1611 const char* from_end,
1612 wchar_t*& to,
1613 wchar_t* /* to_end */,
1614 int enc)
1615{
1616 _STD::codecvt_base::result res;
1617
1618 // the registration code of the character set
1619 unsigned char reg = iso_state->g_map [0];
1620 int width = iso_state->shift_state + 1;
1621
1622 // test input width
1623 if (from_end - from < width) {
1624 // test and deallocate state
1625 if (iso_state->g_map [0] == CHSET_ANSI_X_3_4_1968)
1626 __rw_deallocate_state (*iso_state, state, false);
1627
1628 return CODECVT_OK;
1629 }
1630
1631 // temporary buffer to accomodate the intermediary encoding
1632 char tmp_buffer [8];
1633 char* tmp_to = tmp_buffer;
1634 char* tmp_to_end;
1635
1636 const char* from_next = from;
1637
1638 // convert one character at a time and note that the registration
1639 // code is actually modified by the following call in the case
1640 // of single shift functions
1641 res = __rw_iso2022_to_interm (*iso_state, from_next, from_end,
1642 tmp_to, reg, enc);
1643 if (res != CODECVT_OK ||
1644 (from_next == from && tmp_to == tmp_buffer)) {
1645
1646 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
1647
1648 return res;
1649 }
1650
1651 // the input sequence started with an escape sequence
1652 if (tmp_to == tmp_buffer) {
1653 from = from_next;
1654 return res;
1655 }
1656
1657 tmp_to_end = tmp_to;
1658 tmp_to = tmp_buffer;
1659
1660 // get the proper database for decoding input
1661 const void* pdb = __rw_get_encoding_database (__rw_chset_map [reg].index);
1662 if (pdb == 0) {
1663 __rw_deallocate_state (*iso_state, state, false);
1664 return CODECVT_ERROR;
1665 }
1666 const _RW::__rw_codecvt_t* pimpl =
1667 _RWSTD_STATIC_CAST(const _RW::__rw_codecvt_t*, pdb);
1668
1669 // retrieve the lookup table start
1670 const unsigned int* tbls = pimpl->n_to_w_tab ();
1671 const unsigned int* tbl = tbls;
1672 _RWSTD_ASSERT(tbls);
1673
1674 // wider character representations will be looked upon in the
1675 // database tables
1676 unsigned int wc = tbl [*(unsigned char*)tmp_to];
1677 while (wc & 0x80000000) {
1678 if (wc == _RWSTD_UINT_MAX) {
1679 __rw_deallocate_state (*iso_state, state, false);
1680 return CODECVT_ERROR;
1681 }
1682
1683 // wc is table index
1684 tbl = tbls + 256*(wc & 0x7fffffff);
1685 tmp_to++;
1686
1687 // we have reached end of EUC-JP temporary buffer and we found
1688 // here an incomplete sequence; the incomplete sequence here
1689 // is an error
1690 if (tmp_to == tmp_to_end) {
1691 __rw_deallocate_state (*iso_state, state, false);
1692 return CODECVT_ERROR;
1693 }
1694
1695 wc = tbl [*(unsigned char*)tmp_to];
1696 }
1697
1698 // update source pointer and store the value at destination
1699 from = from_next;
1700 *to++ = pimpl->get_ucs4_at_offset(wc);
1701
1702 return CODECVT_OK;
1703}
1704
1705
1707// Conversion from ISO-2022-JP to UCS-4
1708_STD::codecvt_base::result
1709__rw_iso2022jp_do_in (_RWSTD_MBSTATE_T& state,
1710 const char*& from,
1711 const char* from_end,
1712 wchar_t*& to,
1713 wchar_t* to_end)
1714{
1715 // the iso2022 state
1716 __rw_iso2022_state_t* iso_state =
1717 __rw_get_iso2022_state (state, iso2022_jp);
1718
1719 if (iso_state == 0)
1720 return CODECVT_ERROR;
1721
1722 // Loop until the source buffer is consumed, an error occurs, or
1723 // the destination buffer reaches capacity
1724 const char* from_next = from;
1725 wchar_t* to_next = to;
1726
1727 while (from_end - from && to_end - to) {
1728 // operation result
1729 _STD::codecvt_base::result res;
1730 res = __rw_iso2022_to_ucs4 (state, iso_state, from_next,
1731 from_end, to_next, to_end, iso2022_jp);
1732
1733 if (res != CODECVT_OK)
1734 return res;
1735
1736 // an ok result with no conversion
1737 if (res == CODECVT_OK &&
1738 from_next == from && to_next == to)
1739 return res;
1740
1741 from = from_next;
1742 to = to_next;
1743 }
1744
1745 // deallocate state if the conversion has gone back to initial state
1746 __rw_deallocate_state (*iso_state, state, true);
1747
1748 return CODECVT_OK;
1749}
1750
1751
1752// Conversion from UCS-4 to ISO-2022-JP
1753_STD::codecvt_base::result
1754__rw_iso2022jp_do_out (_RWSTD_MBSTATE_T& state,
1755 const wchar_t*& from,
1756 const wchar_t* from_end,
1757 char*& to,
1758 char* to_end)
1759{
1760 // the iso2022 state
1761 __rw_iso2022_state_t* iso_state =
1762 __rw_get_iso2022_state (state, iso2022_jp);
1763
1764 if (iso_state == 0)
1765 return CODECVT_ERROR;
1766
1767 // destination buffer to accomodate the EUC-JP encoding
1768 char euc_buffer [8];
1769
1770 // use the EUC-JP database for a full lookup
1771 const void* pdb = __rw_get_encoding_database (DBIDX_EUC_JP);
1772 if (pdb == 0){
1773 __rw_deallocate_state (*iso_state, state, false);
1774 return CODECVT_ERROR;
1775 }
1776
1777 const _RW::__rw_codecvt_t* pimpl =
1778 _RWSTD_STATIC_CAST(const _RW::__rw_codecvt_t*, pdb);
1779 _RWSTD_ASSERT(pimpl);
1780
1781 // Loop until the source buffer is consumed, an error occurs, or
1782 // the destination buffer reaches capacity
1783 while (from_end - from && to_end - to) {
1784 _STD::codecvt_base::result res;
1785
1786 // convert the UCS-4 value to EUC-JP
1787 const wchar_t* ps = from;
1788 const wchar_t* pse = from_end;
1789
1790 char* euc = euc_buffer;
1791 char* euce = euc_buffer + 8;
1792
1793 res = __rw_ucs4_to_eucjp (ps, pse, euc, euce, pimpl);
1794 if (res != CODECVT_OK ||
1795 (ps == from && euc == euc_buffer)) {
1796
1797 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
1798
1799 return res;
1800 }
1801
1802 char* pd = to;
1803
1804 // convert the EUC-JP value to ISO-2022
1805 euce = euc;
1806 const char* ceuc = euc_buffer;
1807 res = __rw_eucjp_to_iso2022 (*iso_state, ceuc,
1808 euce, pd, to_end, iso2022_jp);
1809 if (res != CODECVT_OK ||
1810 (ceuc == euc_buffer && pd == to)) {
1811
1812 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
1813
1814 return res;
1815 }
1816
1817 //adjust source pointer
1818 from = ps;
1819 to = pd;
1820 }
1821
1822 // deallocate state if the conversion has gone back to
1823 // initial state
1824 __rw_deallocate_state (*iso_state, state, true);
1825
1826 return CODECVT_OK;
1827}
1828
1829
1830_STD::codecvt_base::result
1831__rw_iso2022jp_do_unshift (_RWSTD_MBSTATE_T& state,
1832 char*& to, char* to_end)
1833{
1834 _STD::codecvt_base::result res =
1836
1837 // the iso2022 state
1838 __rw_iso2022_state_t* iso_state =
1839 __rw_get_iso2022_state (state, iso2022_jp);
1840
1841 if (iso_state == 0)
1842 return res;
1843
1844 if (iso_state->g_map [iso_state->gl_map - 1] != CHSET_ANSI_X_3_4_1968)
1845 res = __rw_iso2022jp_designate (*iso_state, to, to_end,
1846 CHSET_ANSI_X_3_4_1968, iso2022_jp);
1847 else
1848 res = CODECVT_OK;
1849
1850 // deallocate a state if the conversion has gone back to
1851 // initial shift state and operation succeeded, OR, if
1852 // the result is error
1853 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
1854
1855 return res;
1856}
1857
1858
1859_RWSTD_SIZE_T
1860__rw_iso2022jp_do_length (_RWSTD_MBSTATE_T& state,
1861 const char* from, const char* from_end,
1862 _RWSTD_SIZE_T max)
1863{
1864 _RWSTD_ASSERT(from <= from_end);
1865
1866 // the iso2022 state
1867 __rw_iso2022_state_t* iso_state =
1868 __rw_get_iso2022_state (state, iso2022_jp);
1869
1870 if (iso_state == 0)
1871 return CODECVT_ERROR;
1872
1873 int ret = 0;
1874 _STD::codecvt_base::result res = CODECVT_OK;
1875 while (max && from_end - from) {
1876 while (*from == ESCAPE_CHAR)
1877
1878
1879 if (*from == ESCAPE_CHAR) {
1880 const char* tmp = from;
1881 res = __rw_iso2022_escape (*iso_state, from, from_end, iso2022_jp);
1882
1883 if (res != CODECVT_OK || from == tmp)
1884 break;
1885
1886 continue;
1887 }
1888
1889 if (from_end - from < int(iso_state->shift_state) + 1)
1890 break;
1891
1892 ret++, max--;
1893 from += iso_state->shift_state + 1;
1894 }
1895
1896 // deallocate a state if the conversion has gone back to initial shift
1897 // state
1898 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
1899
1900 return ret;
1901}
1902
1903
1904_RWSTD_SIZE_T
1905__rw_iso2022jp_do_max_length ()
1906{
1907 return 2;
1908}
1909
1910
1911int __rw_iso2022jp_do_encoding ()
1912{
1913 return -1;
1914}
1915
1916bool __rw_iso2022jp_do_always_noconv ()
1917{
1918 return false;
1919}
1920
1921
1923// Conversion from ISO-2022-JP to UCS-4
1924_STD::codecvt_base::result
1925__rw_iso2022jp2_do_in (_RWSTD_MBSTATE_T& state,
1926 const char*& from,
1927 const char* from_end,
1928 wchar_t*& to,
1929 wchar_t* to_end)
1930{
1931 // the iso2022 state
1932 __rw_iso2022_state_t* iso_state =
1933 __rw_get_iso2022_state (state, iso2022_jp);
1934
1935 if (iso_state == 0)
1936 return CODECVT_ERROR;
1937
1938 // Loop until the source buffer is consumed, an error occurs, or
1939 // the destination buffer reaches capacity
1940 while (from_end - from && to_end - to) {
1941
1942 const char* from_next = from;
1943 wchar_t* to_next = to;
1944
1945 // operation result
1946 _STD::codecvt_base::result res;
1947 res = __rw_iso2022_to_ucs4 (state, iso_state, from_next,
1948 from_end, to_next, to_end, iso2022_jp2);
1949
1950 if (res != CODECVT_OK)
1951 return res;
1952
1953 // an ok result with no conversion
1954 if (res == CODECVT_OK &&
1955 from_next == from && to_next == to)
1956 return res;
1957
1958 from = from_next;
1959 to = to_next;
1960 }
1961
1962 // deallocate state if the conversion has gone back to initial state
1963 __rw_deallocate_state (*iso_state, state, true);
1964
1965 return CODECVT_OK;
1966}
1967
1968
1969// Conversion from UCS-4 to ISO-2022-JP-2
1970_STD::codecvt_base::result
1971__rw_iso2022jp2_do_out (_RWSTD_MBSTATE_T& state,
1972 const wchar_t*& from,
1973 const wchar_t* from_end,
1974 char*& to,
1975 char* to_end)
1976{
1977 // the iso2022 state
1978 __rw_iso2022_state_t* iso_state =
1979 __rw_get_iso2022_state (state, iso2022_jp);
1980
1981 if (iso_state == 0)
1982 return CODECVT_ERROR;
1983
1984 // destination buffer to accomodate the intermediate encoding
1985 char tmp [8];
1986
1987 // Loop until the source buffer is consumed, an error occurs, or
1988 // the destination buffer reaches capacity
1989 while (from_end - from && to_end - to) {
1990 _STD::codecvt_base::result res;
1991
1992 // convert the UCS-4 value to intermediary encoding
1993 const wchar_t* ps = from;
1994
1995 char* tmps = tmp;
1996 char* tmpe = tmp + 8;
1997
1998 unsigned char reg =
1999 __rw_ucs4_to_interm (ps, tmps);
2000 if (reg == 0) {
2001 // deallocate state
2002 __rw_deallocate_state (*iso_state, state, false);
2003
2004 // error condition - none of the databases contained a mapping
2005 // of the character
2006 return CODECVT_ERROR;
2007 }
2008
2009 char* pd = to;
2010
2011 // convert the intermediary value to ISO-2022
2012 tmpe = tmps;
2013 const char* ctmps = tmp;
2014
2015 // the registration of the encoding dictates how the conversion is
2016 // to be performed further
2017 switch (reg) {
2019 res = __rw_ascii_to_iso2022 (*iso_state, ctmps, tmpe,
2020 pd, to_end, iso2022_jp2);
2021 break;
2023 res = __rw_eucjp_to_iso2022 (*iso_state, ctmps, tmpe,
2024 pd, to_end, iso2022_jp2);
2025 break;
2027 res = __rw_ksc5601_to_iso2022 (*iso_state, ctmps, tmpe,
2028 pd, to_end, iso2022_jp2);
2029 break;
2030 case CHSET_GB2312_1980:
2031 res = __rw_gb2312_to_iso2022 (*iso_state, ctmps, tmpe,
2032 pd, to_end, iso2022_jp2);
2033 break;
2034 case CHSET_ISO_8859_7:
2035 res = __rw_iso88597_to_iso2022 (*iso_state, ctmps, tmpe,
2036 pd, to_end, iso2022_jp2);
2037 break;
2038 case CHSET_ISO_8859_1:
2039 res = __rw_iso88591_to_iso2022 (*iso_state, ctmps, tmpe,
2040 pd, to_end, iso2022_jp2);
2041 break;
2042 default:
2043 return CODECVT_ERROR;
2044 }
2045
2046 if (res != CODECVT_OK || (ctmps==tmp && pd==to)) {
2047
2048 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
2049
2050 return res;
2051 }
2052
2053 //adjust source pointer
2054 from = ps;
2055 to = pd;
2056
2057 // after a successful insertion the single shift functions
2058 // must be cleared
2059 iso_state->sshift2 = iso_state->sshift3 = 0;
2060
2061 }
2062
2063 // deallocate state if the conversion has gone back to
2064 // initial state
2065 __rw_deallocate_state (*iso_state, state, true);
2066
2067 return CODECVT_OK;
2068}
2069
2070
2071_STD::codecvt_base::result
2072__rw_iso2022jp2_do_unshift (_RWSTD_MBSTATE_T& state,
2073 char*& to, char* to_end)
2074{
2075 return __rw_iso2022jp_do_unshift (state, to, to_end);
2076}
2077
2078
2079_RWSTD_SIZE_T
2080__rw_iso2022jp2_do_length (_RWSTD_MBSTATE_T& state,
2081 const char* from, const char* from_end,
2082 _RWSTD_SIZE_T max)
2083{
2084 _RWSTD_ASSERT(from <= from_end);
2085
2086 // the iso2022 state
2087 __rw_iso2022_state_t* iso_state =
2088 __rw_get_iso2022_state (state, iso2022_jp);
2089
2090 if (iso_state == 0)
2091 return CODECVT_ERROR;
2092
2093 int ret = 0;
2094 _STD::codecvt_base::result res = CODECVT_OK;
2095
2096 while (max && from_end - from) {
2097
2098 bool first = true;
2099 for (; *from == ESCAPE_CHAR; first = false) {
2100 // clear up the single shift functions set before
2101 if (first == false)
2102 iso_state->sshift2 = iso_state->sshift3 = 0;
2103
2104 const char* tmp = from;
2105 res = __rw_iso2022_escape (*iso_state, from, from_end,
2106 iso2022_jp2);
2107
2108 // the detected escape sequence has not been consumed because it
2109 // was incomplete
2110 if (res != CODECVT_OK || tmp == from)
2111 return ret;
2112 }
2113
2114 if (*from <= 0x20) {
2115 ;// FIXME - process control characters
2116 }
2117
2118 // the registration for all character sets other than the ISO's
2119 // is stored in the first register, G0.
2120 unsigned char reg = iso_state->g_map [0];
2121 unsigned int width;
2122 if (iso_state->sshift2 == 1) {
2123 width = 1;
2124 } else {
2125 width = __rw_chset_map [reg].width + 1;
2126 }
2127
2128 if (from_end - from < int (width))
2129 break;
2130
2131 ret++, max--;
2132 from += width;
2133
2134 // clean up the single shift function
2135 iso_state->sshift2 = iso_state->sshift3 = 0;
2136
2137 }
2138
2139 // deallocate a state if the conversion has gone back to initial shift
2140 // state
2141 __rw_deallocate_state (*iso_state, state, CODECVT_ERROR != res);
2142
2143 return ret;
2144}
2145
2146
2147_RWSTD_SIZE_T
2148__rw_iso2022jp2_do_max_length ()
2149{
2150 return 2;
2151}
2152
2153
2154int __rw_iso2022jp2_do_encoding ()
2155{
2156 return -1;
2157}
2158
2159
2160bool __rw_iso2022jp2_do_always_noconv ()
2161{
2162 return false;
2163}
2164
2165} // namespace __rw
#define i
Definition 17.names.cpp:126
#define g2
Definition 17.names.cpp:257
#define t
Definition 17.names.cpp:136
#define res
Definition 17.names.cpp:531
#define index
Definition 17.names.cpp:482
#define offset
Definition 17.names.cpp:508
#define c
Definition 17.names.cpp:111
#define tmp
Definition 17.names.cpp:553
#define len
Definition 17.names.cpp:488
#define n
Definition 17.names.cpp:130
volatile double * pd
#define _RWSTD_REINTERPRET_CAST(T, x)
Definition _defs.h:535
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_MT_CLASS_GUARD(type)
Definition _defs.h:697
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_MBSTATE_T
Definition _mbstate.h:199
const char * name
Definition codecvt1.cpp:72
#define ISO_2022_SET_SB94_G0
Definition iso2022.cpp:95
#define ISO_2022_JP_SET_JIS201_ROMAN
Definition iso2022.cpp:68
#define DBIDX_ISO_8859_7
Definition iso2022.cpp:61
#define ISO_2022_STATE_INDEX_T
#define CHSET_ANSI_X_3_4_1968
Definition iso2022.cpp:43
#define CHSET_GB2312_1980
Definition iso2022.cpp:49
#define ISO_2022_JP_SET_JIS201_KANA
Definition iso2022.cpp:69
#define ISO_2022_JP_SET_ISO_8859_1
Definition iso2022.cpp:75
#define EMPTY
#define ISO_2022_JP_SET_SS2
Definition iso2022.cpp:77
#define DBIDX_ANSI_X_3_4_1968
Definition iso2022.cpp:54
#define DBIDX_EUC_KR
Definition iso2022.cpp:64
#define CHSET_ISO_8859_7
Definition iso2022.cpp:52
#define ISO_2022_ARRAY_SIZE
#define CODECVT_PARTIAL
Definition iso2022.cpp:126
#define ISO_2022_JP_SET_JIS208_78
Definition iso2022.cpp:70
#define CHSET_JIS_X_0201_KANA
Definition iso2022.cpp:44
#define DBIDX_GB2312
Definition iso2022.cpp:65
#define CODECVT_ERROR
Definition iso2022.cpp:124
#define ISO_8859_7_CHAR_LEN
Definition iso2022.cpp:92
#define ISO_8859_1_CHAR_LEN
Definition iso2022.cpp:91
#define CHSET_JIS_X_0212_1990
Definition iso2022.cpp:48
#define ISO_2022_SET_SB96_G2
Definition iso2022.cpp:101
#define CHSET_JIS_X_0201_ROMAN
Definition iso2022.cpp:45
#define GB2312_CHAR_LEN
Definition iso2022.cpp:88
#define CHSET_JIS_X_0208_1983
Definition iso2022.cpp:47
#define CHSET_JIS_X_0208_1978
Definition iso2022.cpp:46
#define CHSET_KSC_5601_1987
Definition iso2022.cpp:50
#define DBIDX_ISO_8859_1
Definition iso2022.cpp:55
#define ISO_2022_JP_SET_GB2312_80
Definition iso2022.cpp:72
#define ESCAPE_CHAR
Definition iso2022.cpp:117
#define ISO_2022_JP_SET_ASCII
Definition iso2022.cpp:67
#define KSC5601_CHAR_LEN
Definition iso2022.cpp:89
#define DBIDX_EUC_JP
Definition iso2022.cpp:63
#define ISO_2022_JP_SET_KSC5601_87
Definition iso2022.cpp:73
#define ISO_2022_JP_SET_JIS212_90
Definition iso2022.cpp:74
#define _UTF8_MB_CUR_MAX
Definition iso2022.cpp:120
#define ISO_2022_SET_SS2
Definition iso2022.cpp:115
#define ISO_2022_JP_SET_ISO_8859_7
Definition iso2022.cpp:76
#define ISO_2022_JP_SET_JIS208_83
Definition iso2022.cpp:71
#define CODECVT_OK
Definition iso2022.cpp:125
#define CHSET_ISO_8859_1
Definition iso2022.cpp:51
#define ISO_2022_SET_MB94_G0
Definition iso2022.cpp:106
#define ISO_2022_SET_MB
Definition iso2022.cpp:104
unsigned char UChar
Definition collate.cpp:122
#define max(a, b)