Index: modules/luni/src/main/java/java/io/InputStreamReader.java =================================================================== --- modules/luni/src/main/java/java/io/InputStreamReader.java (revision 547139) +++ modules/luni/src/main/java/java/io/InputStreamReader.java (working copy) @@ -70,6 +70,7 @@ decoder = Charset.forName(encoding).newDecoder().onMalformedInput( CodingErrorAction.REPLACE).onUnmappableCharacter( CodingErrorAction.REPLACE); + bytes.limit(0); } /** @@ -101,6 +102,7 @@ } catch (IllegalArgumentException e) { throw new UnsupportedEncodingException(); } + bytes.limit(0); } /** @@ -118,6 +120,7 @@ dec.averageCharsPerByte(); this.in = in; decoder = dec; + bytes.limit(0); } /** @@ -136,6 +139,7 @@ decoder = charset.newDecoder().onMalformedInput( CodingErrorAction.REPLACE).onUnmappableCharacter( CodingErrorAction.REPLACE); + bytes.limit(0); } /** @@ -385,67 +389,47 @@ if (length == 0) { return 0; } - - // allocate enough space for bytes if the default length is - // inadequate - int availableLen = in.available(); - if (Math.min(availableLen, length) > bytes.capacity()) { - bytes = ByteBuffer.allocate(availableLen); - } - + CharBuffer out = CharBuffer.wrap(buf, offset, length); CoderResult result = CoderResult.UNDERFLOW; byte[] a = bytes.array(); - boolean has_been_read = false; - if (!bytes.hasRemaining() || bytes.limit() == bytes.capacity()) { - // Nothing is available in the buffer... - if (!bytes.hasRemaining()) { - bytes.clear(); - } - int readed = in.read(a, bytes.arrayOffset(), bytes.remaining()); - if (readed == -1) { - endOfInput = true; - return -1; - } - bytes.limit(readed); - has_been_read = true; - } + // bytes.remaining() indicates number of bytes in buffer + // when 1-st time entered, it'll be equal to zero + boolean needInput = !bytes.hasRemaining(); while (out.hasRemaining()) { - if (bytes.hasRemaining()) { - result = decoder.decode(bytes, out, false); - if (!bytes.hasRemaining() && endOfInput) { - decoder.decode(bytes, out, true); - decoder.flush(out); - decoder.reset(); + // fill the buffer if needed + if (needInput) { + if((in.available() == 0) && (out.position() > offset)) { + // we could return the result without blocking read break; } - if (!out.hasRemaining() - || bytes.position() == bytes.limit()) { - bytes.compact(); - } - } - if (in.available() > 0 - && (!has_been_read && out.hasRemaining()) - || out.position() == 0) { - bytes.compact(); - int to_read = bytes.remaining(); - int off = bytes.arrayOffset() + bytes.position(); - + int to_read = bytes.capacity() - bytes.limit(); + int off = bytes.arrayOffset() + bytes.limit(); to_read = in.read(a, off, to_read); + if (to_read == -1) { - if (bytes.hasRemaining()) { - bytes.flip(); - } endOfInput = true; break; + } else if (to_read == 0) { + break; } - has_been_read = true; - if (to_read > 0) { - bytes.limit(bytes.position() + to_read); + bytes.limit(bytes.limit() + to_read); + needInput = false; + } + + // decode bytes + result = decoder.decode(bytes, out, false); + + if (result.isUnderflow()) { + // compact the buffer if no space left + if (bytes.limit() == bytes.capacity()) { + bytes.compact(); + bytes.limit(bytes.position()); bytes.position(0); } + needInput = true; } else { break; } @@ -453,10 +437,7 @@ if (result == CoderResult.UNDERFLOW && endOfInput) { result = decoder.decode(bytes, out, true); - // FIXME: should flush at first, but seems ICU has a bug that it - // will throw IAE if some malform/unmappable bytes found during - // decoding - // result = decoder.flush(chars); + decoder.flush(out); decoder.reset(); } if (result.isMalformed()) { @@ -464,9 +445,6 @@ } else if (result.isUnmappable()) { throw new UnmappableCharacterException(result.length()); } - if (result == CoderResult.OVERFLOW && bytes.position() != 0) { - bytes.flip(); - } return out.position() - offset == 0 ? -1 : out.position() - offset; } @@ -505,7 +483,7 @@ throw new IOException(Msg.getString("K0070")); //$NON-NLS-1$ } try { - return bytes.limit() != bytes.capacity() || in.available() > 0; + return bytes.hasRemaining() || in.available() > 0; } catch (IOException e) { return false; } Index: modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java =================================================================== --- modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java (revision 546816) +++ modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java (working copy) @@ -141,7 +141,7 @@ in.position(x); out.position(outPos); return CoderResult.unmappableForLength(1); } - if (limit - pos < 1 + tail) { + if (limit - x < 1 + tail) { in.position(x); out.position(outPos); return CoderResult.UNDERFLOW; }