From: Niki Roo Date: Fri, 26 Apr 2019 22:33:32 +0000 (+0200) Subject: ReplaceInputStream (wip) X-Git-Tag: nikiroo-utils-4.7.3~74 X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=6ef54b36380b9d123bbdb6b4056cf64b7489225e;p=nikiroo-utils.git ReplaceInputStream (wip) --- diff --git a/src/be/nikiroo/utils/BufferedInputStream.java b/src/be/nikiroo/utils/BufferedInputStream.java index 4a8a8c3..9b95574 100644 --- a/src/be/nikiroo/utils/BufferedInputStream.java +++ b/src/be/nikiroo/utils/BufferedInputStream.java @@ -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 index 0000000..5ce9ef3 --- /dev/null +++ b/src/be/nikiroo/utils/ReplaceInputStream.java @@ -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 index 0000000..e2fc80b --- /dev/null +++ b/src/be/nikiroo/utils/test_code/BufferedInputStreamTest.java @@ -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 index 0000000..d6a741f --- /dev/null +++ b/src/be/nikiroo/utils/test_code/ReplaceInputStreamTest.java @@ -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]); + } + } +} diff --git a/src/be/nikiroo/utils/test_code/Test.java b/src/be/nikiroo/utils/test_code/Test.java index 01766ac..24d6bba 100644 --- a/src/be/nikiroo/utils/test_code/Test.java +++ b/src/be/nikiroo/utils/test_code/Test.java @@ -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;