/* * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings. * * Written by Hye-Shik Chang <perky@FreeBSD.org> */ #define USING_IMPORTED_MAPS#define USING_BINARY_PAIR_SEARCH#define EXTERN_JISX0213_PAIR#define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE#define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE #include "cjkcodecs.h"#include "alg_jisx0201.h"#include "emu_jisx0213_2000.h"#include "mappings_jisx0213_pair.h" /* STATE state->c[0-3] 00000000 ||^^^^^| |+-----+---- G0-3 Character Set +----------- Is G0-3 double byte? state->c[4] 00000000 || |+---- Locked-Shift? +----- ESC Throughout*/ #define ESC 0x1B#define SO 0x0E#define SI 0x0F#define LF 0x0A #define MAX_ESCSEQLEN 16 #define CHARSET_ISO8859_1 'A'#define CHARSET_ASCII 'B'#define CHARSET_ISO8859_7 'F'#define CHARSET_JISX0201_K 'I'#define CHARSET_JISX0201_R 'J' #define CHARSET_GB2312 ('A'|CHARSET_DBCS)#define CHARSET_JISX0208 ('B'|CHARSET_DBCS)#define CHARSET_KSX1001 ('C'|CHARSET_DBCS)#define CHARSET_JISX0212 ('D'|CHARSET_DBCS)#define CHARSET_GB2312_8565 ('E'|CHARSET_DBCS)#define CHARSET_CNS11643_1 ('G'|CHARSET_DBCS)#define CHARSET_CNS11643_2 ('H'|CHARSET_DBCS)#define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS)#define CHARSET_JISX0213_2 ('P'|CHARSET_DBCS)#define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS)#define CHARSET_JISX0208_O ('@'|CHARSET_DBCS) #define CHARSET_DBCS 0x80#define ESCMARK(mark) ((mark) & 0x7f) #define IS_ESCEND(c) (((c) >= 'A' && (c) <= 'Z') || (c) == '@')#define IS_ISO2022ESC(c2) \ ((c2) == '(' || (c2) == ')' || (c2) == '$' || \ (c2) == '.' || (c2) == '&') /* this is not a complete list of ISO-2022 escape sequence headers. * but, it's enough to implement CJK instances of iso-2022. */ #define MAP_UNMAPPABLE 0xFFFF#define MAP_MULTIPLE_AVAIL 0xFFFE /* for JIS X 0213 */ #define F_SHIFTED 0x01#define F_ESCTHROUGHOUT 0x02 #define STATE_SETG(dn, v) ((state)->c[dn]) = (v);#define STATE_GETG(dn) ((state)->c[dn]) #define STATE_G0 STATE_GETG(0)#define STATE_G1 STATE_GETG(1)#define STATE_G2 STATE_GETG(2)#define STATE_G3 STATE_GETG(3)#define STATE_SETG0(v) STATE_SETG(0, v)#define STATE_SETG1(v) STATE_SETG(1, v)#define STATE_SETG2(v) STATE_SETG(2, v)#define STATE_SETG3(v) STATE_SETG(3, v) #define STATE_SETFLAG(f) ((state)->c[4]) |= (f);#define STATE_GETFLAG(f) ((state)->c[4] & (f))#define STATE_CLEARFLAG(f) ((state)->c[4]) &= ~(f);#define STATE_CLEARFLAGS() ((state)->c[4]) = 0; #define ISO2022_CONFIG ((const struct iso2022_config *)config)#define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag))#define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations) /* iso2022_config.flags */#define NO_SHIFT 0x01#define USE_G2 0x02#define USE_JISX0208_EXT 0x04 /*-*- internal data structures -*-*/ typedef int (*iso2022_init_func)(void);typedef ucs4_t (*iso2022_decode_func)(const unsigned char *data);typedef DBCHAR (*iso2022_encode_func)(const ucs4_t *data, Py_ssize_t *length); struct iso2022_designation { unsigned char mark; unsigned char plane; unsigned char width; iso2022_init_func initializer; iso2022_decode_func decoder; iso2022_encode_func encoder;}; struct iso2022_config { int flags; const struct iso2022_designation *designations; /* non-ascii desigs */}; /*-*- iso-2022 codec implementation -*-*/ CODEC_INIT(iso2022){ const struct iso2022_designation *desig = CONFIG_DESIGNATIONS; for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) if (desig->initializer != NULL && desig->initializer() != 0) return -1; return 0;} ENCODER_INIT(iso2022){ STATE_CLEARFLAGS() STATE_SETG0(CHARSET_ASCII) STATE_SETG1(CHARSET_ASCII) return 0;} ENCODER_RESET(iso2022){ if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) NEXT_OUT(1) STATE_CLEARFLAG(F_SHIFTED) } if (STATE_G0 != CHARSET_ASCII) { WRITE3(ESC, '(', 'B') NEXT_OUT(3) STATE_SETG0(CHARSET_ASCII) } return 0;} ENCODER(iso2022){ while (inleft > 0) { const struct iso2022_designation *dsg; DBCHAR encoded; ucs4_t c = **inbuf; Py_ssize_t insize; if (c < 0x80) { if (STATE_G0 != CHARSET_ASCII) { WRITE3(ESC, '(', 'B') STATE_SETG0(CHARSET_ASCII) NEXT_OUT(3) } if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) STATE_CLEARFLAG(F_SHIFTED) NEXT_OUT(1) } WRITE1((unsigned char)c) NEXT(1, 1) continue; } DECODE_SURROGATE(c) insize = GET_INSIZE(c); encoded = MAP_UNMAPPABLE; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { Py_ssize_t length = 1; encoded = dsg->encoder(&c, &length); if (encoded == MAP_MULTIPLE_AVAIL) { /* this implementation won't work for pair * of non-bmp characters. */ if (inleft < 2) { if (!(flags & MBENC_FLUSH)) return MBERR_TOOFEW; length = -1; } else length = 2;#if Py_UNICODE_SIZE == 2 if (length == 2) { ucs4_t u4in[2]; u4in[0] = (ucs4_t)IN1; u4in[1] = (ucs4_t)IN2; encoded = dsg->encoder(u4in, &length); } else encoded = dsg->encoder(&c, &length);#else encoded = dsg->encoder(*inbuf, &length);#endif if (encoded != MAP_UNMAPPABLE) { insize = length; break; } } else if (encoded != MAP_UNMAPPABLE) break; } if (!dsg->mark) return 1; assert(dsg->width == 1 || dsg->width == 2); switch (dsg->plane) { case 0: /* G0 */ if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) STATE_CLEARFLAG(F_SHIFTED) NEXT_OUT(1) } if (STATE_G0 != dsg->mark) { if (dsg->width == 1) { WRITE3(ESC, '(', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(3) } else if (dsg->mark == CHARSET_JISX0208) { WRITE3(ESC, '$', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(3) } else { WRITE4(ESC, '$', '(', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(4) } } break; case 1: /* G1 */ if (STATE_G1 != dsg->mark) { if (dsg->width == 1) { WRITE3(ESC, ')', ESCMARK(dsg->mark)) STATE_SETG1(dsg->mark) NEXT_OUT(3) } else { WRITE4(ESC, '$', ')', ESCMARK(dsg->mark)) STATE_SETG1(dsg->mark) NEXT_OUT(4) } } if (!STATE_GETFLAG(F_SHIFTED)) { WRITE1(SO) STATE_SETFLAG(F_SHIFTED) NEXT_OUT(1) } break; default: /* G2 and G3 is not supported: no encoding in * CJKCodecs are using them yet */ return MBERR_INTERNAL; } if (dsg->width == 1) { WRITE1((unsigned char)encoded) NEXT_OUT(1) } else { WRITE2(encoded >> 8, encoded & 0xff) NEXT_OUT(2) } NEXT_IN(insize) } return 0;} DECODER_INIT(iso2022){ STATE_CLEARFLAGS() STATE_SETG0(CHARSET_ASCII) STATE_SETG1(CHARSET_ASCII) STATE_SETG2(CHARSET_ASCII) return 0;} DECODER_RESET(iso2022){ STATE_SETG0(CHARSET_ASCII) STATE_CLEARFLAG(F_SHIFTED) return 0;} static Py_ssize_tiso2022processesc(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft){ unsigned char charset, designation; Py_ssize_t i, esclen; for (i = 1;i < MAX_ESCSEQLEN;i++) { if (i >= *inleft) return MBERR_TOOFEW; if (IS_ESCEND((*inbuf)[i])) { esclen = i + 1; break; } else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft && (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@') i += 2; } if (i >= MAX_ESCSEQLEN) return 1; /* unterminated escape sequence */ switch (esclen) { case 3: if (IN2 == '$') { charset = IN3 | CHARSET_DBCS; designation = 0; } else { charset = IN3; if (IN2 == '(') designation = 0; else if (IN2 == ')') designation = 1; else if (CONFIG_ISSET(USE_G2) && IN2 == '.') designation = 2; else return 3; } break; case 4: if (IN2 != '$') return 4; charset = IN4 | CHARSET_DBCS; if (IN3 == '(') designation = 0; else if (IN3 == ')') designation = 1; else return 4; break; case 6: /* designation with prefix */ if (CONFIG_ISSET(USE_JISX0208_EXT) && (*inbuf)[3] == ESC && (*inbuf)[4] == '$' && (*inbuf)[5] == 'B') { charset = 'B' | CHARSET_DBCS; designation = 0; } else return 6; break; default: return esclen; } /* raise error when the charset is not designated for this encoding */ if (charset != CHARSET_ASCII) { const struct iso2022_designation *dsg; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) if (dsg->mark == charset) break; if (!dsg->mark) return esclen; } STATE_SETG(designation, charset) *inleft -= esclen; (*inbuf) += esclen; return 0;} #define ISO8859_7_DECODE(c, assi) \ if ((c) < 0xa0) (assi) = (c); \ else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) \ (assi) = (c); \ else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 || \ (0xbffffd77L & (1L << ((c)-0xb4))))) \ (assi) = 0x02d0 + (c); \ else if ((c) == 0xa1) (assi) = 0x2018; \ else if ((c) == 0xa2) (assi) = 0x2019; \ else if ((c) == 0xaf) (assi) = 0x2015; static Py_ssize_tiso2022processg2(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft, Py_UNICODE **outbuf, Py_ssize_t *outleft){ /* not written to use encoder, decoder functions because only few * encodings use G2 designations in CJKCodecs */ if (STATE_G2 == CHARSET_ISO8859_1) { if (IN3 < 0x80) OUT1(IN3 + 0x80) else return 3; } else if (STATE_G2 == CHARSET_ISO8859_7) { ISO8859_7_DECODE(IN3 ^ 0x80, **outbuf) else return 3; } else if (STATE_G2 == CHARSET_ASCII) { if (IN3 & 0x80) return 3; else **outbuf = IN3; } else return MBERR_INTERNAL; (*inbuf) += 3; *inleft -= 3; (*outbuf) += 1; *outleft -= 1; return 0;} DECODER(iso2022){ const struct iso2022_designation *dsgcache = NULL; while (inleft > 0) { unsigned char c = IN1; Py_ssize_t err; if (STATE_GETFLAG(F_ESCTHROUGHOUT)) { /* ESC throughout mode: * for non-iso2022 escape sequences */ WRITE1(c) /* assume as ISO-8859-1 */ NEXT(1, 1) if (IS_ESCEND(c)) { STATE_CLEARFLAG(F_ESCTHROUGHOUT) } continue; } switch (c) { case ESC: REQUIRE_INBUF(2) if (IS_ISO2022ESC(IN2)) { err = iso2022processesc(config, state, inbuf, &inleft); if (err != 0) return err; } else if (CONFIG_ISSET(USE_G2) && IN2 == 'N') {/* SS2 */ REQUIRE_INBUF(3) err = iso2022processg2(config, state, inbuf, &inleft, outbuf, &outleft); if (err != 0) return err; } else { WRITE1(ESC) STATE_SETFLAG(F_ESCTHROUGHOUT) NEXT(1, 1) } break; case SI: if (CONFIG_ISSET(NO_SHIFT)) goto bypass; STATE_CLEARFLAG(F_SHIFTED) NEXT_IN(1) break; case SO: if (CONFIG_ISSET(NO_SHIFT)) goto bypass; STATE_SETFLAG(F_SHIFTED) NEXT_IN(1) break; case LF: STATE_CLEARFLAG(F_SHIFTED) WRITE1(LF) NEXT(1, 1) break; default: if (c < 0x20) /* C0 */ goto bypass; else if (c >= 0x80) return 1; else { const struct iso2022_designation *dsg; unsigned char charset; ucs4_t decoded; if (STATE_GETFLAG(F_SHIFTED)) charset = STATE_G1; else charset = STATE_G0; if (charset == CHARSET_ASCII) {bypass: WRITE1(c) NEXT(1, 1) break; } if (dsgcache != NULL &&Lines 1–500 of 1131. Load more
/* * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings. * * Written by Hye-Shik Chang <perky@FreeBSD.org> */ #define USING_IMPORTED_MAPS #define USING_BINARY_PAIR_SEARCH #define EXTERN_JISX0213_PAIR #define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE #define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE #include "cjkcodecs.h" #include "alg_jisx0201.h" #include "emu_jisx0213_2000.h" #include "mappings_jisx0213_pair.h" /* STATE state->c[0-3] 00000000 ||^^^^^| |+-----+---- G0-3 Character Set +----------- Is G0-3 double byte? state->c[4] 00000000 || |+---- Locked-Shift? +----- ESC Throughout */ #define ESC 0x1B #define SO 0x0E #define SI 0x0F #define LF 0x0A #define MAX_ESCSEQLEN 16 #define CHARSET_ISO8859_1 'A' #define CHARSET_ASCII 'B' #define CHARSET_ISO8859_7 'F' #define CHARSET_JISX0201_K 'I' #define CHARSET_JISX0201_R 'J' #define CHARSET_GB2312 ('A'|CHARSET_DBCS) #define CHARSET_JISX0208 ('B'|CHARSET_DBCS) #define CHARSET_KSX1001 ('C'|CHARSET_DBCS) #define CHARSET_JISX0212 ('D'|CHARSET_DBCS) #define CHARSET_GB2312_8565 ('E'|CHARSET_DBCS) #define CHARSET_CNS11643_1 ('G'|CHARSET_DBCS) #define CHARSET_CNS11643_2 ('H'|CHARSET_DBCS) #define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS) #define CHARSET_JISX0213_2 ('P'|CHARSET_DBCS) #define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS) #define CHARSET_JISX0208_O ('@'|CHARSET_DBCS) #define CHARSET_DBCS 0x80 #define ESCMARK(mark) ((mark) & 0x7f) #define IS_ESCEND(c) (((c) >= 'A' && (c) <= 'Z') || (c) == '@') #define IS_ISO2022ESC(c2) \ ((c2) == '(' || (c2) == ')' || (c2) == '$' || \ (c2) == '.' || (c2) == '&') /* this is not a complete list of ISO-2022 escape sequence headers. * but, it's enough to implement CJK instances of iso-2022. */ #define MAP_UNMAPPABLE 0xFFFF #define MAP_MULTIPLE_AVAIL 0xFFFE /* for JIS X 0213 */ #define F_SHIFTED 0x01 #define F_ESCTHROUGHOUT 0x02 #define STATE_SETG(dn, v) ((state)->c[dn]) = (v); #define STATE_GETG(dn) ((state)->c[dn]) #define STATE_G0 STATE_GETG(0) #define STATE_G1 STATE_GETG(1) #define STATE_G2 STATE_GETG(2) #define STATE_G3 STATE_GETG(3) #define STATE_SETG0(v) STATE_SETG(0, v) #define STATE_SETG1(v) STATE_SETG(1, v) #define STATE_SETG2(v) STATE_SETG(2, v) #define STATE_SETG3(v) STATE_SETG(3, v) #define STATE_SETFLAG(f) ((state)->c[4]) |= (f); #define STATE_GETFLAG(f) ((state)->c[4] & (f)) #define STATE_CLEARFLAG(f) ((state)->c[4]) &= ~(f); #define STATE_CLEARFLAGS() ((state)->c[4]) = 0; #define ISO2022_CONFIG ((const struct iso2022_config *)config) #define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag)) #define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations) /* iso2022_config.flags */ #define NO_SHIFT 0x01 #define USE_G2 0x02 #define USE_JISX0208_EXT 0x04 /*-*- internal data structures -*-*/ typedef int (*iso2022_init_func)(void); typedef ucs4_t (*iso2022_decode_func)(const unsigned char *data); typedef DBCHAR (*iso2022_encode_func)(const ucs4_t *data, Py_ssize_t *length); struct iso2022_designation { unsigned char mark; unsigned char plane; unsigned char width; iso2022_init_func initializer; iso2022_decode_func decoder; iso2022_encode_func encoder; }; struct iso2022_config { int flags; const struct iso2022_designation *designations; /* non-ascii desigs */ }; /*-*- iso-2022 codec implementation -*-*/ CODEC_INIT(iso2022) { const struct iso2022_designation *desig = CONFIG_DESIGNATIONS; for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) if (desig->initializer != NULL && desig->initializer() != 0) return -1; return 0; } ENCODER_INIT(iso2022) { STATE_CLEARFLAGS() STATE_SETG0(CHARSET_ASCII) STATE_SETG1(CHARSET_ASCII) return 0; } ENCODER_RESET(iso2022) { if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) NEXT_OUT(1) STATE_CLEARFLAG(F_SHIFTED) } if (STATE_G0 != CHARSET_ASCII) { WRITE3(ESC, '(', 'B') NEXT_OUT(3) STATE_SETG0(CHARSET_ASCII) } return 0; } ENCODER(iso2022) { while (inleft > 0) { const struct iso2022_designation *dsg; DBCHAR encoded; ucs4_t c = **inbuf; Py_ssize_t insize; if (c < 0x80) { if (STATE_G0 != CHARSET_ASCII) { WRITE3(ESC, '(', 'B') STATE_SETG0(CHARSET_ASCII) NEXT_OUT(3) } if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) STATE_CLEARFLAG(F_SHIFTED) NEXT_OUT(1) } WRITE1((unsigned char)c) NEXT(1, 1) continue; } DECODE_SURROGATE(c) insize = GET_INSIZE(c); encoded = MAP_UNMAPPABLE; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { Py_ssize_t length = 1; encoded = dsg->encoder(&c, &length); if (encoded == MAP_MULTIPLE_AVAIL) { /* this implementation won't work for pair * of non-bmp characters. */ if (inleft < 2) { if (!(flags & MBENC_FLUSH)) return MBERR_TOOFEW; length = -1; } else length = 2; #if Py_UNICODE_SIZE == 2 if (length == 2) { ucs4_t u4in[2]; u4in[0] = (ucs4_t)IN1; u4in[1] = (ucs4_t)IN2; encoded = dsg->encoder(u4in, &length); } else encoded = dsg->encoder(&c, &length); #else encoded = dsg->encoder(*inbuf, &length); #endif if (encoded != MAP_UNMAPPABLE) { insize = length; break; } } else if (encoded != MAP_UNMAPPABLE) break; } if (!dsg->mark) return 1; assert(dsg->width == 1 || dsg->width == 2); switch (dsg->plane) { case 0: /* G0 */ if (STATE_GETFLAG(F_SHIFTED)) { WRITE1(SI) STATE_CLEARFLAG(F_SHIFTED) NEXT_OUT(1) } if (STATE_G0 != dsg->mark) { if (dsg->width == 1) { WRITE3(ESC, '(', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(3) } else if (dsg->mark == CHARSET_JISX0208) { WRITE3(ESC, '$', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(3) } else { WRITE4(ESC, '$', '(', ESCMARK(dsg->mark)) STATE_SETG0(dsg->mark) NEXT_OUT(4) } } break; case 1: /* G1 */ if (STATE_G1 != dsg->mark) { if (dsg->width == 1) { WRITE3(ESC, ')', ESCMARK(dsg->mark)) STATE_SETG1(dsg->mark) NEXT_OUT(3) } else { WRITE4(ESC, '$', ')', ESCMARK(dsg->mark)) STATE_SETG1(dsg->mark) NEXT_OUT(4) } } if (!STATE_GETFLAG(F_SHIFTED)) { WRITE1(SO) STATE_SETFLAG(F_SHIFTED) NEXT_OUT(1) } break; default: /* G2 and G3 is not supported: no encoding in * CJKCodecs are using them yet */ return MBERR_INTERNAL; } if (dsg->width == 1) { WRITE1((unsigned char)encoded) NEXT_OUT(1) } else { WRITE2(encoded >> 8, encoded & 0xff) NEXT_OUT(2) } NEXT_IN(insize) } return 0; } DECODER_INIT(iso2022) { STATE_CLEARFLAGS() STATE_SETG0(CHARSET_ASCII) STATE_SETG1(CHARSET_ASCII) STATE_SETG2(CHARSET_ASCII) return 0; } DECODER_RESET(iso2022) { STATE_SETG0(CHARSET_ASCII) STATE_CLEARFLAG(F_SHIFTED) return 0; } static Py_ssize_t iso2022processesc(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft) { unsigned char charset, designation; Py_ssize_t i, esclen; for (i = 1;i < MAX_ESCSEQLEN;i++) { if (i >= *inleft) return MBERR_TOOFEW; if (IS_ESCEND((*inbuf)[i])) { esclen = i + 1; break; } else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft && (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@') i += 2; } if (i >= MAX_ESCSEQLEN) return 1; /* unterminated escape sequence */ switch (esclen) { case 3: if (IN2 == '$') { charset = IN3 | CHARSET_DBCS; designation = 0; } else { charset = IN3; if (IN2 == '(') designation = 0; else if (IN2 == ')') designation = 1; else if (CONFIG_ISSET(USE_G2) && IN2 == '.') designation = 2; else return 3; } break; case 4: if (IN2 != '$') return 4; charset = IN4 | CHARSET_DBCS; if (IN3 == '(') designation = 0; else if (IN3 == ')') designation = 1; else return 4; break; case 6: /* designation with prefix */ if (CONFIG_ISSET(USE_JISX0208_EXT) && (*inbuf)[3] == ESC && (*inbuf)[4] == '$' && (*inbuf)[5] == 'B') { charset = 'B' | CHARSET_DBCS; designation = 0; } else return 6; break; default: return esclen; } /* raise error when the charset is not designated for this encoding */ if (charset != CHARSET_ASCII) { const struct iso2022_designation *dsg; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) if (dsg->mark == charset) break; if (!dsg->mark) return esclen; } STATE_SETG(designation, charset) *inleft -= esclen; (*inbuf) += esclen; return 0; } #define ISO8859_7_DECODE(c, assi) \ if ((c) < 0xa0) (assi) = (c); \ else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) \ (assi) = (c); \ else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 || \ (0xbffffd77L & (1L << ((c)-0xb4))))) \ (assi) = 0x02d0 + (c); \ else if ((c) == 0xa1) (assi) = 0x2018; \ else if ((c) == 0xa2) (assi) = 0x2019; \ else if ((c) == 0xaf) (assi) = 0x2015; static Py_ssize_t iso2022processg2(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft, Py_UNICODE **outbuf, Py_ssize_t *outleft) { /* not written to use encoder, decoder functions because only few * encodings use G2 designations in CJKCodecs */ if (STATE_G2 == CHARSET_ISO8859_1) { if (IN3 < 0x80) OUT1(IN3 + 0x80) else return 3; } else if (STATE_G2 == CHARSET_ISO8859_7) { ISO8859_7_DECODE(IN3 ^ 0x80, **outbuf) else return 3; } else if (STATE_G2 == CHARSET_ASCII) { if (IN3 & 0x80) return 3; else **outbuf = IN3; } else return MBERR_INTERNAL; (*inbuf) += 3; *inleft -= 3; (*outbuf) += 1; *outleft -= 1; return 0; } DECODER(iso2022) { const struct iso2022_designation *dsgcache = NULL; while (inleft > 0) { unsigned char c = IN1; Py_ssize_t err; if (STATE_GETFLAG(F_ESCTHROUGHOUT)) { /* ESC throughout mode: * for non-iso2022 escape sequences */ WRITE1(c) /* assume as ISO-8859-1 */ NEXT(1, 1) if (IS_ESCEND(c)) { STATE_CLEARFLAG(F_ESCTHROUGHOUT) } continue; } switch (c) { case ESC: REQUIRE_INBUF(2) if (IS_ISO2022ESC(IN2)) { err = iso2022processesc(config, state, inbuf, &inleft); if (err != 0) return err; } else if (CONFIG_ISSET(USE_G2) && IN2 == 'N') {/* SS2 */ REQUIRE_INBUF(3) err = iso2022processg2(config, state, inbuf, &inleft, outbuf, &outleft); if (err != 0) return err; } else { WRITE1(ESC) STATE_SETFLAG(F_ESCTHROUGHOUT) NEXT(1, 1) } break; case SI: if (CONFIG_ISSET(NO_SHIFT)) goto bypass; STATE_CLEARFLAG(F_SHIFTED) NEXT_IN(1) break; case SO: if (CONFIG_ISSET(NO_SHIFT)) goto bypass; STATE_SETFLAG(F_SHIFTED) NEXT_IN(1) break; case LF: STATE_CLEARFLAG(F_SHIFTED) WRITE1(LF) NEXT(1, 1) break; default: if (c < 0x20) /* C0 */ goto bypass; else if (c >= 0x80) return 1; else { const struct iso2022_designation *dsg; unsigned char charset; ucs4_t decoded; if (STATE_GETFLAG(F_SHIFTED)) charset = STATE_G1; else charset = STATE_G0; if (charset == CHARSET_ASCII) { bypass: WRITE1(c) NEXT(1, 1) break; } if (dsgcache != NULL &&