public ByteBuffer convertChunk( byte[] b, int offset, int length, ByteBuffer dst, boolean endOfInput) throws SVNException { myInputByteBuffer = allocate(myInputByteBuffer, length); myInputByteBuffer.put(b, offset, length); myInputByteBuffer.flip(); myCharBuffer = allocate(myCharBuffer, (int) (myDecoder.maxCharsPerByte() * myInputByteBuffer.remaining())); CoderResult result = myDecoder.decode(myInputByteBuffer, myCharBuffer, endOfInput); if (result.isError()) { throwException(result); } else if (result.isUnderflow()) { myInputByteBuffer.compact(); } else { myInputByteBuffer.clear(); } myCharBuffer.flip(); dst = allocate(dst, (int) (myEncoder.maxBytesPerChar() * myCharBuffer.remaining())); result = myEncoder.encode(myCharBuffer, dst, false); if (result.isError()) { throwException(result); } else if (result.isUnderflow()) { myCharBuffer.compact(); } else { myCharBuffer.clear(); } return dst; }
public char[] encode(byte[] data, String encoding) throws IOException { if (encoding == null) { encoding = DEFAULT_ENCODING; } if (!Charset.isSupported(encoding)) throw new IOException("Unsupported encoding " + encoding); Charset charset = Charset.forName(encoding); CharsetDecoder cd = charset .newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE); int en = (int) (cd.maxCharsPerByte() * data.length); char[] ca = new char[en]; ByteBuffer bb = ByteBuffer.wrap(data); CharBuffer cb = CharBuffer.wrap(ca); CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) { cr.throwException(); } cr = cd.flush(cb); if (!cr.isUnderflow()) { cr.throwException(); } return trim(ca, cb.position()); }
@SuppressFBWarnings("SUA_SUSPICIOUS_UNINITIALIZED_ARRAY") public static String decode( final CharsetDecoder cd, final byte[] ba, final int off, final int len) { if (len == 0) { return ""; } int en = (int) (len * (double) cd.maxCharsPerByte()); char[] ca = Arrays.getCharsTmp(en); if (cd instanceof ArrayDecoder) { int clen = ((ArrayDecoder) cd).decode(ba, off, len, ca); return new String(ca, 0, clen); } cd.reset(); ByteBuffer bb = ByteBuffer.wrap(ba, off, len); CharBuffer cb = CharBuffer.wrap(ca); try { CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) { cr.throwException(); } cr = cd.flush(cb); if (!cr.isUnderflow()) { cr.throwException(); } } catch (CharacterCodingException x) { throw new Error(x); } return new String(ca, 0, cb.position()); }
char[] decode(byte[] ba, int off, int len) { int en = (int) (cd.maxCharsPerByte() * len); char[] ca = new char[en]; if (len == 0) return ca; cd.reset(); ByteBuffer bb = ByteBuffer.wrap(ba, off, len); CharBuffer cb = CharBuffer.wrap(ca); try { CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) cr.throwException(); cr = cd.flush(cb); if (!cr.isUnderflow()) cr.throwException(); } catch (CharacterCodingException x) { // Substitution is always enabled, // so this shouldn't happen throw new Error(x); } return trim(ca, cb.position()); }
@JRubyMethod public IRubyObject convert(ThreadContext context, IRubyObject srcBuffer) { if (!(srcBuffer instanceof RubyString)) { throw context.runtime.newTypeError(srcBuffer, context.runtime.getString()); } RubyString srcString = (RubyString) srcBuffer; ByteList srcBL = srcString.getByteList(); if (srcBL.getRealSize() == 0) return context.runtime.newSymbol("source_buffer_empty"); ByteBuffer srcBB = ByteBuffer.wrap(srcBL.getUnsafeBytes(), srcBL.begin(), srcBL.getRealSize()); try { CharBuffer srcCB = CharBuffer.allocate((int) (srcDecoder.maxCharsPerByte() * srcBL.getRealSize()) + 1); CoderResult decodeResult = srcDecoder.decode(srcBB, srcCB, true); srcCB.flip(); ByteBuffer destBB = ByteBuffer.allocate((int) (destEncoder.maxBytesPerChar() * srcCB.limit()) + 1); CoderResult encodeResult = destEncoder.encode(srcCB, destBB, true); destBB.flip(); byte[] destBytes = new byte[destBB.limit()]; destBB.get(destBytes); srcDecoder.reset(); destEncoder.reset(); return context.runtime.newString(new ByteList(destBytes, destEncoding.getEncoding(), false)); } catch (Exception e) { throw context.runtime.newRuntimeError(e.getLocalizedMessage()); } }
String toString(byte[] ba, int length) { CharsetDecoder cd = decoder().reset(); int len = (int) (length * cd.maxCharsPerByte()); char[] ca = new char[len]; if (len == 0) return new String(ca); ByteBuffer bb = ByteBuffer.wrap(ba, 0, length); CharBuffer cb = CharBuffer.wrap(ca); CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) throw new IllegalArgumentException(cr.toString()); cr = cd.flush(cb); if (!cr.isUnderflow()) throw new IllegalArgumentException(cr.toString()); return new String(ca, 0, cb.position()); }
static char[] decode(Charset cs, byte[] ba, int off, int len) { // (1)We never cache the "external" cs, the only benefit of creating // an additional StringDe/Encoder object to wrap it is to share the // de/encode() method. These SD/E objects are short-lifed, the young-gen // gc should be able to take care of them well. But the best approash // is still not to generate them if not really necessary. // (2)The defensive copy of the input byte/char[] has a big performance // impact, as well as the outgoing result byte/char[]. Need to do the // optimization check of (sm==null && classLoader0==null) for both. // (3)getClass().getClassLoader0() is expensive // (4)There might be a timing gap in isTrusted setting. getClassLoader0() // is only chcked (and then isTrusted gets set) when (SM==null). It is // possible that the SM==null for now but then SM is NOT null later // when safeTrim() is invoked...the "safe" way to do is to redundant // check (... && (isTrusted || SM == null || getClassLoader0())) in trim // but it then can be argued that the SM is null when the opertaion // is started... CharsetDecoder cd = cs.newDecoder(); int en = scale(len, cd.maxCharsPerByte()); char[] ca = new char[en]; if (len == 0) return ca; boolean isTrusted = false; if (System.getSecurityManager() != null) { if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) { ba = Arrays.copyOfRange(ba, off, off + len); off = 0; } } cd.onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .reset(); if (cd instanceof ArrayDecoder) { int clen = ((ArrayDecoder) cd).decode(ba, off, len, ca); return safeTrim(ca, clen, cs, isTrusted); } else { ByteBuffer bb = ByteBuffer.wrap(ba, off, len); CharBuffer cb = CharBuffer.wrap(ca); try { CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) cr.throwException(); cr = cd.flush(cb); if (!cr.isUnderflow()) cr.throwException(); } catch (CharacterCodingException x) { // Substitution is always enabled, // so this shouldn't happen throw new Error(x); } return safeTrim(ca, cb.position(), cs, isTrusted); } }
static String decodeString(ByteBuffer src, Charset charset) { final CharsetDecoder decoder = CharsetUtil.getDecoder(charset); final CharBuffer dst = CharBuffer.allocate((int) ((double) src.remaining() * decoder.maxCharsPerByte())); try { CoderResult cr = decoder.decode(src, dst, true); if (!cr.isUnderflow()) { cr.throwException(); } cr = decoder.flush(dst); if (!cr.isUnderflow()) { cr.throwException(); } } catch (CharacterCodingException x) { throw new IllegalStateException(x); } return dst.flip().toString(); }
@SuppressWarnings("unchecked") public static <T> T parseObject( byte[] input, int off, int len, CharsetDecoder charsetDecoder, Type clazz, Feature... features) { charsetDecoder.reset(); int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); char[] chars = ThreadLocalCache.getChars(scaleLength); ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); CharBuffer charByte = CharBuffer.wrap(chars); IOUtils.decode(charsetDecoder, byteBuf, charByte); int position = charByte.position(); return (T) parseObject(chars, position, clazz, features); }
@Override public String toUtf8() { if (!buffer.hasRemaining()) { return ""; } final CharsetDecoder decoder = CharsetUtil.getDecoder(Charsets.UTF_8); final CharBuffer dst = CharBuffer.allocate((int) ((double) buffer.remaining() * decoder.maxCharsPerByte())); try { CoderResult cr = decoder.decode(buffer, dst, true); if (!cr.isUnderflow()) { cr.throwException(); } cr = decoder.flush(dst); if (!cr.isUnderflow()) { cr.throwException(); } } catch (CharacterCodingException x) { throw new IllegalStateException(x); } return dst.flip().toString(); }
public static Object parse( byte[] input, int off, int len, CharsetDecoder charsetDecoder, int features) { charsetDecoder.reset(); int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); char[] chars = ThreadLocalCache.getChars(scaleLength); ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); CharBuffer charBuf = CharBuffer.wrap(chars); IOUtils.decode(charsetDecoder, byteBuf, charBuf); int position = charBuf.position(); DefaultJSONParser parser = new DefaultJSONParser(chars, position, ParserConfig.getGlobalInstance(), features); Object value = parser.parse(); parser.handleResovleTask(value); parser.close(); return value; }
char[] decode(byte[] ba, int off, int len) { int en = scale(len, cd.maxCharsPerByte()); char[] ca = new char[en]; if (len == 0) return ca; if (cd instanceof ArrayDecoder) { int clen = ((ArrayDecoder) cd).decode(ba, off, len, ca); return safeTrim(ca, clen, cs, isTrusted); } else { cd.reset(); ByteBuffer bb = ByteBuffer.wrap(ba, off, len); CharBuffer cb = CharBuffer.wrap(ca); try { CoderResult cr = cd.decode(bb, cb, true); if (!cr.isUnderflow()) cr.throwException(); cr = cd.flush(cb); if (!cr.isUnderflow()) cr.throwException(); } catch (CharacterCodingException x) { // Substitution is always enabled, // so this shouldn't happen throw new Error(x); } return safeTrim(ca, cb.position(), cs, isTrusted); } }
/** * Returns the maximum number of characters needed to convert a byte. Useful for calculating the * maximum output buffer size needed for a particular input buffer. */ public int getMaxCharsPerByte() { if (decoder != null) return (int) Math.ceil(decoder.maxCharsPerByte()); else // only provided for subclasses return 1; // Until UTF-16, this will do for every encoding }