Java Code Examples for java.nio.charset.CoderResult#isUnderflow()

The following examples show how to use java.nio.charset.CoderResult#isUnderflow() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ZipCoder.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
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());
}
 
Example 2
Source File: ShellSession.java    From netbeans with Apache License 2.0 6 votes vote down vote up
private void processInput(final boolean endOfInput) throws IOException {
    // Prepare decoderIn for reading
    decoderIn.flip();
    CoderResult coderResult;
    while (true) {
        coderResult = decoder.decode(decoderIn, decoderOut, endOfInput);
        if (coderResult.isOverflow()) {
            flushOutput();
        } else if (coderResult.isUnderflow()) {
            break;
        } else {
            // The decoder is configured to replace malformed input and unmappable characters,
            // so we should not get here.
            throw new IOException("Unexpected coder result"); //NOI18N
        }
    }
    // Discard the bytes that have been read
    decoderIn.compact();
}
 
Example 3
Source File: TextEncoderHelper.java    From logging-log4j2 with Apache License 2.0 5 votes vote down vote up
private static ByteBuffer encodeAsMuchAsPossible(final CharsetEncoder charsetEncoder, final CharBuffer charBuf,
        final boolean endOfInput, final ByteBufferDestination destination, ByteBuffer temp) {
    CoderResult result;
    do {
        result = charsetEncoder.encode(charBuf, temp, endOfInput);
        temp = drainIfByteBufferFull(destination, temp, result);
    } while (result.isOverflow()); // byte buffer has been drained: retry
    if (!result.isUnderflow()) { // we should have fully read the char buffer contents
        throwException(result);
    }
    return temp;
}
 
Example 4
Source File: DataBuffer.java    From spring-analysis-note with MIT License 5 votes vote down vote up
/**
 * Write the given {@code CharSequence} using the given {@code Charset},
 * starting at the current writing position.
 * @param charSequence the char sequence to write into this buffer
 * @param charset the charset to encode the char sequence with
 * @return this buffer
 * @since 5.1.4
 */
default DataBuffer write(CharSequence charSequence, Charset charset) {
	Assert.notNull(charSequence, "CharSequence must not be null");
	Assert.notNull(charset, "Charset must not be null");
	if (charSequence.length() != 0) {
		CharsetEncoder charsetEncoder = charset.newEncoder()
				.onMalformedInput(CodingErrorAction.REPLACE)
				.onUnmappableCharacter(CodingErrorAction.REPLACE);
		CharBuffer inBuffer = CharBuffer.wrap(charSequence);
		int estimatedSize = (int) (inBuffer.remaining() * charsetEncoder.averageBytesPerChar());
		ByteBuffer outBuffer = ensureCapacity(estimatedSize)
				.asByteBuffer(writePosition(), writableByteCount());
		while (true) {
			CoderResult cr = (inBuffer.hasRemaining() ?
					charsetEncoder.encode(inBuffer, outBuffer, true) : CoderResult.UNDERFLOW);
			if (cr.isUnderflow()) {
				cr = charsetEncoder.flush(outBuffer);
			}
			if (cr.isUnderflow()) {
				break;
			}
			if (cr.isOverflow()) {
				writePosition(writePosition() + outBuffer.position());
				int maximumSize = (int) (inBuffer.remaining() * charsetEncoder.maxBytesPerChar());
				ensureCapacity(maximumSize);
				outBuffer = asByteBuffer(writePosition(), writableByteCount());
			}
		}
		writePosition(writePosition() + outBuffer.position());
	}
	return this;
}
 
Example 5
Source File: StringCoding.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
byte[] encode(char[] ca, int off, int len) {
    int en = scale(len, ce.maxBytesPerChar());
    byte[] ba = new byte[en];
    if (len == 0)
        return ba;
    if (ce instanceof ArrayEncoder) {
        int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
        return safeTrim(ba, blen, cs, isTrusted);
    } else {
        ce.reset();
        ByteBuffer bb = ByteBuffer.wrap(ba);
        CharBuffer cb = CharBuffer.wrap(ca, off, len);
        try {
            CoderResult cr = ce.encode(cb, bb, true);
            if (!cr.isUnderflow())
                cr.throwException();
            cr = ce.flush(bb);
            if (!cr.isUnderflow())
                cr.throwException();
        } catch (CharacterCodingException x) {
            // Substitution is always enabled,
            // so this shouldn't happen
            throw new Error(x);
        }
        return safeTrim(ba, bb.position(), cs, isTrusted);
    }
}
 
