-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #304 from LossyDragon/binary-reader-fix
Add compat methods for ByteArrayOutputStream and InputStream
- Loading branch information
Showing
12 changed files
with
377 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/main/java/in/dragonbra/javasteam/util/compat/ByteArrayOutputStreamCompat.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package `in`.dragonbra.javasteam.util.compat | ||
|
||
import java.io.ByteArrayOutputStream | ||
|
||
/** | ||
* Compatibility class to provide compatibility with Java ByteArrayOutputStream. | ||
*/ | ||
object ByteArrayOutputStreamCompat { | ||
|
||
@JvmStatic | ||
fun toString(byteArrayOutputStream: ByteArrayOutputStream): String = | ||
String(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size()) | ||
} |
92 changes: 92 additions & 0 deletions
92
src/main/java/in/dragonbra/javasteam/util/compat/InputStreamCompat.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package `in`.dragonbra.javasteam.util.compat | ||
|
||
import java.io.IOException | ||
import java.io.InputStream | ||
import java.util.Objects | ||
import kotlin.jvm.Throws | ||
import kotlin.math.min | ||
|
||
/** | ||
* Compatibility (extension) functions for [InputStream.readNBytes]. | ||
* These are basically the same from InputStream. | ||
*/ | ||
|
||
@Throws(IOException::class) | ||
fun InputStream.readNBytesCompat(b: ByteArray, off: Int, len: Int): Int { | ||
Objects.checkFromIndexSize(off, len, b.size) | ||
|
||
var n = 0 | ||
|
||
while (n < len) { | ||
val count = read(b, off + n, len - n) | ||
if (count < 0) { | ||
break | ||
} | ||
n += count | ||
} | ||
|
||
return n | ||
} | ||
|
||
@Suppress("RedundantExplicitType") | ||
@Throws(IOException::class) | ||
fun InputStream.readNBytesCompat(len: Int): ByteArray { | ||
if (len < 0) { | ||
throw IllegalArgumentException("len < 0") | ||
} | ||
|
||
var bufs: MutableList<ByteArray>? = null | ||
var result: ByteArray? = null | ||
var total: Int = 0 | ||
var remaining: Int = len | ||
var n: Int | ||
|
||
do { | ||
var buf = ByteArray(min(remaining, 8192)) | ||
var nread = 0 | ||
|
||
// read to EOF which may read more or less than buffer size | ||
while (read(buf, nread, minOf(buf.size - nread, remaining)).also { n = it } > 0) { | ||
nread += n | ||
remaining -= n | ||
} | ||
|
||
if (nread > 0) { | ||
if ((Integer.MAX_VALUE - 8) - total < nread) { | ||
throw OutOfMemoryError("Required array size too large") | ||
} | ||
total += nread | ||
if (result == null) { | ||
result = buf | ||
} else { | ||
if (bufs == null) { | ||
bufs = arrayListOf() | ||
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 ByteArray(0) | ||
} | ||
return if (result.size == total) result else result.copyOf(total) | ||
} | ||
|
||
result = ByteArray(total) | ||
var offset = 0 | ||
remaining = total | ||
|
||
bufs.forEach { b -> | ||
var count = min(b.size, remaining) | ||
System.arraycopy(b, 0, result, offset, count) | ||
offset += count | ||
remaining -= count | ||
} | ||
|
||
return result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
src/test/java/in/dragonbra/javasteam/util/compat/ByteArrayOutputStreamCompatTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package in.dragonbra.javasteam.util.compat; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
public class ByteArrayOutputStreamCompatTest { | ||
|
||
@Test | ||
public void testEmptyStream() { | ||
var baos = new ByteArrayOutputStream(); | ||
|
||
var compatResult = ByteArrayOutputStreamCompat.toString(baos); | ||
var standardResult = baos.toString(); | ||
|
||
Assertions.assertEquals("", compatResult); | ||
Assertions.assertEquals("", standardResult); | ||
Assertions.assertEquals(standardResult, compatResult); | ||
} | ||
|
||
@Test | ||
public void testAsciiContent() { | ||
var baos = new ByteArrayOutputStream(); | ||
var testString = "Hello, World!"; | ||
|
||
baos.write(testString.getBytes(StandardCharsets.UTF_8), 0, testString.length()); | ||
|
||
var compatResult = ByteArrayOutputStreamCompat.toString(baos); | ||
var standardResult = baos.toString(); | ||
|
||
Assertions.assertEquals(testString, compatResult); | ||
Assertions.assertEquals(testString, standardResult); | ||
Assertions.assertEquals(standardResult, compatResult); | ||
} | ||
|
||
@Test | ||
public void testUnicodeContent() { | ||
var baos = new ByteArrayOutputStream(); | ||
var testString = "Hello, 世界! 👋"; | ||
var bytes = testString.getBytes(StandardCharsets.UTF_8); | ||
|
||
baos.write(bytes, 0, bytes.length); | ||
|
||
var compatResult = ByteArrayOutputStreamCompat.toString(baos); | ||
var standardResult = baos.toString(); | ||
|
||
Assertions.assertEquals(testString, compatResult); | ||
Assertions.assertEquals(testString, standardResult); | ||
Assertions.assertEquals(standardResult, compatResult); | ||
} | ||
|
||
@Test | ||
public void testLargeContent() { | ||
var baos = new ByteArrayOutputStream(); | ||
var largeString = new StringBuilder(); | ||
for (int i = 0; i < 1000; i++) { | ||
largeString.append("Line ").append(i).append("\n"); | ||
} | ||
var testString = largeString.toString(); | ||
var bytes = testString.getBytes(StandardCharsets.UTF_8); | ||
baos.write(bytes, 0, bytes.length); | ||
|
||
var compatResult = ByteArrayOutputStreamCompat.toString(baos); | ||
var standardResult = baos.toString(); | ||
|
||
Assertions.assertEquals(testString, compatResult); | ||
Assertions.assertEquals(testString, standardResult); | ||
Assertions.assertEquals(standardResult, compatResult); | ||
} | ||
|
||
@Test | ||
public void testPartialWrites() { | ||
var baos = new ByteArrayOutputStream(); | ||
var part1 = "Hello"; | ||
var part2 = ", "; | ||
var part3 = "World!"; | ||
|
||
baos.write(part1.getBytes(StandardCharsets.UTF_8), 0, part1.length()); | ||
baos.write(part2.getBytes(StandardCharsets.UTF_8), 0, part2.length()); | ||
baos.write(part3.getBytes(StandardCharsets.UTF_8), 0, part3.length()); | ||
|
||
var expected = part1 + part2 + part3; | ||
var compatResult = ByteArrayOutputStreamCompat.toString(baos); | ||
var standardResult = baos.toString(); | ||
|
||
Assertions.assertEquals(expected, compatResult); | ||
Assertions.assertEquals(expected, standardResult); | ||
Assertions.assertEquals(standardResult, compatResult); | ||
} | ||
|
||
} |
Oops, something went wrong.