+
+ /* Writing of UTF-16BE */
+ case UTF16_BE_WRITE:
+ {
+ void *p = &c->code;
+ c->string_at = p;
+ uint code = c->code;
+ c->string_at = p;
+ if (code < 0xd800 || code - 0xe000 < 0x2000)
+ {}
+ else if ((code -= 0x10000) < 0x100000)
+ {
+ put_u16_be(p, 0xd800 | (code >> 10));
+ put_u16_be(p + 2, 0xdc00 | (code & 0x3ff));
+ c->remains = 4;
+ c->state = SEQ_WRITE;
+ goto seq;
+ }
+ else
+ code = UNI_REPLACEMENT;
+ put_u16_be(p, code);
+ c->remains = 2;
+ c->state = SEQ_WRITE;
+ goto seq;
+ }
+
+ /* Writing of UTF-16LE */
+ case UTF16_LE_WRITE:
+ {
+ void *p = &c->code;
+ c->string_at = p;
+ uint code = c->code;
+ c->string_at = p;
+ if (code < 0xd800 || code - 0xe000 < 0x2000)
+ {}
+ else if ((code -= 0x10000) < 0x100000)
+ {
+ put_u16_le(p, 0xd800 | (code >> 10));
+ put_u16_le(p + 2, 0xdc00 | (code & 0x3ff));
+ c->remains = 4;
+ c->state = SEQ_WRITE;
+ }
+ else
+ code = UNI_REPLACEMENT;
+ put_u16_le(p, code);
+ c->remains = 2;
+ c->state = SEQ_WRITE;
+ goto seq;
+ }
+
+ /* Reading of UTF16-BE */
+ case UTF16_BE_READ:
+ if (s >= se)
+ goto cse;
+ c->code = *s++;
+ c->state = UTF16_BE_READ_1;
+ /* fall-thru */
+ case UTF16_BE_READ_1:
+ if (s >= se)
+ goto cse;
+ c->code = (c->code << 8) | *s++;
+ if (c->code - 0xd800 >= 0x800)
+ goto got_char;
+ c->code = (c->code - 0xd800) << 10;
+ c->state = UTF16_BE_READ_2;
+ /* fall-thru */
+ case UTF16_BE_READ_2:
+ if (s >= se)
+ goto cse;
+ if (*s - 0xdc >= 4)
+ c->code = ~0U;
+ else
+ c->code |= (*s - 0xdc) << 8;
+ s++;
+ c->state = UTF16_BE_READ_3;
+ /* fall-thru */
+ case UTF16_BE_READ_3:
+ if (s >= se)
+ goto cse;
+ if ((int)c->code >= 0)
+ c->code += 0x10000 + *s;
+ else
+ c->code = UNI_REPLACEMENT;
+ s++;
+ goto got_char;
+
+ /* Reading of UTF16-LE */
+ case UTF16_LE_READ:
+ if (s >= se)
+ goto cse;
+ c->code = *s++;
+ c->state = UTF16_LE_READ_1;
+ /* fall-thru */
+ case UTF16_LE_READ_1:
+ if (s >= se)
+ goto cse;
+ c->code |= *s++ << 8;
+ if (c->code - 0xd800 >= 0x800)
+ goto got_char;
+ c->code = (c->code - 0xd800) << 10;
+ c->state = UTF16_LE_READ_2;
+ /* fall-thru */
+ case UTF16_LE_READ_2:
+ if (s >= se)
+ goto cse;
+ c->code |= *s++;
+ c->state = UTF16_LE_READ_3;
+ /* fall-thru */
+ case UTF16_LE_READ_3:
+ if (s >= se)
+ goto cse;
+ if (*s - 0xdc < 4)
+ c->code += 0x10000 + ((*s - 0xdc) << 8);
+ else
+ c->code = UNI_REPLACEMENT;
+ s++;
+ goto got_char;
+