Example 6
Source File: StringCoding.java    From dragonwell8_jdk with GNU General Public License v2.0 5 votes vote down vote up
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);
    }
}
 
Example 7
Source File: StringCoding.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
byte[] encode(char[] ca, int off, int len) {
    int en = scale(len, ce.maxBytesPerChar());
    byte[] ba = new byte[en];
    if (len == 0)
        return ba;
    if (ce instanceof ArrayEncoder) {
        int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
        return safeTrim(ba, blen, cs, isTrusted);
    } else {
        ce.reset();
        ByteBuffer bb = ByteBuffer.wrap(ba);
        CharBuffer cb = CharBuffer.wrap(ca, off, len);
        try {
            CoderResult cr = ce.encode(cb, bb, true);
            if (!cr.isUnderflow())
                cr.throwException();
            cr = ce.flush(bb);
            if (!cr.isUnderflow())
                cr.throwException();
        } catch (CharacterCodingException x) {
            // Substitution is always enabled,
            // so this shouldn't happen
            throw new Error(x);
        }
        return safeTrim(ba, bb.position(), cs, isTrusted);
    }
}
 
Example 8
Source File: StringCoding.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
byte[] encode(char[] ca, int off, int len) {
    int en = scale(len, ce.maxBytesPerChar());
    byte[] ba = new byte[en];
    if (len == 0)
        return ba;
    if (ce instanceof ArrayEncoder) {
        int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
        return safeTrim(ba, blen, cs, isTrusted);
    } else {
        ce.reset();
        ByteBuffer bb = ByteBuffer.wrap(ba);
        CharBuffer cb = CharBuffer.wrap(ca, off, len);
        try {
            CoderResult cr = ce.encode(cb, bb, true);
            if (!cr.isUnderflow())
                cr.throwException();
            cr = ce.flush(bb);
            if (!cr.isUnderflow())
                cr.throwException();
        } catch (CharacterCodingException x) {
            // Substitution is always enabled,
            // so this shouldn't happen
            throw new Error(x);
        }
        return safeTrim(ba, bb.position(), cs, isTrusted);
    }
}
 
Example 9
Source File: ByteBufUtil.java    From netty4.0.27Learn with Apache License 2.0 5 votes vote down vote up
static ByteBuf encodeString0(ByteBufAllocator alloc, boolean enforceHeap, CharBuffer src, Charset charset) {
    final CharsetEncoder encoder = CharsetUtil.getEncoder(charset);
    int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar());
    boolean release = true;
    final ByteBuf dst;
    if (enforceHeap) {
        dst = alloc.heapBuffer(length);
    } else {
        dst = alloc.buffer(length);
    }
    try {
        final ByteBuffer dstBuf = dst.internalNioBuffer(0, length);
        final int pos = dstBuf.position();
        CoderResult cr = encoder.encode(src, dstBuf, true);
        if (!cr.isUnderflow()) {
            cr.throwException();
        }
        cr = encoder.flush(dstBuf);
        if (!cr.isUnderflow()) {
            cr.throwException();
        }
        dst.writerIndex(dst.writerIndex() + dstBuf.position() - pos);
        release = false;
        return dst;
    } catch (CharacterCodingException x) {
        throw new IllegalStateException(x);
    } finally {
        if (release) {
            dst.release();
        }
    }
}
 
