Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(95)

Unified Diff: main/classes/core/src/com/ibm/icu/impl/ICUBinary.java

Issue 155570043: ICU ticket #11341: getByteBufferFromInputStream() can be very inefficient (Closed) Base URL: http://source.icu-project.org/repos/icu/icu4j/trunk
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: main/classes/core/src/com/ibm/icu/impl/ICUBinary.java
===================================================================
--- main/classes/core/src/com/ibm/icu/impl/ICUBinary.java (revision 36665)
+++ main/classes/core/src/com/ibm/icu/impl/ICUBinary.java (working copy)
@@ -519,32 +519,52 @@
*/
public static ByteBuffer getByteBufferFromInputStream(InputStream is) throws IOException {
try {
+ // is.available() may return 0, or 1, or the total number of bytes in the stream,
+ // or some other number.
+ // Do not try to use is.available() == 0 to find the end of the stream!
+ byte[] bytes;
int avail = is.available();
- byte[] bytes = new byte[avail];
- readFully(is, bytes, 0, avail);
- while((avail = is.available()) != 0) {
- // TODO Java 6 replace new byte[] and arraycopy(): byte[] newBytes = Arrays.copyOf(bytes, bytes.length + avail);
- byte[] newBytes = new byte[bytes.length + avail];
- System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
- readFully(is, newBytes, bytes.length, avail);
- bytes = newBytes;
+ if (avail > 32) {
+ // There are more bytes available than just the ICU data header length.
+ // With luck, it is the total number of bytes.
+ bytes = new byte[avail];
+ } else {
+ bytes = new byte[128]; // empty .res files are even smaller
}
- return ByteBuffer.wrap(bytes);
+ // Call is.read(...) until one returns a negative value.
+ int length = 0;
+ for(;;) {
+ if (length < bytes.length) {
+ int numRead = is.read(bytes, length, bytes.length - length);
+ if (numRead < 0) {
+ break; // end of stream
+ }
+ length += numRead;
+ } else {
+ // See if we are at the end of the stream before we grow the array.
+ int nextByte = is.read();
+ if (nextByte < 0) {
+ break;
+ }
+ int capacity = 2 * bytes.length;
+ if (capacity < 128) {
+ capacity = 128;
+ } else if (capacity < 0x4000) {
+ capacity *= 2; // Grow faster until we reach 16kB.
+ }
+ // TODO Java 6 replace new byte[] and arraycopy(): bytes = Arrays.copyOf(bytes, capacity);
+ byte[] newBytes = new byte[capacity];
+ System.arraycopy(bytes, 0, newBytes, 0, length);
+ bytes = newBytes;
+ bytes[length++] = (byte) nextByte;
+ }
+ }
+ return ByteBuffer.wrap(bytes, 0, length);
} finally {
is.close();
}
}
- private static void readFully(InputStream is, byte[] bytes, int offset, int avail)
- throws IOException {
- while (avail > 0) {
- int numRead = is.read(bytes, offset, avail);
- assert numRead > 0;
- offset += numRead;
- avail -= numRead;
- }
- }
-
/**
* Returns a VersionInfo for the bytes in the compact version integer.
*/
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b