// protected int[] readExtIndexes(int skip) throws IOException protected ByteBuffer readExtIndexes(int skip) throws IOException, InvalidFormatException { ICUBinary.skipBytes(byteBuffer, skip); ByteBuffer b = ICUBinary.sliceWithOrder(byteBuffer); int lengthOfIndexes = b.getInt(0); if (lengthOfIndexes < 32) { throw new InvalidFormatException(); } int numBytesExtensionStructure = b.getInt(31 * 4); b.limit(numBytesExtensionStructure); ICUBinary.skipBytes(byteBuffer, numBytesExtensionStructure); return b; }
/** * Protected constructor. * * @param bytes ICU conversion data file * @exception IOException throw if data file fails authentication */ protected UConverterDataReader(ByteBuffer bytes) throws IOException { // if(debug) System.out.println("Bytes in buffer " + bytes.remaining()); byteBuffer = bytes; /*unicodeVersion = */ ICUBinary.readHeader(byteBuffer, DATA_FORMAT_ID, IS_ACCEPTABLE); // if(debug) System.out.println("Bytes left in byteBuffer " + byteBuffer.remaining()); }
protected void readMBCSTable(MBCSHeader header, UConverterMBCSTable mbcsTable) throws IOException { IntBuffer intBuffer = byteBuffer.asIntBuffer(); mbcsTable.countStates = (byte) header.countStates; mbcsTable.stateTable = new int[header.countStates][256]; int i; for (i = 0; i < header.countStates; ++i) { intBuffer.get(mbcsTable.stateTable[i]); } mbcsTable.countToUFallbacks = header.countToUFallbacks; mbcsTable.toUFallbacks = new MBCSToUFallback[header.countToUFallbacks]; for (i = 0; i < header.countToUFallbacks; ++i) { int offset = intBuffer.get(); int codePoint = intBuffer.get(); mbcsTable.toUFallbacks[i] = new MBCSToUFallback(offset, codePoint); } // Skip as many bytes as we have read from the IntBuffer. int length = intBuffer.position() * 4; ICUBinary.skipBytes(byteBuffer, length); // Consider leaving some large arrays as CharBuffer/IntBuffer rather than // reading them into Java arrays, to reduce initialization time and memory usage, // at the cost of some performance. // For example: unicodeCodeUnits, fromUnicodeTable, fromUnicodeInts. // Take care not to modify the buffer contents for swaplfnl. CharBuffer charBuffer = byteBuffer.asCharBuffer(); length = header.offsetFromUTable - header.offsetToUCodeUnits; assert (length & 1) == 0; mbcsTable.unicodeCodeUnits = new char[length / 2]; charBuffer.get(mbcsTable.unicodeCodeUnits); // Skip as many bytes as we have read from the CharBuffer. ICUBinary.skipBytes(byteBuffer, length); length = header.offsetFromUBytes - header.offsetFromUTable; assert (length & 1) == 0; int fromUTableCharsLength; if (mbcsTable.outputType == CharsetMBCS.MBCS_OUTPUT_1) { // single-byte table stage1 + stage2 fromUTableCharsLength = length / 2; } else if (mbcsTable.hasSupplementary()) { // stage1 for Unicode limit 0x110000 >> 10 fromUTableCharsLength = 0x440; } else { // stage1 for BMP limit 0x10000 >> 10 fromUTableCharsLength = 0x40; } mbcsTable.fromUnicodeTable = new char[fromUTableCharsLength]; charBuffer.get(mbcsTable.fromUnicodeTable); if (mbcsTable.outputType != CharsetMBCS.MBCS_OUTPUT_1) { // Read both stage1 and stage2 together into an int[] array. // Keeping the short stage1 in the array avoids offsetting at runtime. // The stage1 part of this array will not be used. assert (length & 3) == 0; mbcsTable.fromUnicodeTableInts = new int[length / 4]; byteBuffer.asIntBuffer().get(mbcsTable.fromUnicodeTableInts); } // Skip as many bytes as are in stage1 + stage2. ICUBinary.skipBytes(byteBuffer, length); mbcsTable.fromUBytesLength = header.fromUBytesLength; boolean noFromU = ((header.options & CharsetMBCS.MBCS_OPT_NO_FROM_U) != 0); if (!noFromU) { switch (mbcsTable.outputType) { case CharsetMBCS.MBCS_OUTPUT_1: case CharsetMBCS.MBCS_OUTPUT_2: case CharsetMBCS.MBCS_OUTPUT_2_SISO: case CharsetMBCS.MBCS_OUTPUT_3_EUC: mbcsTable.fromUnicodeChars = ICUBinary.getChars(byteBuffer, header.fromUBytesLength / 2, 0); break; case CharsetMBCS.MBCS_OUTPUT_3: case CharsetMBCS.MBCS_OUTPUT_4_EUC: mbcsTable.fromUnicodeBytes = new byte[header.fromUBytesLength]; byteBuffer.get(mbcsTable.fromUnicodeBytes); break; case CharsetMBCS.MBCS_OUTPUT_4: mbcsTable.fromUnicodeInts = ICUBinary.getInts(byteBuffer, header.fromUBytesLength / 4, 0); break; default: // Cannot occur, caller checked already. assert false; } } else { // Optional utf8Friendly mbcsIndex -- _MBCSHeader.version 4.3 (ICU 3.8) and higher. // Needed for reconstituting omitted data. mbcsTable.mbcsIndex = byteBuffer.asCharBuffer(); } }