Example 10
Source File: StringCoding.java    From dragonwell8_jdk with GNU General Public License v2.0 5 votes vote down vote up
static byte[] encode(Charset cs, char[] ca, int off, int len) {
    CharsetEncoder ce = cs.newEncoder();
    int en = scale(len, ce.maxBytesPerChar());
    byte[] ba = new byte[en];
    if (len == 0)
        return ba;
    boolean isTrusted = false;
    if (System.getSecurityManager() != null) {
        if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
            ca =  Arrays.copyOfRange(ca, off, off + len);
            off = 0;
        }
    }
    ce.onMalformedInput(CodingErrorAction.REPLACE)
      .onUnmappableCharacter(CodingErrorAction.REPLACE)
      .reset();
    if (ce instanceof ArrayEncoder) {
        int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
        return safeTrim(ba, blen, cs, isTrusted);
    } else {
        ByteBuffer bb = ByteBuffer.wrap(ba);
        CharBuffer cb = CharBuffer.wrap(ca, off, len);
        try {
            CoderResult cr = ce.encode(cb, bb, true);
            if (!cr.isUnderflow())
                cr.throwException();
            cr = ce.flush(bb);
            if (!cr.isUnderflow())
                cr.throwException();
        } catch (CharacterCodingException x) {
            throw new Error(x);
        }
        return safeTrim(ba, bb.position(), cs, isTrusted);
    }
}
 
Example 11
Source File: CompositeReadableBuffer.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
private CharBuffer readStringFromComponents(CharsetDecoder decoder) throws CharacterCodingException {
    int size = (int)(remaining() * decoder.averageCharsPerByte());
    CharBuffer decoded = CharBuffer.allocate(size);

    int arrayIndex = currentArrayIndex;
    final int viewSpan = limit() - position();
    int processed = Math.min(currentArray.length - currentOffset, viewSpan);
    ByteBuffer wrapper = ByteBuffer.wrap(currentArray, currentOffset, processed);

    CoderResult step = CoderResult.OVERFLOW;

    do {
        boolean endOfInput = processed == viewSpan;
        step = decoder.decode(wrapper, decoded, endOfInput);
        if (step.isUnderflow() && endOfInput) {
            step = decoder.flush(decoded);
            break;
        }

        if (step.isOverflow()) {
            size = 2 * size + 1;
            CharBuffer upsized = CharBuffer.allocate(size);
            decoded.flip();
            upsized.put(decoded);
            decoded = upsized;
            continue;
        }

        byte[] next = contents.get(++arrayIndex);
        int wrapSize = Math.min(next.length, viewSpan - processed);
        wrapper = ByteBuffer.wrap(next, 0, wrapSize);
        processed += wrapSize;
    } while (!step.isError());

    if (step.isError()) {
        step.throwException();
    }

    return (CharBuffer) decoded.flip();
}
 
Example 12
Source File: C2BConverter.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Convert the given characters to bytes.
 * 
 * @param cc char input
 * @param bc byte output
 */
public void convert(CharChunk cc, ByteChunk bc) 
        throws IOException {
    if ((bb == null) || (bb.array() != bc.getBuffer())) {
        // Create a new byte buffer if anything changed
        bb = ByteBuffer.wrap(bc.getBuffer(), bc.getEnd(), 
                bc.getBuffer().length - bc.getEnd());
    } else {
        // Initialize the byte buffer
        bb.limit(bc.getBuffer().length);
        bb.position(bc.getEnd());
    }
    if ((cb == null) || (cb.array() != cc.getBuffer())) {
        // Create a new char buffer if anything changed
        cb = CharBuffer.wrap(cc.getBuffer(), cc.getStart(), 
                cc.getLength());
    } else {
        // Initialize the char buffer
        cb.limit(cc.getEnd());
        cb.position(cc.getStart());
    }
    CoderResult result = null;
    // Parse leftover if any are present
    if (leftovers.position() > 0) {
        int pos = bb.position();
        // Loop until one char is encoded or there is a encoder error
        do {
            leftovers.put((char) cc.substract());
            leftovers.flip();
            result = encoder.encode(leftovers, bb, false);
            leftovers.position(leftovers.limit());
            leftovers.limit(leftovers.array().length);
        } while (result.isUnderflow() && (bb.position() == pos));
        if (result.isError() || result.isMalformed()) {
            result.throwException();
        }
        cb.position(cc.getStart());
        leftovers.position(0);
    }
    // Do the decoding and get the results into the byte chunk and the char
    // chunk
    result = encoder.encode(cb, bb, false);
    if (result.isError() || result.isMalformed()) {
        result.throwException();
    } else if (result.isOverflow()) {
        // Propagate current positions to the byte chunk and char chunk
        bc.setEnd(bb.position());
        cc.setOffset(cb.position());
    } else if (result.isUnderflow()) {
        // Propagate current positions to the byte chunk and char chunk
        bc.setEnd(bb.position());
        cc.setOffset(cb.position());
        // Put leftovers in the leftovers char buffer
        if (cc.getLength() > 0) {
            leftovers.limit(leftovers.array().length);
            leftovers.position(cc.getLength());
            cc.substract(leftovers.array(), 0, cc.getLength());
        }
    }
}
 
