1 module BufferUtilsDemo;
2 
3 import hunt.io.ByteBuffer;
4 import hunt.io.BufferUtils;
5 import hunt.logging;
6 
7 import hunt.Assert;
8 import hunt.util.UnitTest;
9 import hunt.Exceptions;
10 
11 alias assertTrue = Assert.assertTrue;
12 alias assertFalse = Assert.assertFalse;
13 alias assertThat = Assert.assertThat;
14 alias assertEquals = Assert.assertEquals;
15 alias assertNotNull = Assert.assertNotNull;
16 alias assertNull = Assert.assertNull;
17 
18 import std.conv;
19 
20 class BufferUtilsDemo {
21 
22     @Test void testToInt() {
23         ByteBuffer[] buf = [
24             BufferUtils.toBuffer("0"), BufferUtils.toBuffer(" 42 "),
25             BufferUtils.toBuffer("   43abc"), BufferUtils.toBuffer("-44"), BufferUtils.toBuffer(" - 45;"),
26             BufferUtils.toBuffer("-2147483648"), BufferUtils.toBuffer("2147483647"),
27         ];
28 
29         int[] val = [0, 42, 43, -44, -45, -2147483648, 2147483647];
30 
31         for (size_t i = 0; i < buf.length; i++)
32             assertEquals("t" ~ i.to!string(), val[i], BufferUtils.toInt(buf[i]));
33     }
34 
35     @Test void testPutInt() {
36         int[] val = [0, 42, 43, -44, -45, int.min, int.max];
37 
38         string[] str = ["0", "42", "43", "-44", "-45", to!string(int.min), to!string(int.max)];
39 
40         ByteBuffer buffer = BufferUtils.allocate(24);
41 
42         for (int i = 0; i < val.length; i++) {
43             BufferUtils.clearToFill(buffer);
44             BufferUtils.putDecInt(buffer, val[i]);
45             BufferUtils.flipToFlush(buffer, 0);
46             assertEquals("t" ~ i.to!string(), str[i], BufferUtils.toString(buffer));
47         }
48     }
49 
50     @Test void testPutLong() {
51         long[] val = [0L, 42L, 43L, -44L, -45L, long.min, long.max];
52 
53         string[] str = ["0", "42", "43", "-44", "-45", to!string(long.min), to!string(long.max)];
54 
55         ByteBuffer buffer = BufferUtils.allocate(50);
56 
57         for (int i = 0; i < val.length; i++) {
58             BufferUtils.clearToFill(buffer);
59             BufferUtils.putDecLong(buffer, val[i]);
60             BufferUtils.flipToFlush(buffer, 0);
61             assertEquals("t" ~ i.to!string(), str[i], BufferUtils.toString(buffer));
62         }
63     }
64 
65     @Test void testPutHexInt() {
66         int[] val = [0, 42, 43, -44, -45, -2147483648, 2147483647];
67 
68         string[] str = ["0", "2A", "2B", "-2C", "-2D", "-80000000", "7FFFFFFF"];
69 
70         ByteBuffer buffer = BufferUtils.allocate(50);
71 
72         for (int i = 0; i < val.length; i++) {
73             BufferUtils.clearToFill(buffer);
74             BufferUtils.putHexInt(buffer, val[i]);
75             BufferUtils.flipToFlush(buffer, 0);
76             assertEquals("t" ~ i.to!string, str[i], BufferUtils.toString(buffer));
77         }
78     }
79 
80     @Test void testPut() {
81         ByteBuffer to = BufferUtils.allocate(10);
82         ByteBuffer from = BufferUtils.toBuffer("12345");
83 
84         BufferUtils.clear(to);
85         assertEquals(5, BufferUtils.append(to, from));
86         assertTrue(BufferUtils.isEmpty(from));
87         assertEquals("12345", BufferUtils.toString(to));
88 
89         from = BufferUtils.toBuffer("XX67890ZZ");
90         from.position(2);
91 
92         assertEquals(5, BufferUtils.append(to, from));
93         assertEquals(2, from.remaining());
94         assertEquals("1234567890", BufferUtils.toString(to));
95     }
96 
97     @Test void testAppend() {
98         ByteBuffer to = BufferUtils.allocate(8);
99         ByteBuffer from = BufferUtils.toBuffer("12345");
100 
101         BufferUtils.append(to, from.array(), 0, 3);
102         assertEquals("123", BufferUtils.toString(to));
103         BufferUtils.append(to, from.array(), 3, 2);
104         assertEquals("12345", BufferUtils.toString(to));
105 
106         try {
107             BufferUtils.append(to, from.array(), 0, 5);
108             Assert.fail();
109         } catch (BufferOverflowException e) {
110         }
111     }
112 
113     @Test void testPutDirect() {
114         ByteBuffer to = BufferUtils.allocateDirect(10);
115         ByteBuffer from = BufferUtils.toBuffer("12345");
116 
117         BufferUtils.clear(to);
118         assertEquals(5, BufferUtils.append(to, from));
119         assertTrue(BufferUtils.isEmpty(from));
120         assertEquals("12345", BufferUtils.toString(to));
121 
122         from = BufferUtils.toBuffer("XX67890ZZ");
123         from.position(2);
124 
125         assertEquals(5, BufferUtils.append(to, from));
126         assertEquals(2, from.remaining());
127         assertEquals("1234567890", BufferUtils.toString(to));
128     }
129 
130         @Test
131         void testToBuffer_Array() {
132             byte[] arr = new byte[128];
133             // Arrays.fill(arr, (byte) 0x44);
134             arr[] = 0x44;
135             ByteBuffer buf = BufferUtils.toBuffer(arr);
136 
137             int count = 0;
138             while (buf.remaining() > 0) {
139                 byte b = buf.get();
140                 Assert.assertEquals(b, 0x44);
141                 count++;
142             }
143 
144             Assert.assertEquals("Count of bytes", arr.length, count);
145         }
146 
147         @Test
148         void testToBuffer_ArrayOffsetLength() {
149             byte[] arr = new byte[128];
150             arr[] = cast(byte)0xFF; // fill whole thing with FF
151             
152             int offset = 10;
153             int length = 100;
154             arr[offset ..  offset + length] = 0x77;
155             ByteBuffer buf = BufferUtils.toBuffer(arr, offset, length); // fill partial with 0x77
156 
157             int count = 0;
158             while (buf.remaining() > 0) {
159                 byte b = buf.get();
160                 Assert.assertEquals(b, 0x77);
161                 count++;
162             }
163 
164             Assert.assertEquals("Count of bytes", length, count);
165         }
166 
167     //     @Test
168     //     @Ignore("Very simple microbenchmark to compare different writeTo implementations. Only for development thus " ~
169     //             "ignored.")
170     //     void testWriteToMicrobenchmark() {
171     //         int capacity = 1024 * 128;
172     //         int iterations = 100;
173     //         int testRuns = 10;
174     //         byte[] bytes = new byte[capacity];
175     //         ThreadLocalRandom.current().nextBytes(bytes);
176     //         ByteBuffer buffer = BufferUtils.allocate(capacity);
177     //         BufferUtils.append(buffer, bytes, 0, capacity);
178     //         long startTest = System.nanoTime();
179     //         for (int i = 0; i < testRuns; i++) {
180     //             long start = System.nanoTime();
181     //             for (int j = 0; j < iterations; j++) {
182     //                 ByteArrayOutputStream out = new ByteArrayOutputStream();
183     //                 long startRun = System.nanoTime();
184     //                 BufferUtils.writeTo(buffer.asReadOnlyBuffer(), out);
185     //                 long elapsedRun = System.nanoTime() - startRun;
186     // //                LOG.warn("run elapsed={}ms", elapsedRun / 1000);
187     //                 assertThat("Bytes in out equal bytes in buffer", Arrays.equals(bytes, out.toByteArray()), is(true));
188     //             }
189     //             long elapsed = System.nanoTime() - start;
190     //             System.out.println(StringUtils.replace("elapsed={}ms average={}ms", elapsed / 1000, elapsed / iterations / 1000));
191     //         }
192     //         System.out.println(StringUtils.replace("overall average: {}ms", (System.nanoTime() - startTest) / testRuns / iterations / 1000));
193     //     }
194 
195     //     @Test
196     //     void testWriteToWithBufferThatDoesNotExposeArrayAndSmallContent() {
197     //         int capacity = BufferUtils.TEMP_BUFFER_SIZE / 4;
198     //         testWriteToWithBufferThatDoesNotExposeArray(capacity);
199     //     }
200 
201     //     @Test
202     //     void testWriteToWithBufferThatDoesNotExposeArrayAndContentLengthMatchingTempBufferSize() {
203     //         int capacity = BufferUtils.TEMP_BUFFER_SIZE;
204     //         testWriteToWithBufferThatDoesNotExposeArray(capacity);
205     //     }
206 
207     //     @Test
208     //     void testWriteToWithBufferThatDoesNotExposeArrayAndContentSlightlyBiggerThanTwoTimesTempBufferSize()
209     //             throws
210     //             IOException {
211     //         int capacity = BufferUtils.TEMP_BUFFER_SIZE * 2 + 1024;
212     //         testWriteToWithBufferThatDoesNotExposeArray(capacity);
213     //     }
214 
215     @Test void testEnsureCapacity() {
216         ByteBuffer b = BufferUtils.toBuffer("Goodbye Cruel World");
217         assertTrue(b == BufferUtils.ensureCapacity(b, 0));
218         assertTrue(b == BufferUtils.ensureCapacity(b, 10));
219         assertTrue(b == BufferUtils.ensureCapacity(b, b.capacity()));
220 
221         ByteBuffer b1 = BufferUtils.ensureCapacity(b, 64);
222         assertTrue(b != b1);
223         assertEquals(64, b1.capacity());
224         assertEquals("Goodbye Cruel World", BufferUtils.toString(b1));
225 
226         b1.position(8);
227         b1.limit(13);
228         assertEquals("Cruel", BufferUtils.toString(b1));
229         ByteBuffer b2 = b1.slice();
230         assertEquals("Cruel", BufferUtils.toString(b2));
231         trace(BufferUtils.toDetailString(b2));
232         assertEquals(8, b2.arrayOffset());
233         assertEquals(5, b2.capacity());
234 
235         assertTrue(b2 == BufferUtils.ensureCapacity(b2, 5));
236 
237         ByteBuffer b3 = BufferUtils.ensureCapacity(b2, 64);
238 
239         trace(BufferUtils.toDetailString(b3));
240         assertTrue(b2 != b3);
241         assertEquals(64, b3.capacity());
242         assertEquals("Cruel", BufferUtils.toString(b3));
243         assertEquals(0, b3.arrayOffset());
244 
245     }
246 
247     //     private void testWriteToWithBufferThatDoesNotExposeArray(int capacity) {
248     //         ByteArrayOutputStream out = new ByteArrayOutputStream();
249     //         byte[] bytes = new byte[capacity];
250     //         ThreadLocalRandom.current().nextBytes(bytes);
251     //         ByteBuffer buffer = BufferUtils.allocate(capacity);
252     //         BufferUtils.append(buffer, bytes, 0, capacity);
253     //         BufferUtils.writeTo(buffer.asReadOnlyBuffer(), out);
254     //         assertThat("Bytes in out equal bytes in buffer", Arrays.equals(bytes, out.toByteArray()), is(true));
255     //     }
256 
257     //     @Test
258     //     void testMappedFile() {
259     //         string data = "Now is the time for all good men to come to the aid of the party";
260     //         File file = File.createTempFile("test", ".txt");
261     //         file.deleteOnExit();
262     //         try (FileWriter out = new FileWriter(file);) {
263     //             out.write(data);
264     //         }
265 
266     //         ByteBuffer mapped = BufferUtils.toMappedBuffer(file);
267     //         assertEquals(data, BufferUtils.toString(mapped));
268     //         assertTrue(BufferUtils.isMappedBuffer(mapped));
269 
270     //         ByteBuffer direct = BufferUtils.allocateDirect(data.length());
271     //         BufferUtils.clearToFill(direct);
272     //         direct.put(data.getBytes(StandardCharsets.ISO_8859_1));
273     //         BufferUtils.flipToFlush(direct, 0);
274     //         assertEquals(data, BufferUtils.toString(direct));
275     //         assertFalse(BufferUtils.isMappedBuffer(direct));
276 
277     //         ByteBuffer slice = direct.slice();
278     //         assertEquals(data, BufferUtils.toString(slice));
279     //         assertFalse(BufferUtils.isMappedBuffer(slice));
280 
281     //         ByteBuffer duplicate = direct.duplicate();
282     //         assertEquals(data, BufferUtils.toString(duplicate));
283     //         assertFalse(BufferUtils.isMappedBuffer(duplicate));
284 
285     //         ByteBuffer readonly = direct.asReadOnlyBuffer();
286     //         assertEquals(data, BufferUtils.toString(readonly));
287     //         assertFalse(BufferUtils.isMappedBuffer(readonly));
288     //     }
289 
290     //     @Test
291     //     void testNormalizeCapacity() {
292     //         Assert.assertThat(BufferUtils.normalizeBufferSize(5), is(1024));
293     //         Assert.assertThat(BufferUtils.normalizeBufferSize(1023), is(1024));
294     //         Assert.assertThat(BufferUtils.normalizeBufferSize(1024), is(1024));
295     //         Assert.assertThat(BufferUtils.normalizeBufferSize(70), is(1024));
296     //         Assert.assertThat(BufferUtils.normalizeBufferSize(1025), is(1024 * 2));
297     //         Assert.assertThat(BufferUtils.normalizeBufferSize(1900), is(1024 * 2));
298     //         Assert.assertThat(BufferUtils.normalizeBufferSize(2048), is(1024 * 2));
299     //         Assert.assertThat(BufferUtils.normalizeBufferSize(2049), is(1024 * 3));
300     //         Assert.assertThat(BufferUtils.normalizeBufferSize(5000), is(1024 * 5));
301     //     }
302 
303     //     @Test
304     //     void testSplit() {
305     //         ByteBuffer buffer = ByteBuffer.allocate(35);
306     //         for (byte i = 0; i < 35; i++) {
307     //             buffer.put(i);
308     //         }
309     //         buffer.flip();
310     //         List<ByteBuffer> list = BufferUtils.split(buffer, 35);
311     //         assertEquals(list.size(), 1);
312     //         assertEquals(list.get(0), buffer);
313 
314     //         list = BufferUtils.split(buffer, 10);
315     //         assertEquals(list.size(), 4);
316     //         assertEquals(list.get(0).remaining(), 10);
317     //         assertEquals(list.get(3).remaining(), 5);
318     //         assertEquals(list.get(3).get(4), 34);
319 
320     //         assertEquals(buffer.position(), 0);
321     //     }
322 }