Ranides Atterwim 10 年 前
コミット
70778110fd

+ 22 - 8
assira/src/main/java/net/ranides/assira/io/DataBuffer.java

@@ -17,6 +17,7 @@ import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import net.ranides.assira.collection.arrays.ArrayAllocator;
+import net.ranides.assira.collection.arrays.ArrayUtils;
 import net.ranides.assira.collection.arrays.NativeArray;
 import net.ranides.assira.collection.arrays.NativeArrayAllocator;
 import net.ranides.assira.text.Charsets;
@@ -40,9 +41,18 @@ public class DataBuffer implements DataInput, DataOutput {
         return ByteBuffer.wrap(array.$array(), 0, buffer.position());
     }
     
+    public byte[] bytes() {
+        int n = buffer.position();
+        return ArrayUtils.copy(array.$array(), 0, new byte[n], 0, n);
+    }
+    
     public DataBuffer seek(int position) throws IOException {
-        if(position != buffer.position(position).position()) {
-            throw new IOException("EOF ?");
+        try {
+            if(position != buffer.position(position).position()) {
+                throw new IOException("EOF ?");
+            }
+        } catch(IllegalArgumentException cause) {
+            throw new IOException(cause);
         }
         return this;
     }
@@ -65,7 +75,7 @@ public class DataBuffer implements DataInput, DataOutput {
     @Override
     public int skipBytes(int n) throws IOException {
         reserve(n);
-        buffer.position(buffer.position()+n);
+        seek(seek()+n);
         return n;
     }
 
@@ -195,13 +205,18 @@ public class DataBuffer implements DataInput, DataOutput {
         byte[] bytes = new byte[size];
         readFully(bytes);
         return new String(bytes, Charsets.UTF8);
-
+    }
+    
+    public void readChars(char[] data) throws IOException {
+        checkEOF(2 * data.length);
+        for(int i=0; i<data.length; i++) {
+            data[i] = buffer.getChar();
+        }
     }
     
     @Override
     public void write(int b) throws IOException {
-        reserve(1);
-        buffer.put((byte)b);
+        writeByte(b);
     }
 
     @Override
@@ -212,8 +227,7 @@ public class DataBuffer implements DataInput, DataOutput {
 
     @Override
     public void write(byte[] b) throws IOException {
-        reserve(b.length);
-        buffer.put(b);
+        write(b, 0, b.length);
     }
 
     @Override

+ 87 - 0
assira/src/test/java/net/ranides/assira/io/DataBufferTest.java

@@ -7,6 +7,8 @@
 package net.ranides.assira.io;
 
 import java.io.IOException;
+import java.util.Arrays;
+import net.ranides.assira.junit.NewAssert;
 import net.ranides.assira.text.Charsets;
 import org.junit.Test;
 import static org.junit.Assert.*;
@@ -100,4 +102,89 @@ public class DataBufferTest {
         assertEquals(null, db3.readLine(Charsets.UTF8));
     }
     
+    @Test
+    public void testTypes() throws IOException {
+        DataBuffer dbo = new DataBuffer();
+        
+        dbo.write(44);
+        dbo.write("hello".getBytes(Charsets.US_ASCII));
+        dbo.writeBoolean(true);
+        dbo.writeBoolean(false);
+        dbo.writeByte(0xF4);
+        dbo.writeShort(0x2345);
+        dbo.writeShort(0xF701);
+        dbo.writeChar('Q');
+        dbo.writeInt(0x334455AA);
+        dbo.writeLong(0x1020304011121314L);
+        dbo.writeFloat(3.14f);
+        dbo.writeDouble(2.7168);
+        dbo.writeBytes("world");
+        dbo.writeChars("źrebię na łące ");
+        dbo.writeUTF("patrzy na słońce gorące.");
+        dbo.writeByte(66);
+        
+        DataBuffer dbi = new DataBuffer();
+        dbi.write(dbo.bytes());
+        dbi.seek(0);
+        assertEquals(44, dbi.readByte());
+        
+        byte[] v1 = new byte[5];
+        dbi.readFully(v1);
+        assertEquals("hello", new String(v1, Charsets.US_ASCII));
+        assertEquals(true, dbi.readBoolean());
+        assertEquals(false, dbi.readBoolean());
+        assertEquals(0xF4, dbi.readUnsignedByte());
+        
+        assertEquals(0x2345, dbi.readShort());
+        assertEquals(0xF701, dbi.readUnsignedShort());
+        assertEquals('Q', dbi.readChar());
+        assertEquals(0x334455AA, dbi.readInt());
+        assertEquals(0x1020304011121314L, dbi.readLong());
+        assertEquals(3.14f, dbi.readFloat(), 1e-5f);
+        assertEquals(2.7168f, dbi.readDouble(), 1e-5);
+        
+        byte[] v2 = new byte[5];
+        dbi.readFully(v2);
+        assertEquals("world", new String(v2, Charsets.US_ASCII));
+        
+        char[] exp3 = "źrebię na łące ".toCharArray();
+        char[] v3 = new char[exp3.length];
+        dbi.readChars(v3);
+        assertArrayEquals(exp3, v3);
+        
+        assertEquals("patrzy na słońce gorące.", dbi.readUTF());
+        assertEquals(66, dbi.readByte());
+    }
+    
+    @Test
+    public void testSeek() throws IOException {
+        DataBuffer dbo = new DataBuffer();
+        
+        dbo.writeBytes("hello world");
+        dbo.seek(3);
+        assertArrayEquals(new byte[]{104,101,108}, dbo.bytes());
+        
+        NewAssert.assertThrows(IOException.class, ()->{
+            dbo.seek(-2);
+        });
+        NewAssert.assertThrows(IOException.class, ()->{
+            dbo.seek(100);
+        });
+        
+        dbo.seek(4);
+        assertEquals('o', dbo.readByte());
+        
+        dbo.skipBytes(3);
+        assertEquals('r', dbo.readByte());
+        
+        NewAssert.assertThrows(IOException.class, ()->{
+            dbo.skipBytes(-20);
+        });
+        
+        dbo.skipBytes(-3);
+        assertEquals('w', dbo.readByte());
+        
+        assertEquals(120, dbo.skipBytes(120));
+    }
+    
 }