protected CoderResult decodeLoop(ByteBuffer bb, CharBuffer cb) { int cbRemaining = cb.remaining(); if (CharsetProviderImpl.hasLoadedNatives() && bb.isDirect() && bb.hasRemaining() && cb.hasArray()) { int toProceed = bb.remaining(); int cbPos = cb.position(); int bbPos = bb.position(); boolean throwOverflow = false; if (cbRemaining < toProceed) { toProceed = cbRemaining; throwOverflow = true; } int res = nDecode( cb.array(), cb.arrayOffset() + cbPos, toProceed, AddressUtil.getDirectBufferAddress(bb), bbPos); bb.position(bbPos + res); cb.position(cbPos + res); if (throwOverflow) return CoderResult.OVERFLOW; } else { if (bb.hasArray() && cb.hasArray()) { int rem = bb.remaining(); rem = cbRemaining >= rem ? rem : cbRemaining; byte[] bArr = bb.array(); char[] cArr = cb.array(); int bStart = bb.position(); int cStart = cb.position(); int i; for (i = bStart; i < bStart + rem; i++) { char in = (char) (bArr[i] & 0xFF); if (in >= 4) { int index = (int) in - 4; cArr[cStart++] = (char) arr[index]; } else { cArr[cStart++] = (char) (in & 0xFF); } } bb.position(i); cb.position(cStart); if (rem == cbRemaining && bb.hasRemaining()) return CoderResult.OVERFLOW; } else { while (bb.hasRemaining()) { if (cbRemaining == 0) return CoderResult.OVERFLOW; char in = (char) (bb.get() & 0xFF); if (in >= 4) { int index = (int) in - 4; cb.put(arr[index]); } else { cb.put((char) (in & 0xFF)); } cbRemaining--; } } } return CoderResult.UNDERFLOW; }
protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb) { int bbRemaining = bb.remaining(); if (CharsetProviderImpl.hasLoadedNatives() && bb.isDirect() && cb.hasRemaining() && cb.hasArray()) { int toProceed = cb.remaining(); int cbPos = cb.position(); int bbPos = bb.position(); boolean throwOverflow = false; if (bbRemaining < toProceed) { toProceed = bbRemaining; throwOverflow = true; } int[] res = {toProceed, 0}; nEncode( AddressUtil.getDirectBufferAddress(bb), bbPos, cb.array(), cb.arrayOffset() + cbPos, res); if (res[0] <= 0) { bb.position(bbPos - res[0]); cb.position(cbPos - res[0]); if (res[1] != 0) { if (res[1] < 0) return CoderResult.malformedForLength(-res[1]); else return CoderResult.unmappableForLength(res[1]); } } else { bb.position(bbPos + res[0]); cb.position(cbPos + res[0]); if (throwOverflow) return CoderResult.OVERFLOW; } } else { if (bb.hasArray() && cb.hasArray()) { byte[] byteArr = bb.array(); char[] charArr = cb.array(); int rem = cb.remaining(); int byteArrStart = bb.position(); rem = bbRemaining <= rem ? bbRemaining : rem; int x; for (x = cb.position(); x < cb.position() + rem; x++) { char c = charArr[x]; if (c > (char) 0x20AC) { if (c >= 0xD800 && c <= 0xDFFF) { if (x + 1 < cb.limit()) { char c1 = charArr[x + 1]; if (c1 >= 0xD800 && c1 <= 0xDFFF) { cb.position(x); bb.position(byteArrStart); return CoderResult.unmappableForLength(2); } } else { cb.position(x); bb.position(byteArrStart); return CoderResult.UNDERFLOW; } cb.position(x); bb.position(byteArrStart); return CoderResult.malformedForLength(1); } cb.position(x); bb.position(byteArrStart); return CoderResult.unmappableForLength(1); } else { if (c < 0x04) { byteArr[byteArrStart++] = (byte) c; } else { int index = (int) c >> 8; index = encodeIndex[index]; if (index < 0) { cb.position(x); bb.position(byteArrStart); return CoderResult.unmappableForLength(1); } index <<= 8; index += (int) c & 0xFF; if ((byte) arr[index] != 0) { byteArr[byteArrStart++] = (byte) arr[index]; } else { cb.position(x); bb.position(byteArrStart); return CoderResult.unmappableForLength(1); } } } } cb.position(x); bb.position(byteArrStart); if (rem == bbRemaining && cb.hasRemaining()) { return CoderResult.OVERFLOW; } } else { while (cb.hasRemaining()) { if (bbRemaining == 0) return CoderResult.OVERFLOW; char c = cb.get(); if (c > (char) 0x20AC) { if (c >= 0xD800 && c <= 0xDFFF) { if (cb.hasRemaining()) { char c1 = cb.get(); if (c1 >= 0xD800 && c1 <= 0xDFFF) { cb.position(cb.position() - 2); return CoderResult.unmappableForLength(2); } else { cb.position(cb.position() - 1); } } else { cb.position(cb.position() - 1); return CoderResult.UNDERFLOW; } cb.position(cb.position() - 1); return CoderResult.malformedForLength(1); } cb.position(cb.position() - 1); return CoderResult.unmappableForLength(1); } else { if (c < 0x04) { bb.put((byte) c); } else { int index = (int) c >> 8; index = encodeIndex[index]; if (index < 0) { cb.position(cb.position() - 1); return CoderResult.unmappableForLength(1); } index <<= 8; index += (int) c & 0xFF; if ((byte) arr[index] != 0) { bb.put((byte) arr[index]); } else { cb.position(cb.position() - 1); return CoderResult.unmappableForLength(1); } } bbRemaining--; } } } } return CoderResult.UNDERFLOW; }