Example 13
Source File: StringCoding.java    From dragonwell8_jdk with GNU General Public License v2.0 4 votes vote down vote up
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);
    }
}
 
Example 14
Source File: StringCoding.java    From openjdk-jdk9 with GNU General Public License v2.0 4 votes vote down vote up
static byte[] encode(Charset cs, byte coder, byte[] val) {
    if (cs == UTF_8) {
        return encodeUTF8(coder, val);
    } else if (cs == ISO_8859_1) {
        return encode8859_1(coder, val);
    } else if (cs == US_ASCII) {
        return encodeASCII(coder, val);
    }
    CharsetEncoder ce = cs.newEncoder();
    // fastpath for ascii compatible
    if (coder == LATIN1 && (((ce instanceof ArrayEncoder) &&
                             ((ArrayEncoder)ce).isASCIICompatible() &&
                             !hasNegatives(val, 0, val.length)))) {
        return Arrays.copyOf(val, val.length);
    }
    int len = val.length >> coder;  // assume LATIN1=0/UTF16=1;
    int en = scale(len, ce.maxBytesPerChar());
    byte[] ba = new byte[en];
    if (len == 0) {
        return ba;
    }
    boolean isTrusted = System.getSecurityManager() == null ||
                        cs.getClass().getClassLoader0() == null;
    ce.onMalformedInput(CodingErrorAction.REPLACE)
      .onUnmappableCharacter(CodingErrorAction.REPLACE)
      .reset();
    if (ce instanceof ArrayEncoder) {
        if (!isTrusted) {
            val = Arrays.copyOf(val, val.length);
        }
        int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
                                      : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
        if (blen != -1) {
            return safeTrim(ba, blen, isTrusted);
        }
    }
    char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
                                   : StringUTF16.toChars(val);
    ByteBuffer bb = ByteBuffer.wrap(ba);
    CharBuffer cb = CharBuffer.wrap(ca, 0, len);
    try {
        CoderResult cr = ce.encode(cb, bb, true);
        if (!cr.isUnderflow())
            cr.throwException();
        cr = ce.flush(bb);
        if (!cr.isUnderflow())
            cr.throwException();
    } catch (CharacterCodingException x) {
        throw new Error(x);
    }
    return safeTrim(ba, bb.position(), isTrusted);
}
 
