ReplaceInputStream (wip)
authorNiki Roo <niki@nikiroo.be>
Fri, 26 Apr 2019 22:33:32 +0000 (00:33 +0200)
committerNiki Roo <niki@nikiroo.be>
Fri, 26 Apr 2019 22:33:32 +0000 (00:33 +0200)
src/be/nikiroo/utils/BufferedInputStream.java
src/be/nikiroo/utils/ReplaceInputStream.java [new file with mode: 0644]
src/be/nikiroo/utils/test_code/BufferedInputStreamTest.java [new file with mode: 0644]
src/be/nikiroo/utils/test_code/ReplaceInputStreamTest.java [new file with mode: 0644]
src/be/nikiroo/utils/test_code/Test.java

index 4a8a8c3967056ee39d395d13a3ab93629063b3c2..9b95574b8165ea8d093cafe4869b8b307886a8ac 100644 (file)
@@ -386,7 +386,7 @@ public class BufferedInputStream extends InputStream {
        }
 
        // buffer must be > search
-       static private boolean startsWith(byte[] search, byte[] buffer, int offset) {
+       static protected boolean startsWith(byte[] search, byte[] buffer, int offset) {
                boolean same = true;
                for (int i = 0; i < search.length; i++) {
                        if (search[i] != buffer[offset + i]) {
diff --git a/src/be/nikiroo/utils/ReplaceInputStream.java b/src/be/nikiroo/utils/ReplaceInputStream.java
new file mode 100644 (file)
index 0000000..5ce9ef3
--- /dev/null
@@ -0,0 +1,68 @@
+package be.nikiroo.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class ReplaceInputStream extends BufferedInputStream {
+       private byte[] from;
+       private byte[] to;
+
+       private byte[] source;
+       private int spos;
+       private int slen;
+
+       public ReplaceInputStream(InputStream in, String from, String to) {
+               this(in, bytes(from), bytes(to));
+       }
+
+       public ReplaceInputStream(InputStream in, byte[] from, byte[] to) {
+               super(in);
+               this.from = from;
+               this.to = to;
+
+               source = new byte[4096];
+               spos = 0;
+               slen = 0;
+       }
+
+       @Override
+       protected int read(InputStream in, byte[] buffer) throws IOException {
+               if (buffer.length < to.length) {
+                       throw new IOException(
+                                       "Underlaying buffer is too small to contain the replace String");
+               }
+
+               if (spos >= slen) {
+                       spos = 0;
+                       slen = in.read(source);
+               }
+
+               // Note: very simple, not efficient implementation, sorry.
+               int count = 0;
+               int i = spos;
+               while (i < slen && count < buffer.length - to.length) {
+                       if (from.length > 0 && startsWith(from, source, spos)) {
+                               System.arraycopy(to, 0, buffer, spos, to.length);
+                               count += to.length;
+                               i += to.length;
+                               spos += to.length;
+                       } else {
+                               buffer[count++] = source[i++];
+                               spos++;
+                       }
+               }
+
+               return count;
+       }
+
+       static private byte[] bytes(String str) {
+               try {
+                       return str.getBytes("UTF-8");
+               } catch (UnsupportedEncodingException e) {
+                       // All conforming JVM must support UTF-8
+                       e.printStackTrace();
+                       return null;
+               }
+       }
+}
diff --git a/src/be/nikiroo/utils/test_code/BufferedInputStreamTest.java b/src/be/nikiroo/utils/test_code/BufferedInputStreamTest.java
new file mode 100644 (file)
index 0000000..e2fc80b
--- /dev/null
@@ -0,0 +1,46 @@
+package be.nikiroo.utils.test_code;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import be.nikiroo.utils.BufferedInputStream;
+import be.nikiroo.utils.IOUtils;
+import be.nikiroo.utils.test.TestCase;
+import be.nikiroo.utils.test.TestLauncher;
+
+public class BufferedInputStreamTest extends TestLauncher {
+       public BufferedInputStreamTest(String[] args) {
+               super("BufferedInputStream test", args);
+
+               addTest(new TestCase("Simple InputStream reading") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               BufferedInputStream in = new BufferedInputStream(
+                                               new ByteArrayInputStream(expected));
+                               checkArrays(this, "FIRST", in, expected);
+                       }
+               });
+
+               addTest(new TestCase("Simple byte array reading") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               BufferedInputStream in = new BufferedInputStream(expected);
+                               checkArrays(this, "FIRST", in, expected);
+                       }
+               });
+       }
+
+       static void checkArrays(TestCase test, String prefix, InputStream in,
+                       byte[] expected) throws Exception {
+               byte[] actual = IOUtils.toByteArray(in);
+               test.assertEquals("The " + prefix
+                               + " resulting array has not the correct number of items",
+                               expected.length, actual.length);
+               for (int i = 0; i < actual.length; i++) {
+                       test.assertEquals("Item " + i + " (0-based) is not the same",
+                                       expected[i], actual[i]);
+               }
+       }
+}
diff --git a/src/be/nikiroo/utils/test_code/ReplaceInputStreamTest.java b/src/be/nikiroo/utils/test_code/ReplaceInputStreamTest.java
new file mode 100644 (file)
index 0000000..d6a741f
--- /dev/null
@@ -0,0 +1,98 @@
+package be.nikiroo.utils.test_code;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import be.nikiroo.utils.IOUtils;
+import be.nikiroo.utils.ReplaceInputStream;
+import be.nikiroo.utils.test.TestCase;
+import be.nikiroo.utils.test.TestLauncher;
+
+public class ReplaceInputStreamTest extends TestLauncher {
+       public ReplaceInputStreamTest(String[] args) {
+               super("ReplaceInputStream test", args);
+
+               addTest(new TestCase("Simple InputStream, empty replace") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               ReplaceInputStream in = new ReplaceInputStream(
+                                               new ByteArrayInputStream(expected), new byte[0],
+                                               new byte[0]);
+                               checkArrays(this, "FIRST", in, expected);
+                       }
+               });
+
+               addTest(new TestCase("Simple InputStream, simple replace") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               ReplaceInputStream in = new ReplaceInputStream(
+                                               new ByteArrayInputStream(expected), new byte[] { 0 },
+                                               new byte[] { 10 });
+
+                               checkArrays(this, "FIRST", in, new byte[] { 42, 12, 10, 127 });
+                       }
+               });
+
+               addTest(new TestCase("Simple byte array reading, 3/4 replace") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               ReplaceInputStream in = new ReplaceInputStream(
+                                               new ByteArrayInputStream(expected), new byte[] { 12, 0,
+                                                               127 }, new byte[] { 10, 10, 10 });
+
+                               checkArrays(this, "FIRST", in, new byte[] { 42, 10, 10, 10 });
+                       }
+               });
+
+               addTest(new TestCase("Simple byte array reading, longer replace") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               ReplaceInputStream in = new ReplaceInputStream(
+                                               new ByteArrayInputStream(expected), new byte[] { 0 },
+                                               new byte[] { 10, 10, 10 });
+
+                               // TODO NOT OK!!
+                               System.out.println();
+                               for (int i = 0; i < expected.length; i++) {
+                                       System.out.println("expected[" + i + "] = " + expected[i]);
+                               }
+                               byte[] actual = IOUtils.readSmallStream(in).getBytes("UTF-8");
+                               for (int i = 0; i < actual.length; i++) {
+                                       System.out.println("actual[" + i + "] = " + actual[i]);
+                               }
+                               System.exit(1);
+                               //
+
+                               checkArrays(this, "FIRST", in, new byte[] { 42, 12, 10, 10, 10,
+                                               127 });
+                       }
+               });
+
+               addTest(new TestCase("Simple byte array reading, shorter replace") {
+                       @Override
+                       public void test() throws Exception {
+                               byte[] expected = new byte[] { 42, 12, 0, 127 };
+                               ReplaceInputStream in = new ReplaceInputStream(
+                                               new ByteArrayInputStream(expected), new byte[] { 42,
+                                                               12, 0 }, new byte[] { 10 });
+                               checkArrays(this, "FIRST", in, new byte[] { 10, 127 });
+                       }
+               });
+       }
+
+       static void checkArrays(TestCase test, String prefix, InputStream in,
+                       byte[] expected) throws Exception {
+               byte[] actual = IOUtils.toByteArray(in);
+               test.assertEquals("The " + prefix
+                               + " resulting array has not the correct number of items",
+                               expected.length, actual.length);
+               for (int i = 0; i < actual.length; i++) {
+                       test.assertEquals("Item " + i + " (0-based) is not the same",
+                                       expected[i], actual[i]);
+               }
+       }
+}
index 01766ac031535b33f04886ba6405dd2e6e4688ec..24d6bba5fd908efe3b18750a8027f213d5651fe5 100644 (file)
@@ -33,7 +33,9 @@ public class Test extends TestLauncher {
                addSeries(new StringUtilsTest(args));
                addSeries(new TempFilesTest(args));
                addSeries(new CryptUtilsTest(args));
+               addSeries(new BufferedInputStreamTest(args));
                addSeries(new NextableInputStreamTest(args));
+               addSeries(new ReplaceInputStreamTest(args));
 
                // TODO: test cache and downloader
                Cache cache = null;