/* Copyright (C) 1999 Cygnus Solutions This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ #include #include #include #define ERROR_CHAR 0xFFFD extern unsigned short JIS0208_to_Unicode[84][94]; extern unsigned short JIS0212_to_Unicode[76][94]; jint gnu::gcj::convert::Input_SJIS::read(jcharArray outbuffer, jint outpos, jint outlength) { jint start_outpos = outpos; for (;;) { if (outpos >= outlength) break; if (inpos >= inlength) break; int b = ((unsigned char*) elements(inbuffer))[inpos++]; if (first_byte == 0) { if (b < 128) { #if 1 // Technically, we should translate 0x5c to Yen symbol; // in practice, it is not clear. if (b == 0x5c) b = 0x00A5; // Yen sign. #endif elements(outbuffer)[outpos++] = (char) b; } else if (b >= 0xA1 && b <= 0xDF) { b += 0xFF61 - 0xA1; elements(outbuffer)[outpos++] = b; } else first_byte = b; } else { // From Lunde: "CJKV Informatio Processing", O'Reilly, 1999, p 420: bool adjust = b < 159; int rowOffset = first_byte < 160 ? 112 : 176; int cellOffset = adjust ? (b > 127 ? 32 : 31) : 126; first_byte = ((first_byte - rowOffset) << 1) - adjust; b -= cellOffset; first_byte -= 33; b -= 33; if ((unsigned) first_byte >= 84 || (unsigned) b >= 94) b = ERROR_CHAR; else { b = JIS0208_to_Unicode[first_byte][b]; if (b == 0) b = ERROR_CHAR; } elements(outbuffer)[outpos++] = b; first_byte = 0; } } return outpos - start_outpos; }