From: handa Date: Mon, 5 Sep 2005 05:01:00 +0000 (+0000) Subject: (read_mtext_element): Handle \uXXXX notation. X-Git-Tag: REL-1-3-0~189 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6f50210716b98bb790d2b97b4c4e9799e1be5bf;p=m17n%2Fm17n-lib.git (read_mtext_element): Handle \uXXXX notation. --- diff --git a/src/plist.c b/src/plist.c index 165d25f..3947726 100644 --- a/src/plist.c +++ b/src/plist.c @@ -206,35 +206,30 @@ read_hexadesimal (MStream *st) /** Read an M-text element from ST, and add it to LIST. Return a list for the next element. */ +#define READ_MTEXT_BUF_SIZE 256 + static MPlist * read_mtext_element (MPlist *plist, MStream *st, int skip) { - unsigned char buffer[1024]; - int bufsize = 1024; - unsigned char *buf = buffer; - int c, i; + union { + int chars[READ_MTEXT_BUF_SIZE]; + unsigned char bytes[sizeof (int) * READ_MTEXT_BUF_SIZE]; + } buffer; + unsigned char *bytes = buffer.bytes; + int nbytes = sizeof (int) * READ_MTEXT_BUF_SIZE; + int *chars = NULL; + int nchars = 0; + int c, i, j; i = 0; while ((c = GETC (st)) != EOF && c != '"') { - if (i + MAX_UTF8_CHAR_BYTES >= bufsize) - { - bufsize *= 2; - if (buf == buffer) - { - MTABLE_MALLOC (buf, bufsize, MERROR_PLIST); - memcpy (buf, buffer, i); - } - else - MTABLE_REALLOC (buf, bufsize, MERROR_PLIST); - } - if (c == '\\') { c = GETC (st); if (c == EOF) break; - if (c == 'x') + if (c == 'x' || c == 'u') { int next_c; @@ -248,15 +243,67 @@ read_mtext_element (MPlist *plist, MStream *st, int skip) } if (! skip) - buf[i++] = c; + { + if (c >= 0x80 && ! chars) + { + chars = buffer.chars; + for (j = i - 1; j >= 0; j--) + chars[j] = bytes[j]; + nchars = i; + if (bytes != buffer.bytes) + free (bytes); + } + + if (chars) + { + if (i + 1 >= nchars) + { + nchars *= 2; + if (chars == buffer.chars) + { + MTABLE_MALLOC (chars, nchars, MERROR_PLIST); + memcpy (chars, buffer.chars, sizeof (int) * i); + } + else + MTABLE_REALLOC (chars, nchars, MERROR_PLIST); + } + chars[i++] = c; + } + else + { + if (i + MAX_UTF8_CHAR_BYTES >= nbytes) + { + nbytes *= 2; + if (bytes == buffer.bytes) + { + MTABLE_MALLOC (bytes, nbytes, MERROR_PLIST); + memcpy (bytes, buffer.bytes, i); + } + else + MTABLE_REALLOC (bytes, nbytes, MERROR_PLIST); + } + bytes[i++] = c; + } + } } if (! skip) { - MPLIST_SET_ADVANCE (plist, Mtext, - mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1)); - if (buf != buffer) - free (buf); + MText *mt; + + if (chars) + { + mt = mtext__from_data (chars, i, MTEXT_FORMAT_UTF_32, 1); + if (chars != buffer.chars) + free (chars); + } + else + { + mt = mtext__from_data (bytes, i, MTEXT_FORMAT_UTF_8, 1); + if (bytes != buffer.bytes) + free (bytes); + } + MPLIST_SET_ADVANCE (plist, Mtext, mt); } return plist; }