Example 15
Source File: AbstractAdaptiveByteBuffer.java    From craft-atom with MIT License 4 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public String getString(CharsetDecoder decoder) throws CharacterCodingException {
    if (!hasRemaining()) {
        return "";
    }

    boolean utf16 = decoder.charset().name().startsWith("UTF-16");

    int oldPos = position();
    int oldLimit = limit();
    int end = -1;
    int newPos;

    if (!utf16) {
        end = indexOf((byte) 0x00);
        if (end < 0) {
            newPos = end = oldLimit;
        } else {
            newPos = end + 1;
        }
    } else {
        int i = oldPos;
        for (;;) {
            boolean wasZero = get(i) == 0;
            i++;

            if (i >= oldLimit) {
                break;
            }

            if (get(i) != 0) {
                i++;
                if (i >= oldLimit) {
                    break;
                }

                continue;
            }

            if (wasZero) {
                end = i - 1;
                break;
            }
        }

        if (end < 0) {
            newPos = end = oldPos + (oldLimit - oldPos & 0xFFFFFFFE);
        } else {
            if (end + 2 <= oldLimit) {
                newPos = end + 2;
            } else {
                newPos = end;
            }
        }
    }

    if (oldPos == end) {
        position(newPos);
        return "";
    }

    limit(end);
    decoder.reset();

    int expectedLength = (int) (remaining() * decoder.averageCharsPerByte()) + 1;
    CharBuffer out = CharBuffer.allocate(expectedLength);
    for (;;) {
        CoderResult cr;
        if (hasRemaining()) {
            cr = decoder.decode(buf(), out, true);
        } else {
            cr = decoder.flush(out);
        }

        if (cr.isUnderflow()) {
            break;
        }

        if (cr.isOverflow()) {
            CharBuffer o = CharBuffer.allocate(out.capacity() + expectedLength);
            out.flip();
            o.put(out);
            out = o;
            continue;
        }

        if (cr.isError()) {
            // Revert the buffer back to the previous state.
            limit(oldLimit);
            position(oldPos);
            cr.throwException();
        }
    }

    limit(oldLimit);
    position(newPos);
    return out.flip().toString();
}
 
Example 16
Source File: StringCoding.java    From jdk-1.7-annotated with Apache License 2.0 4 votes vote down vote up
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);
    }
}
 
Example 17
Source File: CharSequenceCustomEncodingBytesWriter.java    From Chronicle-Map with Apache License 2.0 4 votes vote down vote up
@Override
public void write(Bytes out, @NotNull CharSequence cs) {
    // Write the actual cs length for accurate StringBuilder.ensureCapacity() while reading
    out.writeStopBit(cs.length());
    long encodedSizePos = out.writePosition();
    out.writeSkip(4);
    charsetEncoder.reset();
    inputBuffer.clear();
    outputBuffer.clear();
    int csPos = 0;
    boolean endOfInput = false;
    // this loop inspired by the CharsetEncoder.encode(CharBuffer) implementation
    while (true) {
        if (!endOfInput) {
            int nextCsPos = Math.min(csPos + inputBuffer.remaining(), cs.length());
            append(inputBuffer, cs, csPos, nextCsPos);
            inputBuffer.flip();
            endOfInput = nextCsPos == cs.length();
            csPos = nextCsPos;
        }

        CoderResult cr = inputBuffer.hasRemaining() ?
                charsetEncoder.encode(inputBuffer, outputBuffer, endOfInput) :
                CoderResult.UNDERFLOW;

        if (cr.isUnderflow() && endOfInput)
            cr = charsetEncoder.flush(outputBuffer);

        if (cr.isUnderflow()) {
            if (endOfInput) {
                break;
            } else {
                inputBuffer.compact();
                continue;
            }
        }

        if (cr.isOverflow()) {
            outputBuffer.flip();
            writeOutputBuffer(out);
            outputBuffer.clear();
            continue;
        }

        try {
            cr.throwException();
        } catch (CharacterCodingException e) {
            throw new IORuntimeException(e);
        }
    }
    outputBuffer.flip();
    writeOutputBuffer(out);

    out.writeInt(encodedSizePos, (int) (out.writePosition() - encodedSizePos - 4));
}
 
Example 18
Source File: StringCoding.java    From jdk1.8-source-analysis with Apache License 2.0 4 votes vote down vote up
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);
    }
}
 
