Java Code Examples for java.nio.CharBuffer#hasRemaining()

The following examples show how to use java.nio.CharBuffer#hasRemaining() . 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: DoubleByte.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
protected CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
    int mark = src.position();
    try {

        while (src.hasRemaining() && dst.hasRemaining()) {
            int b1 = src.get() & 0xff;
            char c = b2cSB[b1];
            int inSize = 1;
            if (c == UNMAPPABLE_DECODING) {
                if (src.remaining() < 1)
                    return crMalformedOrUnderFlow(b1);
                int b2 = src.get() & 0xff;
                if (b2 < b2Min || b2 > b2Max ||
                    (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING)
                    return crMalformedOrUnmappable(b1, b2);
                inSize++;
            }
            dst.put(c);
            mark += inSize;
        }
        return src.hasRemaining()? CoderResult.OVERFLOW
                                 : CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 2
Source File: DoubleByte.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 6 votes vote down vote up
protected CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
    int mark = src.position();
    try {

        while (src.hasRemaining() && dst.hasRemaining()) {
            int b1 = src.get() & 0xff;
            char c = b2cSB[b1];
            int inSize = 1;
            if (c == UNMAPPABLE_DECODING) {
                if (src.remaining() < 1)
                    return crMalformedOrUnderFlow(b1);
                int b2 = src.get() & 0xff;
                if (b2 < b2Min || b2 > b2Max ||
                    (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING)
                    return crMalformedOrUnmappable(b1, b2);
                inSize++;
            }
            dst.put(c);
            mark += inSize;
        }
        return src.hasRemaining()? CoderResult.OVERFLOW
                                 : CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 3
Source File: ISO_8859_1.java    From hottub with GNU General Public License v2.0 6 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src,
                                     ByteBuffer dst)
{
    int mark = src.position();
    try {
        while (src.hasRemaining()) {
            char c = src.get();
            if (c <= '\u00FF') {
                if (!dst.hasRemaining())
                    return CoderResult.OVERFLOW;
                dst.put((byte)c);
                mark++;
                continue;
            }
            if (sgp.parse(c, src) < 0)
                return sgp.error();
            return sgp.unmappableResult();
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 4
Source File: SingleByteDecoder.java    From shortyz with GNU General Public License v3.0 6 votes vote down vote up
private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
    int mark = src.position();
    try {
        while (src.hasRemaining()) {
            int b = src.get();

            char c = decode(b);
            if (c == '\uFFFD')
                return CoderResult.unmappableForLength(1);
            if (!dst.hasRemaining())
                return CoderResult.OVERFLOW;
            mark++;
            dst.put(c);
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 5
Source File: debug.java    From antsdb with GNU Lesser General Public License v3.0 5 votes vote down vote up
public static String dumpHex(CharBuffer buf) {
    StringBuilder s = new StringBuilder();
    buf = buf.duplicate();
    buf.position(0);
    for (int i=0; buf.hasRemaining(); i++) {
        char ch = buf.get();
        String hex = BytesUtil.toHex(ch);
        s.append(hex);
        s.append(' ');
        if ((i > 0) && (i % 8 == 0)) {
           buf.append("\n"); 
        }
    }
    return s.toString();
}
 
Example 6
Source File: UsingBuffers.java    From LearningOfThinkInJava with Apache License 2.0 5 votes vote down vote up
private static void symmetricScramble(CharBuffer buffer){
    while (buffer.hasRemaining()){
        buffer.mark();
        char c1=buffer.get();
        char c2=buffer.get();
        buffer.reset();
        buffer.put(c2).put(c1);
    }
}
 
Example 7
Source File: Chars.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Sums the remaining chars in the char buffer.
 */
static int intSum(CharBuffer cb) {
    int sum = 0;
    cb.mark();
    while (cb.hasRemaining()) {
        sum += cb.get();
    }
    cb.reset();
    return sum;
}
 
Example 8
Source File: Chars.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Sums the remaining chars in the char buffer.
 */
static int intSum(CharBuffer cb) {
    int sum = 0;
    cb.mark();
    while (cb.hasRemaining()) {
        sum += cb.get();
    }
    cb.reset();
    return sum;
}
 
Example 9
Source File: HKSCS.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
protected CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
    int mark = src.position();
    try {
        while (src.hasRemaining()) {
            int inSize = 1;
            char c = src.get();
            int bb = encodeChar(c);
            if (bb == UNMAPPABLE_ENCODING) {
                if (Character.isSurrogate(c)) {
                    int cp;
                    if ((cp = sgp().parse(c, src)) < 0)
                        return sgp.error();
                    bb = encodeSupp(cp);
                    if (bb == UNMAPPABLE_ENCODING)
                        return CoderResult.unmappableForLength(2);
                    inSize = 2;
                } else {
                    return CoderResult.unmappableForLength(1);
                }
            }
            if (bb > MAX_SINGLEBYTE) {  // DoubleByte
                if (dst.remaining() < 2)
                    return CoderResult.OVERFLOW;
                dst.put((byte)(bb >> 8));
                dst.put((byte)(bb));
            } else {
                if (dst.remaining() < 1)
                return CoderResult.OVERFLOW;
                dst.put((byte)bb);
            }
            mark += inSize;
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 10
Source File: PerforceShiftJISCharset.java    From p4ic4idea with Apache License 2.0 5 votes vote down vote up
/**
 * Implementation of the encoding loop. Apply Perforce specific updates,
 * then reset the encoder and encode the characters to bytes.
 */
protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb) {
	CharBuffer tmpcb = CharBuffer.allocate(cb.remaining());
	while (cb.hasRemaining()) {
		tmpcb.put(cb.get());
	}
	tmpcb.rewind();
	update(tmpcb);
	encoder.reset();
	CoderResult cr = encoder.encode(tmpcb, bb, true);
	cb.position(cb.position() - tmpcb.remaining());
	return (cr);
}
 
Example 11
Source File: UTF_32Coder.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
    int mark = src.position();
    if (!doneBOM && src.hasRemaining()) {
        if (dst.remaining() < 4)
            return CoderResult.OVERFLOW;
        put(BOM_BIG, dst);
        doneBOM = true;
    }
    try {
        while (src.hasRemaining()) {
            char c = src.get();
            if (!Character.isSurrogate(c)) {
                if (dst.remaining() < 4)
                    return CoderResult.OVERFLOW;
                mark++;
                put(c, dst);
            } else if (Character.isHighSurrogate(c)) {
                if (!src.hasRemaining())
                    return CoderResult.UNDERFLOW;
                char low = src.get();
                if (Character.isLowSurrogate(low)) {
                    if (dst.remaining() < 4)
                        return CoderResult.OVERFLOW;
                    mark += 2;
                    put(Character.toCodePoint(c, low), dst);
                } else {
                    return CoderResult.malformedForLength(1);
                }
            } else {
                // assert Character.isLowSurrogate(c);
                return CoderResult.malformedForLength(1);
            }
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 12
Source File: Chars.java    From jdk8u-dev-jdk with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Randomize the char buffer's contents, position and limit.
 */
static CharBuffer randomize(CharBuffer cb) {
    while (cb.hasRemaining()) {
        cb.put((char)RAND.nextInt());
    }
    return randomizeRange(cb);
}
 
Example 13
Source File: DoubleByteEncoder.java    From dragonwell8_jdk with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
    int mark = src.position();

    try {
        while (src.hasRemaining()) {
            char c = src.get();
            if (Character.isSurrogate(c)) {
                int surr;
                if ((surr = sgp.parse(c, src)) < 0)
                    return sgp.error();
                char c2 = Surrogate.low(surr);
                byte[] outputBytes = new byte[2];
                outputBytes = encodeSurrogate(c, c2);

                if (outputBytes == null) {
                    return sgp.unmappableResult();
                } else {
                    if (dst.remaining() < 2)
                        return CoderResult.OVERFLOW;
                    mark += 2;
                    dst.put(outputBytes[0]);
                    dst.put(outputBytes[1]);
                    continue;
                }
            }
            if (c >= '\uFFFE')
                return CoderResult.unmappableForLength(1);
            int b = encodeSingle(c);

            if (b != -1) { // Single-byte character
                if (dst.remaining() < 1)
                    return CoderResult.OVERFLOW;
                mark++;
                dst.put((byte)b);
                continue;
            }
            // Double Byte character

            int ncode = encodeDouble(c);
            if (ncode != 0 && c != '\u0000') {
                if (dst.remaining() < 2)
                    return CoderResult.OVERFLOW;
                mark++;
                dst.put((byte) ((ncode & 0xff00) >> 8));
                dst.put((byte) ncode);
                continue;
            }
            return CoderResult.unmappableForLength(1);
        }

        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 14
Source File: ISO2022.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src,
                                     ByteBuffer dst)
{
    int outputSize = 0;
    byte[]  outputByte = new byte[8];
    int     inputSize = 0;                 // Size of input
    newshiftout = shiftout;
    newSODesDefined = SODesDefined;
    newSS2DesDefined = SS2DesDefined;
    newSS3DesDefined = SS3DesDefined;
    int mark = src.position();

    try {
        while (src.hasRemaining()) {
            char inputChar = src.get();
            if (Character.isSurrogate(inputChar)) {
                if (sgp.parse(inputChar, src) < 0)
                    return sgp.error();
                return sgp.unmappableResult();
            }
            if (inputChar < 0x80) {     // ASCII
                if (shiftout){
                    newshiftout = false;
                    outputSize = 2;
                    outputByte[0] = ISO_SI;
                    outputByte[1] = (byte)(inputChar & 0x7f);
                } else {
                    outputSize = 1;
                    outputByte[0] = (byte)(inputChar & 0x7f);
                }
                if(inputChar == '\n'){
                    newSODesDefined = false;
                    newSS2DesDefined = false;
                    newSS3DesDefined = false;
                }
            } else {
                outputSize = unicodeToNative(inputChar, outputByte);
                if (outputSize == 0) {
                    return CoderResult.unmappableForLength(1);
                }
            }

            if (dst.remaining() < outputSize)
                return CoderResult.OVERFLOW;
            for (int i = 0; i < outputSize; i++)
                dst.put(outputByte[i]);
            mark++;
            shiftout = newshiftout;
            SODesDefined = newSODesDefined;
            SS2DesDefined = newSS2DesDefined;
            SS3DesDefined = newSS3DesDefined;
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 15
Source File: JISAutoDetect.java    From openjdk-jdk9 with GNU General Public License v2.0 4 votes vote down vote up
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
    if (detectedDecoder == null) {
        copyLeadingASCII(src, dst);

        // All ASCII?
        if (! src.hasRemaining())
            return CoderResult.UNDERFLOW;
        // Overflow only if there is still ascii but no out buffer.
        if (!dst.hasRemaining() &&
            isPlainASCII(src.get(src.position())))
            return CoderResult.OVERFLOW;

        // We need to perform double, not float, arithmetic; otherwise
        // we lose low order bits when src is larger than 2**24.
        int cbufsiz = (int)(src.limit() * (double)maxCharsPerByte());
        CharBuffer sandbox = CharBuffer.allocate(cbufsiz);

        // First try ISO-2022-JP, since there is no ambiguity
        Charset cs2022 = Charset.forName("ISO-2022-JP");
        DelegatableDecoder dd2022
            = (DelegatableDecoder) cs2022.newDecoder();
        ByteBuffer src2022 = src.asReadOnlyBuffer();
        CoderResult res2022 = dd2022.decodeLoop(src2022, sandbox);
        if (! res2022.isError())
            return decodeLoop(dd2022, src, dst);

        // We must choose between EUC and SJIS
        Charset csEUCJ = Charset.forName(EUCJPName);
        Charset csSJIS = Charset.forName(SJISName);

        DelegatableDecoder ddEUCJ
            = (DelegatableDecoder) csEUCJ.newDecoder();
        DelegatableDecoder ddSJIS
            = (DelegatableDecoder) csSJIS.newDecoder();

        ByteBuffer srcEUCJ = src.asReadOnlyBuffer();
        sandbox.clear();
        CoderResult resEUCJ = ddEUCJ.decodeLoop(srcEUCJ, sandbox);
        // If EUC decoding fails, must be SJIS
        if (resEUCJ.isError())
            return decodeLoop(ddSJIS, src, dst);
        ByteBuffer srcSJIS = src.asReadOnlyBuffer();
        CharBuffer sandboxSJIS = CharBuffer.allocate(cbufsiz);
        CoderResult resSJIS = ddSJIS.decodeLoop(srcSJIS, sandboxSJIS);
        // If SJIS decoding fails, must be EUC
        if (resSJIS.isError())
            return decodeLoop(ddEUCJ, src, dst);

        // From here on, we have some ambiguity, and must guess.

        // We prefer input that does not appear to end mid-character.
        if (srcEUCJ.position() > srcSJIS.position())
            return decodeLoop(ddEUCJ, src, dst);

        if (srcEUCJ.position() < srcSJIS.position())
            return decodeLoop(ddSJIS, src, dst);

        // end-of-input is after the first byte of the first char?
        if (src.position() == srcEUCJ.position())
            return CoderResult.UNDERFLOW;

        // Use heuristic knowledge of typical Japanese text
        sandbox.flip();
        return decodeLoop(looksLikeJapanese(sandbox) ? ddEUCJ : ddSJIS,
                          src, dst);
    }

    return detectedDecoder.decodeLoop(src, dst);
}
 
Example 16
Source File: SimpleEUCDecoder.java    From jdk8u-jdk with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
    int mark = src.position();

    try {
        while (src.hasRemaining()) {
            char outputChar = '\uFFFD';
            int inputSize = 1;
            int byte1, byte2;

            byte1 = src.get() & 0xff;
            if ( byte1 <= 0x9f ) {
                if (byte1 == SS2 || byte1 == SS3 ) {
                    return CoderResult.malformedForLength(1);
                }
                outputChar = byteToCharTable.charAt(byte1);
            } else if (byte1 < 0xa1 || byte1 > 0xfe) {
                return CoderResult.malformedForLength(1);
            } else {
                if (!src.hasRemaining()) {
                    return CoderResult.UNDERFLOW;
                }
                byte2 = src.get() & 0xff;
                inputSize++;
                if ( byte2 < 0xa1 || byte2 > 0xfe) {
                    return CoderResult.malformedForLength(2);
                }
                outputChar = mappingTableG1.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1);
            }
            if (outputChar == '\uFFFD') {
                return CoderResult.unmappableForLength(inputSize);
            }
            if (!dst.hasRemaining())
                return CoderResult.OVERFLOW;
                dst.put(outputChar);
            mark += inputSize;
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 17
Source File: EUC_JP.java    From jdk8u60 with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src,
                                     ByteBuffer dst)
{
    int outputSize = 0;
    byte[]  outputByte;
    int     inputSize = 0;                 // Size of input
    byte[]  tmpBuf = new byte[3];

    int mark = src.position();

    try {
        while (src.hasRemaining()) {
            outputByte = tmpBuf;
            char c = src.get();
            if (Character.isSurrogate(c)) {
                if (sgp.parse(c, src) < 0)
                    return sgp.error();
                return sgp.unmappableResult();
            }
            outputSize = encodeSingle(c, outputByte);
            if (outputSize == 0) { // DoubleByte
                int ncode = encodeDouble(c);
                if (ncode != UNMAPPABLE_ENCODING) {
                    if ((ncode & 0xFF0000) == 0) {
                        outputByte[0] = (byte) ((ncode & 0xff00) >> 8);
                        outputByte[1] = (byte) (ncode & 0xff);
                        outputSize = 2;
                    } else {
                        outputByte[0] = (byte) 0x8f;
                        outputByte[1] = (byte) ((ncode & 0xff00) >> 8);
                        outputByte[2] = (byte) (ncode & 0xff);
                        outputSize = 3;
                    }
                } else {
                    return CoderResult.unmappableForLength(1);
                }
            }
            if (dst.remaining() < outputSize)
                return CoderResult.OVERFLOW;
            // Put the byte in the output buffer
            for (int i = 0; i < outputSize; i++) {
                dst.put(outputByte[i]);
            }
            mark++;
        }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 18
Source File: DoubleByteEncoder.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
    int mark = src.position();

    try {
        while (src.hasRemaining()) {
            char c = src.get();
            if (Character.isSurrogate(c)) {
                int surr;
                if ((surr = sgp.parse(c, src)) < 0)
                    return sgp.error();
                char c2 = Surrogate.low(surr);
                byte[] outputBytes = new byte[2];
                outputBytes = encodeSurrogate(c, c2);

                if (outputBytes == null) {
                    return sgp.unmappableResult();
                } else {
                    if (dst.remaining() < 2)
                        return CoderResult.OVERFLOW;
                    mark += 2;
                    dst.put(outputBytes[0]);
                    dst.put(outputBytes[1]);
                    continue;
                }
            }
            if (c >= '\uFFFE')
                return CoderResult.unmappableForLength(1);
            int b = encodeSingle(c);

            if (b != -1) { // Single-byte character
                if (dst.remaining() < 1)
                    return CoderResult.OVERFLOW;
                mark++;
                dst.put((byte)b);
                continue;
            }
            // Double Byte character

            int ncode = encodeDouble(c);
            if (ncode != 0 && c != '\u0000') {
                if (dst.remaining() < 2)
                    return CoderResult.OVERFLOW;
                mark++;
                dst.put((byte) ((ncode & 0xff00) >> 8));
                dst.put((byte) ncode);
                continue;
            }
            return CoderResult.unmappableForLength(1);
        }

        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 19
Source File: DBCS_IBM_EBCDIC_Encoder.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
    int mark = src.position();
    int outputSize = 0;             // size of output
    int spaceNeeded;

    try {
        while (src.hasRemaining()) {
            int index;
            int theBytes;
            char c = src.get();
            if (Surrogate.is(c)) {
                if (sgp.parse(c, src) < 0)
                    return sgp.error();
                return sgp.unmappableResult();
            }
            if (c >= '\uFFFE')
                return CoderResult.unmappableForLength(1);

            index = index1[((c & mask1) >> shift)]
                            + (c & mask2);
            if (index < 15000)
                theBytes = (int)(index2.charAt(index));
            else
                theBytes = (int)(index2a.charAt(index-15000));
            b1 = (byte)((theBytes & 0x0000ff00)>>8);
            b2 = (byte)(theBytes & 0x000000ff);

            if (b1== 0x00 && b2 == 0x00
                && c != '\u0000') {
                    return CoderResult.unmappableForLength(1);
            }

            if (currentState == DBCS && b1 == 0x00) {
                if (dst.remaining() < 1)
                    return CoderResult.OVERFLOW;
                currentState = SBCS;
                dst.put(SI);
            } else if (currentState == SBCS && b1 != 0x00) {
                if (dst.remaining() < 1)
                    return CoderResult.OVERFLOW;
                currentState = DBCS;
                dst.put(SO);
            }

            if (currentState == DBCS)
                spaceNeeded = 2;
            else
                spaceNeeded = 1;

            if (dst.remaining() < spaceNeeded)
                return CoderResult.OVERFLOW;

            if (currentState == SBCS)
                dst.put(b2);
            else {
                dst.put(b1);
                dst.put(b2);
            }
            mark++;
         }
        return CoderResult.UNDERFLOW;
    } finally {
        src.position(mark);
    }
}
 
Example 20
Source File: JISAutoDetect.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
    if (detectedDecoder == null) {
        copyLeadingASCII(src, dst);

        // All ASCII?
        if (! src.hasRemaining())
            return CoderResult.UNDERFLOW;
        if (! dst.hasRemaining())
            return CoderResult.OVERFLOW;

        // We need to perform double, not float, arithmetic; otherwise
        // we lose low order bits when src is larger than 2**24.
        int cbufsiz = (int)(src.limit() * (double)maxCharsPerByte());
        CharBuffer sandbox = CharBuffer.allocate(cbufsiz);

        // First try ISO-2022-JP, since there is no ambiguity
        Charset cs2022 = Charset.forName("ISO-2022-JP");
        DelegatableDecoder dd2022
            = (DelegatableDecoder) cs2022.newDecoder();
        ByteBuffer src2022 = src.asReadOnlyBuffer();
        CoderResult res2022 = dd2022.decodeLoop(src2022, sandbox);
        if (! res2022.isError())
            return decodeLoop(cs2022, src, dst);

        // We must choose between EUC and SJIS
        Charset csEUCJ = Charset.forName(EUCJPName);
        Charset csSJIS = Charset.forName(SJISName);

        DelegatableDecoder ddEUCJ
            = (DelegatableDecoder) csEUCJ.newDecoder();
        ByteBuffer srcEUCJ = src.asReadOnlyBuffer();
        sandbox.clear();
        CoderResult resEUCJ = ddEUCJ.decodeLoop(srcEUCJ, sandbox);
        // If EUC decoding fails, must be SJIS
        if (resEUCJ.isError())
            return decodeLoop(csSJIS, src, dst);

        DelegatableDecoder ddSJIS
            = (DelegatableDecoder) csSJIS.newDecoder();
        ByteBuffer srcSJIS = src.asReadOnlyBuffer();
        CharBuffer sandboxSJIS = CharBuffer.allocate(cbufsiz);
        CoderResult resSJIS = ddSJIS.decodeLoop(srcSJIS, sandboxSJIS);
        // If SJIS decoding fails, must be EUC
        if (resSJIS.isError())
            return decodeLoop(csEUCJ, src, dst);

        // From here on, we have some ambiguity, and must guess.

        // We prefer input that does not appear to end mid-character.
        if (srcEUCJ.position() > srcSJIS.position())
            return decodeLoop(csEUCJ, src, dst);

        if (srcEUCJ.position() < srcSJIS.position())
            return decodeLoop(csSJIS, src, dst);

        // end-of-input is after the first byte of the first char?
        if (src.position() == srcEUCJ.position())
            return CoderResult.UNDERFLOW;

        // Use heuristic knowledge of typical Japanese text
        sandbox.flip();
        Charset guess = looksLikeJapanese(sandbox) ? csEUCJ : csSJIS;
        return decodeLoop(guess, src, dst);
    }

    return detectedDecoder.decodeLoop(src, dst);
}