Skip to content

Commit

Permalink
Use Java 11 InputStream::readAllBytes to read String entities
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <[email protected]>
  • Loading branch information
jansupol authored and senivam committed Dec 5, 2022
1 parent b13c518 commit 8a484d2
Showing 1 changed file with 72 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -19,13 +19,15 @@
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -134,7 +136,7 @@ public static Charset getCharset(MediaType m) {
* @throws IOException if there is an error reading from the input stream.
*/
public static String readFromAsString(InputStream in, MediaType type) throws IOException {
return readFromAsString(new InputStreamReader(in, getCharset(type)));
return new String(readAllBytes(in), getCharset(type));
}

/**
Expand All @@ -154,6 +156,73 @@ public static String readFromAsString(Reader reader) throws IOException {
}
return sb.toString();
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;

/**
* Java 9+ InputStream::readAllBytes
* TODO Replace when Java 8 not any longer supported (3.1+)
*/
private static byte[] readAllBytes(InputStream inputStream) throws IOException {
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = Integer.MAX_VALUE;
int n;
do {
byte[] buf = new byte[Math.min(remaining, BUFFER_SIZE)];
int nread = 0;

// read to EOF which may read more or less than buffer size
while ((n = inputStream.read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
}

if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
// if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);

if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ? result : Arrays.copyOf(result, total);
}

result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}

return result;
}

/**
* Convert a string to bytes and write those bytes to an output stream.
Expand Down

0 comments on commit 8a484d2

Please sign in to comment.