Example 19
Source File: ReaderInputStream.java    From codebuff with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public int read(byte[] b, int off, int len) throws IOException {
  // Obey InputStream contract.
  checkPositionIndexes(off, off + len, b.length);
  if (len == 0) {
    return 0;
  }

  // The rest of this method implements the process described by the CharsetEncoder javadoc.
  int totalBytesRead = 0;
  boolean doneEncoding = endOfInput;
  DRAINING:
  while (true) {
    // We stay in draining mode until there are no bytes left in the output buffer. Then we go
    // back to encoding/flushing.
    if (draining) {
      totalBytesRead += drain(b, off + totalBytesRead, len - totalBytesRead);
      if (totalBytesRead == len || doneFlushing) {
        return (totalBytesRead > 0) ? totalBytesRead : -1;
      }
      draining = false;
      byteBuffer.clear();
    }

    while (true) {
      // We call encode until there is no more input. The last call to encode will have endOfInput
      // == true. Then there is a final call to flush.
      CoderResult result;
      if (doneFlushing) {
        result = CoderResult.UNDERFLOW;
      } else if (doneEncoding) {
        result = encoder.flush(byteBuffer);
      } else {
        result = encoder.encode(charBuffer, byteBuffer, endOfInput);
      }
      if (result.isOverflow()) {
        // Not enough room in output buffer--drain it, creating a bigger buffer if necessary.
        startDraining(true);
        continue DRAINING;
      } else if (result.isUnderflow()) {
        // If encoder underflows, it means either:
        // a) the final flush() succeeded; next drain (then done)
        // b) we encoded all of the input; next flush
        // c) we ran of out input to encode; next read more input
        if (doneEncoding) { // (a)
          doneFlushing = true;
          startDraining(false);
          continue DRAINING;
        } else if (endOfInput) { // (b)
          doneEncoding = true;
        } else { // (c)
          readMoreChars();
        }
      } else if (result.isError()) {
        // Only reach here if a CharsetEncoder with non-REPLACE settings is used.
        result.throwException();
        return 0; // Not called.
      }
    }
  }
}
 
Example 20
Source File: B2CConverter.java    From Tomcat8-Source-Read with MIT License 4 votes vote down vote up
/**
 * Convert the given bytes to characters.
 *
 * @param bc byte input
 * @param cc char output
 * @param ic byte input channel
 * @param endOfInput    Is this all of the available data
 *
 * @throws IOException If the conversion can not be completed
 */
public void convert(ByteBuffer bc, CharBuffer cc, ByteChunk.ByteInputChannel ic, boolean endOfInput)
        throws IOException {
    if ((bb == null) || (bb.array() != bc.array())) {
        // Create a new byte buffer if anything changed
        bb = ByteBuffer.wrap(bc.array(), bc.arrayOffset() + bc.position(), bc.remaining());
    } else {
        // Initialize the byte buffer
        bb.limit(bc.limit());
        bb.position(bc.position());
    }
    if ((cb == null) || (cb.array() != cc.array())) {
        // Create a new char buffer if anything changed
        cb = CharBuffer.wrap(cc.array(), cc.limit(), cc.capacity() - cc.limit());
    } else {
        // Initialize the char buffer
        cb.limit(cc.capacity());
        cb.position(cc.limit());
    }
    CoderResult result = null;
    // Parse leftover if any are present
    if (leftovers.position() > 0) {
        int pos = cb.position();
        // Loop until one char is decoded or there is a decoder error
        do {
            byte chr;
            if (bc.remaining() == 0) {
                int n = ic.realReadBytes();
                chr = n < 0 ? -1 : bc.get();
            } else {
                chr = bc.get();
            }
            leftovers.put(chr);
            leftovers.flip();
            result = decoder.decode(leftovers, cb, endOfInput);
            leftovers.position(leftovers.limit());
            leftovers.limit(leftovers.array().length);
        } while (result.isUnderflow() && (cb.position() == pos));
        if (result.isError() || result.isMalformed()) {
            result.throwException();
        }
        bb.position(bc.position());
        leftovers.position(0);
    }
    // Do the decoding and get the results into the byte chunk and the char
    // chunk
    result = decoder.decode(bb, cb, endOfInput);
    if (result.isError() || result.isMalformed()) {
        result.throwException();
    } else if (result.isOverflow()) {
        // Propagate current positions to the byte chunk and char chunk, if
        // this continues the char buffer will get resized
        bc.position(bb.position());
        cc.limit(cb.position());
    } else if (result.isUnderflow()) {
        // Propagate current positions to the byte chunk and char chunk
        bc.position(bb.position());
        cc.limit(cb.position());
        // Put leftovers in the leftovers byte buffer
        if (bc.remaining() > 0) {
            leftovers.limit(leftovers.array().length);
            leftovers.position(bc.remaining());
            bc.get(leftovers.array(), 0, bc.remaining());
        }
    }
}