aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-05-04 01:04:53 +0200
committerSven Gothel <[email protected]>2023-05-04 01:04:53 +0200
commitb32e378ec80488c5ffbd0d9bb356217e6db0245f (patch)
tree1eae94088800a2eb7924822cf7d23561a403357e /src
parent6e67a7b54af82aa4e4ec28f50ff08a26f9d80627 (diff)
IOUtil.copyStreamChunk2ByteBuffer(..): Added new method to copy a chunk (segment) of the input stream (skipBytes, byteCount)
This method is inspired by Bug 1280, <https://github.com/sgothel/joal/pull/16>, 'copy only needed bytes' for JOAL's com.jogamp.openal.util.WAVData.loadFromStream(..). This method is a revised version of the proposed IOHelpers.copyFromStream2ByteBuffer(..), see <https://github.com/OndrejSpanel/joal/commit/1616659e98904270af4faca25b770d0983609735>
Diffstat (limited to 'src')
-rw-r--r--src/java/com/jogamp/common/util/IOUtil.java33
-rw-r--r--src/junit/com/jogamp/common/util/TestIOUtil01.java112
2 files changed, 145 insertions, 0 deletions
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java
index 499fa1b..e68c3b3 100644
--- a/src/java/com/jogamp/common/util/IOUtil.java
+++ b/src/java/com/jogamp/common/util/IOUtil.java
@@ -337,6 +337,39 @@ public class IOUtil {
return data;
}
+ /**
+ * Copy the specified input stream chunk to a NIO ByteBuffer w/ native byte order, which is being returned.
+ *
+ * @param stream input stream, which will be wrapped into a BufferedInputStream, if not already done.
+ * @param skipBytes initial bytes to skip from input stream.
+ * @param byteCount bytes to copy starting after skipBytes.
+ */
+ public static ByteBuffer copyStreamChunk2ByteBuffer(InputStream stream, int skipBytes, int byteCount) throws IOException {
+ if( !(stream instanceof BufferedInputStream) ) {
+ stream = new BufferedInputStream(stream);
+ }
+ final MachineDataInfo machine = Platform.getMachineDataInfo();
+ final ByteBuffer data = Buffers.newDirectByteBuffer( machine.pageAlignedSize( byteCount ) );
+ final byte[] chunk = new byte[machine.pageSizeInBytes()];
+ int numRead = 1; // EOS: -1 == numRead, EOF maybe reached earlier w/ 0 == numRead
+ while ( numRead > 0 && skipBytes > 0 ) {
+ final int chunk2Read = Math.min(machine.pageSizeInBytes(), skipBytes);
+ numRead = stream.read(chunk, 0, chunk2Read);
+ skipBytes -= numRead;
+ }
+ while ( numRead > 0 && byteCount > 0 ) {
+ final int chunk2Read = Math.min(machine.pageSizeInBytes(), byteCount);
+ numRead = stream.read(chunk, 0, chunk2Read);
+ if (numRead > 0) {
+ data.put(chunk, 0, numRead);
+ }
+ byteCount -= numRead;
+ }
+
+ data.flip();
+ return data;
+ }
+
/***
*
* RESOURCE / FILE NAME STUFF
diff --git a/src/junit/com/jogamp/common/util/TestIOUtil01.java b/src/junit/com/jogamp/common/util/TestIOUtil01.java
index 19bc8b0..c0e26a9 100644
--- a/src/junit/com/jogamp/common/util/TestIOUtil01.java
+++ b/src/junit/com/jogamp/common/util/TestIOUtil01.java
@@ -221,6 +221,118 @@ public class TestIOUtil01 extends SingletonJunitCase {
}
}
+ @Test
+ public void test21CopyStreamChunk01Buffer() throws IOException {
+ final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
+ Assert.assertNotNull(urlConn);
+ final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
+ final ByteBuffer bb;
+ final int skipBytes = 0;
+ final int byteCount = orig.length;
+ try {
+ bb = IOUtil.copyStreamChunk2ByteBuffer( bis, skipBytes, byteCount );
+ } finally {
+ IOUtil.close(bis, false);
+ }
+ Assert.assertTrue( machine.pageAlignedSize( byteCount ) >= byteCount );
+ Assert.assertEquals( machine.pageAlignedSize( byteCount ), bb.capacity() );
+ Assert.assertEquals(orig.length, bb.limit());
+ int i;
+ for(i=tsz-1; i>=0 && orig[i]==bb.get(i); i--) ;
+ Assert.assertTrue("Bytes not equal orig vs array", 0>i);
+ System.err.println(getTestMethodName()+" OK: ["+skipBytes+".."+(skipBytes+byteCount)+"): "+bb);
+ }
+
+ @Test
+ public void test22CopyStreamChunk02Buffer() throws IOException {
+ final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
+ Assert.assertNotNull(urlConn);
+ final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
+ final ByteBuffer bb;
+ final int skipBytes = 0;
+ final int byteCount = orig.length + machine.pageSizeInBytes(); // expect more data than exists, complete with actual data
+ try {
+ bb = IOUtil.copyStreamChunk2ByteBuffer( bis, skipBytes, byteCount );
+ } finally {
+ IOUtil.close(bis, false);
+ }
+ Assert.assertTrue( machine.pageAlignedSize( byteCount ) >= byteCount );
+ Assert.assertEquals( machine.pageAlignedSize( byteCount ), bb.capacity() );
+ Assert.assertEquals( orig.length, bb.limit() );
+ int i;
+ for(i=tsz-1; i>=0 && orig[i]==bb.get(i); i--) ;
+ Assert.assertTrue("Bytes not equal orig vs array", 0>i);
+ System.err.println(getTestMethodName()+" OK: ["+skipBytes+".."+(skipBytes+byteCount)+"): "+bb);
+ }
+
+ @Test
+ public void test23CopyStreamChunk03Buffer() throws IOException {
+ final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
+ Assert.assertNotNull(urlConn);
+ final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
+ final ByteBuffer bb;
+ final int skipBytes = 0;
+ final int byteCount = orig.length / 2; // take less data than exists
+ Assert.assertTrue( orig.length >= byteCount );
+ try {
+ bb = IOUtil.copyStreamChunk2ByteBuffer( bis, skipBytes, byteCount );
+ } finally {
+ IOUtil.close(bis, false);
+ }
+ Assert.assertTrue( machine.pageAlignedSize( byteCount ) >= byteCount );
+ Assert.assertEquals( machine.pageAlignedSize( byteCount ), bb.capacity() );
+ Assert.assertEquals( byteCount, bb.limit() );
+ int i;
+ for(i=byteCount-1; i>=0 && orig[i]==bb.get(i); i--) ;
+ Assert.assertTrue("Bytes not equal orig vs array", 0>i);
+ System.err.println(getTestMethodName()+" OK: ["+skipBytes+".."+(skipBytes+byteCount)+"): "+bb);
+ }
+
+ @Test
+ public void test24CopyStreamChunk04Buffer() throws IOException {
+ final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
+ Assert.assertNotNull(urlConn);
+ final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
+ final ByteBuffer bb;
+ final int skipBytes = orig.length / 2;
+ final int byteCount = orig.length / 4; // take less data than exists
+ Assert.assertTrue( orig.length >= skipBytes + byteCount );
+ Assert.assertTrue( orig.length >= byteCount );
+ try {
+ bb = IOUtil.copyStreamChunk2ByteBuffer( bis, skipBytes, byteCount );
+ } finally {
+ IOUtil.close(bis, false);
+ }
+ Assert.assertTrue( machine.pageAlignedSize( byteCount ) >= byteCount );
+ Assert.assertEquals( machine.pageAlignedSize( byteCount ), bb.capacity() );
+ Assert.assertEquals( byteCount, bb.limit() );
+ int i;
+ for(i=byteCount-1; i>=0 && orig[skipBytes+i]==bb.get(i); i--) ;
+ Assert.assertTrue("Bytes not equal orig vs array", 0>i);
+ System.err.println(getTestMethodName()+" OK: ["+skipBytes+".."+(skipBytes+byteCount)+"): "+bb);
+ }
+
+ @Test
+ public void test25CopyStreamChunk05Buffer() throws IOException {
+ final URLConnection urlConn = IOUtil.getResource(tfilename, this.getClass().getClassLoader(), this.getClass());
+ Assert.assertNotNull(urlConn);
+ final BufferedInputStream bis = new BufferedInputStream( urlConn.getInputStream() );
+ final ByteBuffer bb;
+ final int skipBytes = orig.length * 2; // skip all and more ..
+ final int byteCount = orig.length; // expect more data than left, won't take anything
+ Assert.assertTrue( orig.length < skipBytes + byteCount );
+ Assert.assertTrue( orig.length >= byteCount );
+ try {
+ bb = IOUtil.copyStreamChunk2ByteBuffer( bis, skipBytes, byteCount );
+ } finally {
+ IOUtil.close(bis, false);
+ }
+ Assert.assertTrue( machine.pageAlignedSize( byteCount ) >= byteCount );
+ Assert.assertEquals( machine.pageAlignedSize( byteCount ), bb.capacity() );
+ Assert.assertEquals( 0, bb.limit() );
+ System.err.println(getTestMethodName()+" OK: ["+skipBytes+".."+(skipBytes+byteCount)+"): "+bb);
+ }
+
public static void main(final String args[]) throws IOException {
final String tstname = TestIOUtil01.class.getName();
org.junit.runner.JUnitCore.main(tstname);