diff options
Diffstat (limited to 'simple/simple-common/src/test/java/org/simpleframework/common/buffer')
11 files changed, 692 insertions, 0 deletions
diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/ArrayBufferTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/ArrayBufferTest.java new file mode 100644 index 0000000..1f6f494 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/ArrayBufferTest.java @@ -0,0 +1,54 @@ +package org.simpleframework.common.buffer; + +import org.simpleframework.common.buffer.ArrayBuffer; +import org.simpleframework.common.buffer.Buffer; + +import junit.framework.TestCase; + +public class ArrayBufferTest extends TestCase { + + public void testBuffer() throws Exception { + Buffer buffer = new ArrayBuffer(1, 2); + + buffer.append(new byte[]{'a'}).append(new byte[]{'b'}); + + assertEquals(buffer.encode(), "ab"); + assertEquals(buffer.encode("ISO-8859-1"), "ab"); + + boolean overflow = false; + + try { + buffer.append(new byte[]{'c'}); + } catch(Exception e) { + overflow = true; + } + assertTrue(overflow); + + buffer.clear(); + + assertEquals(buffer.encode(), ""); + assertEquals(buffer.encode("UTF-8"), ""); + + buffer = new ArrayBuffer(1024, 2048); + buffer.append("abcdefghijklmnopqrstuvwxyz".getBytes()); + + Buffer alphabet = buffer.allocate(); + alphabet.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes()); + + Buffer digits = buffer.allocate(); + digits.append("0123456789".getBytes()); + + assertEquals(alphabet.encode(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + assertEquals(digits.encode(), "0123456789"); + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + + Buffer extra = digits.allocate(); + extra.append("#@?".getBytes()); + + assertEquals(extra.encode(), "#@?"); + assertEquals(digits.encode(), "0123456789#@?"); + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#@?"); + assertEquals(buffer.length(), 65); + } + +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/BufferAllocatorTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/BufferAllocatorTest.java new file mode 100644 index 0000000..9584047 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/BufferAllocatorTest.java @@ -0,0 +1,79 @@ +package org.simpleframework.common.buffer; + +import org.simpleframework.common.buffer.Allocator; +import org.simpleframework.common.buffer.ArrayAllocator; +import org.simpleframework.common.buffer.Buffer; +import org.simpleframework.common.buffer.BufferAllocator; + +import junit.framework.TestCase; + +public class BufferAllocatorTest extends TestCase { + + public void testBuffer() throws Exception { + Allocator allocator = new ArrayAllocator(1, 2); + Buffer buffer = new BufferAllocator(allocator, 1, 2); + + buffer.append(new byte[]{'a'}).append(new byte[]{'b'}); + + assertEquals(buffer.encode(), "ab"); + assertEquals(buffer.encode("ISO-8859-1"), "ab"); + + boolean overflow = false; + + try { + buffer.append(new byte[]{'c'}); + } catch(Exception e) { + overflow = true; + } + assertTrue(overflow); + + buffer.clear(); + + assertEquals(buffer.encode(), ""); + assertEquals(buffer.encode("UTF-8"), ""); + + allocator = new ArrayAllocator(1024, 2048); + buffer = new BufferAllocator(allocator, 1024, 2048); + buffer.append("abcdefghijklmnopqrstuvwxyz".getBytes()); + + Buffer alphabet = buffer.allocate(); + alphabet.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes()); + + Buffer digits = buffer.allocate(); + digits.append("0123456789".getBytes()); + + assertEquals(alphabet.encode(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + assertEquals(digits.encode(), "0123456789"); + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + + Buffer extra = digits.allocate(); + extra.append("#@?".getBytes()); + + assertEquals(extra.encode(), "#@?"); + assertEquals(extra.length(), 3); + assertEquals(digits.encode(), "0123456789#@?"); + assertEquals(digits.length(), 13); + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#@?"); + assertEquals(buffer.length(), 65); + } + + public void testCascadingBufferAllocator() throws Exception { + Allocator allocator = new ArrayAllocator(1024, 2048); + allocator = new BufferAllocator(allocator, 1024, 2048); + allocator = new BufferAllocator(allocator, 1024, 2048); + allocator = new BufferAllocator(allocator, 1024, 2048); + allocator = new BufferAllocator(allocator, 1024, 2048); + + Buffer buffer = allocator.allocate(1024); + + buffer.append("abcdefghijklmnopqrstuvwxyz".getBytes()); + + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyz"); + + buffer.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes()); + + assertEquals(buffer.encode(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + assertEquals(buffer.length(), 52); + } + +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileBufferTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileBufferTest.java new file mode 100644 index 0000000..54cb142 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileBufferTest.java @@ -0,0 +1,45 @@ +package org.simpleframework.common.buffer; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.simpleframework.common.buffer.Buffer; +import org.simpleframework.common.buffer.FileBuffer; + +import junit.framework.TestCase; + +public class FileBufferTest extends TestCase { + + public void testFileBuffer() throws Exception { + File tempFile = File.createTempFile(FileBufferTest.class.getSimpleName(), null); + Buffer buffer = new FileBuffer(tempFile); + buffer.append("abcdefghijklmnopqrstuvwxyz".getBytes()); + + Buffer alphabet = buffer.allocate(); + alphabet.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes()); + + Buffer digits = buffer.allocate(); + digits.append("0123456789".getBytes()); + + expect(buffer, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".getBytes()); + expect(alphabet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes()); + expect(digits, "0123456789".getBytes()); + } + + private void expect(Buffer buffer, byte[] expect) throws IOException { + InputStream result = buffer.open(); + + for(int i =0; i < expect.length; i++) { + byte octet = expect[i]; + int value = result.read(); + + if(value < 0) { + throw new IOException("Buffer exhausted too early"); + } + assertEquals(octet, (byte)value); + } + assertEquals(-1, result.read()); + } + +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueue.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueue.java new file mode 100644 index 0000000..b404562 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueue.java @@ -0,0 +1,109 @@ +package org.simpleframework.common.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.simpleframework.common.buffer.Allocator; +import org.simpleframework.common.buffer.Buffer; +import org.simpleframework.common.buffer.BufferAllocator; + +public class FileByteQueue { + + private BlockingQueue<Block> blocks; + private BlockAllocator allocator; + private Block source; + + public FileByteQueue(Allocator allocator) throws IOException { + this.blocks = new LinkedBlockingQueue<Block>(); + this.allocator = new BlockAllocator(allocator); + } + + public int read(byte[] array, int off, int size) throws Exception { + int left = blocks.size(); + int mark = size; + + for(int i = 0; source != null || i < left; i++) { + if(source == null) { + source = blocks.take(); + } + int remain = source.remaining(); + int read = Math.min(remain, size); + + if(read > 0) { + source.read(array, off, size); + size -= read; + off += read; + } + if(remain == 0) { + source.close(); // clear up file handles + source = null; + } + if(size <= 0) { + return mark; + } + } + return mark - size; + } + + public void write(byte[] array, int off, int size) throws Exception { + Block buffer = allocator.allocate(array, off, size); + + if(size > 0) { + blocks.offer(buffer); + } + } + + private class BlockAllocator { + + private Allocator allocator; + + public BlockAllocator(Allocator allocator) { + this.allocator = new BufferAllocator(allocator); + } + + public Block allocate(byte[] array, int off, int size) throws IOException { + Buffer buffer = allocator.allocate(); + + if(size > 0) { + buffer.append(array, off, size); + } + return new Block(buffer, size); + } + } + + private class Block { + + private InputStream source; + private int remaining; + private int size; + + public Block(Buffer buffer, int size) throws IOException { + this.source = buffer.open(); + this.remaining = size; + this.size = size; + } + + public int read(byte[] array, int off, int size) throws IOException { + int count = source.read(array, off, size); + + if(count > 0) { + remaining -= size; + } + return count; + } + + public void close() throws IOException { + source.close(); + } + + public int remaining() { + return remaining; + } + + public int size() { + return size; + } + } +}
\ No newline at end of file diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueueTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueueTest.java new file mode 100644 index 0000000..9699454 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/FileByteQueueTest.java @@ -0,0 +1,22 @@ +package org.simpleframework.common.buffer; + +import junit.framework.TestCase; + +public class FileByteQueueTest extends TestCase { + + public void testQueue() throws Exception { + /* Allocator allocator = new FileAllocator(); + FileByteQueue queue = new FileByteQueue(allocator); + for(int i = 0; i < 26; i++) { + queue.write(new byte[]{(byte)(i+'a')}, 0, 1); + System.err.println("WRITE>>"+(char)(i+'a')); + } + for(int i = 0; i < 26; i++) { + byte[] buffer = new byte[1]; + assertEquals(queue.read(buffer, 0, 1), 1); + System.err.println("READ>>"+((char)buffer[0])); + assertEquals(buffer[0], (byte)(i+'a')); + }*/ + } + +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueue.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueue.java new file mode 100644 index 0000000..893ae80 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueue.java @@ -0,0 +1,100 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.IOException; + +import org.simpleframework.common.buffer.BufferException; + +public class ArrayByteQueue implements ByteQueue { + + private byte[] buffer; + private int limit; + private int count; + private int seek; + private boolean closed; + + public ArrayByteQueue(int limit) { + this.buffer = new byte[16]; + this.limit = limit; + } + + public synchronized void write(byte[] array) throws IOException { + write(array, 0, array.length); + } + + public synchronized void write(byte[] array, int off, int size) throws IOException { + if(closed) { + throw new BufferException("Queue has been closed"); + } + if (size + count > buffer.length) { + expand(count + size); + } + int fragment = buffer.length - seek; // from read pos to end + int space = fragment - count; // space at end + + if(space >= size) { + System.arraycopy(array, off, buffer, seek + count, size); + } else { + int chunk = Math.min(fragment, count); + + System.arraycopy(buffer, seek, buffer, 0, chunk); // adjust downward + System.arraycopy(array, off, buffer, chunk, size); + seek = 0; + } + notify(); + count += size; + } + + public synchronized int read(byte[] array) throws IOException { + return read(array, 0, array.length); + } + + public synchronized int read(byte[] array, int off, int size) throws IOException { + while(count == 0) { + try { + if(closed) { + return -1; + } + wait(); + } catch(Exception e) { + throw new BufferException("Thread interrupted", e); + } + } + int chunk = Math.min(size, count); + + if(chunk > 0) { + System.arraycopy(buffer, seek, array, off, chunk); + seek += chunk; + count -= chunk; + } + return chunk; + } + + private synchronized void expand(int capacity) throws IOException { + if (capacity > limit) { + throw new BufferException("Capacity limit %s exceeded", limit); + } + int resize = buffer.length * 2; + int size = Math.max(capacity, resize); + byte[] temp = new byte[size]; + + System.arraycopy(buffer, seek, temp, 0, count); + buffer = temp; + seek = 0; + } + + public synchronized void reset() throws IOException { + if(closed) { + throw new BufferException("Queue has been closed"); + } + seek = 0; + count = 0; + } + + public synchronized int available() { + return count; + } + + public synchronized void close() { + closed = true; + } +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueueTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueueTest.java new file mode 100644 index 0000000..7d361f3 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ArrayByteQueueTest.java @@ -0,0 +1,119 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import junit.framework.TestCase; + +public class ArrayByteQueueTest extends TestCase { + + public void testArrayByteQueue() throws Exception { + ArrayByteQueue queue = new ArrayByteQueue(10); + + for(int i = 0; i < 9; i++) { + queue.write(new byte[]{(byte)('A'+i)}); + } + for(int i = 0; i < 9; i++) { + byte[] b = new byte[1]; + queue.read(b); + System.err.write(b); + System.err.println(); + } + for(int i = 9; i < 19; i++) { + queue.write(new byte[]{(byte)('A'+i)}); + } + for(int i = 0; i < 9; i++) { + byte[] b = new byte[1]; + queue.read(b); + System.err.write(b); + System.err.println(); + } + } + + public void testRandomReadWrite() throws Exception { + ArrayByteQueue queue = new ArrayByteQueue(1024 * 10); + + for(int i = 0; i < 100; i++) { + String text = "Test: "+i; + queue.write(text.getBytes()); + } + for(int i = 0; i < 100; i++) { + String text = "Test: "+i; + byte[] buffer = new byte[256]; + int size = queue.read(buffer, 0, text.length()); + String result = new String(buffer, 0, size); + System.err.println(result); + assertEquals(result, text); + } + } + /* + public void testStream() throws Exception { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + final ArrayByteQueue queue = new ArrayByteQueue(1024 * 10); + final Thread reader = new Thread(new Runnable() { + public void run() { + try { + for(int i = 0; i < 100; i++) { + byte[] chunk = new byte[(int)Math.round((Math.random() * 100))]; + int size = queue.read(chunk); + output.write(chunk, 0, size); + } + } catch(Exception e) { + e.printStackTrace(); + } + } + }); + final Thread writer = new Thread(new Runnable() { + public void run() { + try { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ObjectOutputStream objectOutput = new ObjectOutputStream(buffer); + + for(int i = 0; i < 100; i++) { + try { + TestMessage message = new TestMessage(i, "Test Message: " +i); + objectOutput.writeObject(message); + objectOutput.flush(); + byte[] messageBytes = buffer.toByteArray(); + queue.write(messageBytes); + buffer.reset(); // clear out the buffer so toByteArray picks up changes only + } catch(Exception e) { + e.printStackTrace(); + } + } + }catch(Exception e){ + e.printStackTrace(); + } + } + }); + writer.start(); + reader.start(); + writer.join(); + Thread.sleep(5000); + reader.interrupt(); + reader.join(); + + ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); + ObjectInputStream objectInput = new ObjectInputStream(input); + + for(int i = 0; i < 100; i++) { + TestMessage message = (TestMessage)objectInput.readObject(); + assertEquals(message.count, i); + assertEquals(message.text, "Test Message: "+i); + } + } +*/ + private static class TestMessage implements Serializable { + + public final int count; + public final String text; + + public TestMessage(int count, String text) { + this.count = count; + this.text = text; + } + } +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueue.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueue.java new file mode 100644 index 0000000..5f3e97f --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueue.java @@ -0,0 +1,67 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.IOException; +import java.io.InputStream; + +import org.simpleframework.common.buffer.ArrayBuffer; +import org.simpleframework.common.buffer.Buffer; + +public class BufferQueue implements Buffer { + + private final ByteQueue queue; + private final Buffer buffer; + + public BufferQueue(ByteQueue queue) { + this.buffer = new ArrayBuffer(); + this.queue = queue; + } + + public InputStream open() throws IOException { + return new ByteQueueStream(queue); + } + + public Buffer allocate() throws IOException { + return new BufferQueue(queue); + } + + public String encode() throws IOException { + return encode("UTF-8"); + } + + public String encode(String charset) throws IOException { + InputStream source = open(); + byte[] chunk = new byte[512]; + int count = 0; + + while((count = source.read(chunk)) != -1) { + buffer.append(chunk, 0, count); + } + return buffer.encode(charset); + } + + public Buffer append(byte[] array) throws IOException { + if(array.length > 0) { + queue.write(array); + } + return this; + } + + public Buffer append(byte[] array, int off, int len) throws IOException { + if(len > 0) { + queue.write(array, off, len); + } + return this; + } + + public void clear() throws IOException { + queue.reset(); + } + + public void close() throws IOException { + queue.close(); + } + + public long length() { + return buffer.length(); + } +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueueTest.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueueTest.java new file mode 100644 index 0000000..22eaba7 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/BufferQueueTest.java @@ -0,0 +1,44 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.InputStream; + +import junit.framework.TestCase; + +public class BufferQueueTest extends TestCase { + + public void testBufferQueue() throws Exception { + final ByteQueue queue = new ArrayByteQueue(1024 * 1000); + final BufferQueue buffer = new BufferQueue(queue); + + Thread reader = new Thread(new Runnable() { + public void run() { + try { + InputStream source = buffer.open(); + for(int i = 0; i < 1000; i++) { + int octet = source.read(); + System.err.write(octet); + System.err.flush(); + } + }catch(Exception e) { + e.printStackTrace(); + } + } + }); + Thread writer = new Thread(new Runnable() { + public void run() { + try { + for(int i = 0; i < 1000; i++) { + buffer.append(("Test message: "+i+"\n").getBytes()); + } + }catch(Exception e) { + e.printStackTrace(); + } + } + }); + reader.start(); + writer.start(); + reader.join(); + writer.join(); + } + +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueue.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueue.java new file mode 100644 index 0000000..dc567e9 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueue.java @@ -0,0 +1,13 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.IOException; + +public interface ByteQueue { + void write(byte[] array) throws IOException; + void write(byte[] array, int off, int size) throws IOException; + int read(byte[] array) throws IOException; + int read(byte[] array, int off, int size) throws IOException; + int available() throws IOException; + void reset() throws IOException; + void close() throws IOException; +} diff --git a/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueueStream.java b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueueStream.java new file mode 100644 index 0000000..dbf73e1 --- /dev/null +++ b/simple/simple-common/src/test/java/org/simpleframework/common/buffer/queue/ByteQueueStream.java @@ -0,0 +1,40 @@ +package org.simpleframework.common.buffer.queue; + +import java.io.IOException; +import java.io.InputStream; + +public class ByteQueueStream extends InputStream { + + private final ByteQueue queue; + + public ByteQueueStream(ByteQueue queue) { + this.queue = queue; + } + + @Override + public int read() throws IOException { + byte[] array = new byte[1]; + int count = read(array) ; + + if(count != -1) { + return array[0] & 0xff; + } + return -1; + } + + public int read(byte[] buffer) throws IOException { + return queue.read(buffer, 0, buffer.length); + } + + public int read(byte[] buffer, int off, int size) throws IOException { + return queue.read(buffer, off, size); + } + + public int available() throws IOException { + return queue.available(); + } + + public void close() throws IOException { + queue.close(); + } +} |