code cleanup + fixes
authorNiki Roo <niki@nikiroo.be>
Mon, 29 Apr 2019 21:58:39 +0000 (23:58 +0200)
committerNiki Roo <niki@nikiroo.be>
Mon, 29 Apr 2019 21:58:39 +0000 (23:58 +0200)
src/be/nikiroo/utils/serial/CustomSerializer.java
src/be/nikiroo/utils/serial/Importer.java
src/be/nikiroo/utils/streams/BufferedInputStream.java
src/be/nikiroo/utils/test_code/NextableInputStreamTest.java

index fe63f71903619c6ae49f7fa8d765ddf0b2858f0a..496fcb16baceaa3123386f612feaa899aff52f6a 100644 (file)
@@ -171,7 +171,7 @@ public abstract class CustomSerializer {
        }
 
        public static boolean isCustom(BufferedInputStream in) throws IOException {
-               return in.startsWiths("custom^");
+               return in.startsWith("custom^");
        }
 
        public static String typeOf(String encodedValue) {
index 5b75d313bc465918feb18786f90badb163ece6be..6718fb8ecf623b8bd66350be1d1f51685836b2cf 100644 (file)
@@ -89,8 +89,8 @@ public class Importer {
                                }
                                first = false;
 
-                               boolean zip = stream.startsWiths("ZIP:");
-                               boolean b64 = stream.startsWiths("B64:");
+                               boolean zip = stream.startsWith("ZIP:");
+                               boolean b64 = stream.startsWith("B64:");
 
                                if (zip || b64) {
                                        stream.skip("XXX:".length());
@@ -137,8 +137,9 @@ public class Importer {
         * @throws IOException
         *             if the content cannot be read (for instance, corrupt data)
         */
-       private boolean processLine(BufferedInputStream in) throws NoSuchFieldException,
-                       NoSuchMethodException, ClassNotFoundException, IOException {
+       private boolean processLine(BufferedInputStream in)
+                       throws NoSuchFieldException, NoSuchMethodException,
+                       ClassNotFoundException, IOException {
 
                // Defer to latest child if any
                if (child != null) {
@@ -153,16 +154,34 @@ public class Importer {
                        return false;
                }
 
-               // TODO use the stream, Luke
-               String line = IOUtils.readSmallStream(in);
-
-               if (line.equals("{")) { // START: new child if needed
+               // Start/Stop object
+               if (in.is("{")) { // START: new child if needed
                        if (link != null) {
                                child = new Importer(map);
                        }
-               } else if (line.equals("}")) { // STOP: report self to parent
+                       in.end();
+                       return false;
+               } else if (in.is("}")) { // STOP: report self to parent
+                       in.end();
                        return true;
-               } else if (line.startsWith("REF ")) { // REF: create/link self
+               }
+
+               // Custom objects
+               if (CustomSerializer.isCustom(in)) {
+                       // not a field value but a direct value
+                       String line = IOUtils.readSmallStream(in);
+                       me = SerialUtils.decode(line);
+                       return false;
+               }
+
+               // TODO use the stream, Luke
+               // .. at least for REF
+               String line = IOUtils.readSmallStream(in);
+
+               if (line.startsWith("REF ")) { // REF: create/link self
+                       // TODO: here, line is REF type@999:xxx
+                       // xxx is optional
+                       // note: use .end() when containsKey(ref)
                        String[] tab = line.substring("REF ".length()).split("@");
                        String type = tab[0];
                        tab = tab[1].split(":");
@@ -188,7 +207,7 @@ public class Importer {
                                // field value is compound
                                currentFieldName = line.substring(0, line.length() - 1);
                        } else if (line.startsWith(":") || !line.contains(":")
-                                       || line.startsWith("\"") || CustomSerializer.isCustom(line)) {
+                                       || line.startsWith("\"")) {
                                // not a field value but a direct value
                                me = SerialUtils.decode(line);
                        } else {
index 336dba4000c54a26b25e33d0e84a2d8f46b2a01d..d1f53dfe26b0a84367a56a61815477c1c321073e 100644 (file)
@@ -174,7 +174,7 @@ public class BufferedInputStream extends InputStream {
         */
        public boolean is(byte[] search) throws IOException {
                if (startsWith(search)) {
-                       return stop == search.length;
+                       return (stop - start) == search.length;
                }
 
                return false;
@@ -196,7 +196,7 @@ public class BufferedInputStream extends InputStream {
         *             in case of I/O error or if the size of the search term is
         *             greater than the internal buffer
         */
-       public boolean startsWiths(String search) throws IOException {
+       public boolean startsWith(String search) throws IOException {
                return startsWith(StringUtils.getBytes(search));
        }
 
@@ -204,6 +204,9 @@ public class BufferedInputStream extends InputStream {
         * Check if the current content (what will be read next) starts with the
         * given search term.
         * <p>
+        * An empty string will always return true (unless the stream is closed,
+        * which would throw an {@link IOException}).
+        * <p>
         * Note: the search term size <b>must</b> be smaller or equal the internal
         * buffer size.
         * 
@@ -232,7 +235,7 @@ public class BufferedInputStream extends InputStream {
                if (available() >= search.length) {
                        // Easy path
                        return StreamUtils.startsWith(search, buffer, start, stop);
-               } else if (!eof) {
+               } else if (in != null && !eof) {
                        // Harder path
                        if (buffer2 == null && buffer.length == originalBuffer.length) {
                                buffer2 = Arrays.copyOf(buffer, buffer.length * 2);
@@ -280,6 +283,24 @@ public class BufferedInputStream extends InputStream {
                return !hasMoreData();
        }
 
+       /**
+        * Read the whole {@link InputStream} until the end and return the number of
+        * bytes read.
+        * 
+        * @return the number of bytes read
+        * 
+        * @throws IOException
+        *             in case of I/O error
+        */
+       public long end() throws IOException {
+               long skipped = 0;
+               while (hasMoreData()) {
+                       skipped += skip(buffer.length);
+               }
+
+               return skipped;
+       }
+
        @Override
        public int read() throws IOException {
                checkClose();
index 70123b99ee7095be9764b0605c844284665031e2..f8031f0d3b040035d77087b51e3534052fd801ae 100644 (file)
@@ -103,10 +103,9 @@ public class NextableInputStreamTest extends TestLauncher {
                                                new NextableInputStreamStep(12));
 
                                checkNext(this, "FIRST", in, new byte[] { 42 });
-                               checkNextAll(this, "REST", in,
-                                               new byte[] { 0, 127, 12, 51, 11, 12 });
-                               assertEquals("The stream still has some data", false,
-                                               in.next());
+                               checkNextAll(this, "REST", in, new byte[] { 0, 127, 12, 51, 11,
+                                               12 });
+                               assertEquals("The stream still has some data", false, in.next());
                        }
                });
 
@@ -146,8 +145,19 @@ public class NextableInputStreamTest extends TestLauncher {
                                NextableInputStream in = new NextableInputStream(data, null);
                                in.next();
 
+                               byte[] rest = new byte[] { 12, 51, 11, 12 };
+
                                in.skip(4);
-                               checkArrays(this, "ONLY", in, new byte[] { 12, 51, 11, 12 });
+                               assertEquals("STARTS_WITH OK_1", true, in.startsWith(rest));
+                               assertEquals("STARTS_WITH KO_1", false,
+                                               in.startsWith(new byte[] { 0 }));
+                               assertEquals("STARTS_WITH KO_2", false, in.startsWith(data));
+                               assertEquals("STARTS_WITH KO_3", false,
+                                               in.startsWith(new byte[] { 1, 2, 3 }));
+                               assertEquals("STARTS_WITH OK_2", true, in.startsWith(rest));
+                               assertEquals("READ REST", IOUtils.readSmallStream(in),
+                                               new String(rest));
+                               in.close();
                        }
                });
 
@@ -169,17 +179,21 @@ public class NextableInputStreamTest extends TestLauncher {
                                // no
                                assertEquals("It actually does not start with that", false,
                                                in.startsWith(new byte[] { 12 }));
-                               assertEquals("It actually does not start with that", false,
-                                               in.startsWith(
-                                                               new byte[] { 42, 12, 0, 127, 12, 51, 11, 11 }));
+                               assertEquals(
+                                               "It actually does not start with that",
+                                               false,
+                                               in.startsWith(new byte[] { 42, 12, 0, 127, 12, 51, 11,
+                                                               11 }));
 
                                // too big
                                try {
-                                       in.startsWith(
-                                                       new byte[] { 42, 12, 0, 127, 12, 51, 11, 12, 0 });
+                                       in.startsWith(new byte[] { 42, 12, 0, 127, 12, 51, 11, 12,
+                                                       0 });
                                        fail("Searching a prefix bigger than the array should throw an IOException");
                                } catch (IOException e) {
                                }
+
+                               in.close();
                        }
                });
 
@@ -193,24 +207,69 @@ public class NextableInputStreamTest extends TestLauncher {
 
                                // yes
                                assertEquals("It actually starts with that", true,
-                                               in.startsWiths("F"));
+                                               in.startsWith("F"));
                                assertEquals("It actually starts with that", true,
-                                               in.startsWiths("Fanfan et"));
+                                               in.startsWith("Fanfan et"));
                                assertEquals("It actually is the same text", true,
-                                               in.startsWiths(text));
+                                               in.startsWith(text));
 
                                // no
                                assertEquals("It actually does not start with that", false,
-                                               in.startsWiths("Toto"));
+                                               in.startsWith("Toto"));
                                assertEquals("It actually does not start with that", false,
-                                               in.startsWiths("Fanfan et Toto vont à la mee"));
+                                               in.startsWith("Fanfan et Toto vont à la mee"));
 
                                // too big
                                try {
-                                       in.startsWiths("Fanfan et Toto vont à la mer.");
+                                       in.startsWith("Fanfan et Toto vont à la mer.");
                                        fail("Searching a prefix bigger than the array should throw an IOException");
                                } catch (IOException e) {
                                }
+
+                               in.close();
+                       }
+               });
+
+               addTest(new TestCase("Starts With strings + steps") {
+                       @Override
+                       public void test() throws Exception {
+                               String data = "{\nREF: fanfan\n}";
+                               NextableInputStream in = new NextableInputStream(
+                                               data.getBytes("UTF-8"), new NextableInputStreamStep(
+                                                               '\n'));
+                               in.next();
+
+                               assertEquals("STARTS_WITH OK", true, in.startsWith("{"));
+                               in.skip(1);
+                               assertEquals("STARTS_WITH WHEN SPENT", false,
+                                               in.startsWith("{"));
+
+                               checkNext(this, "PARTIAL CONTENT", in,
+                                               "REF: fanfan".getBytes("UTF-8"));
+                       }
+               });
+
+               addTest(new TestCase("InputStream is(String)") {
+                       @Override
+                       public void test() throws Exception {
+                               String data = "{\nREF: fanfan\n}";
+                               NextableInputStream in = new NextableInputStream(
+                                               new ByteArrayInputStream(data.getBytes("UTF-8")),
+                                               new NextableInputStreamStep('\n'));
+
+                               in.next();
+                               assertEquals("Item 1 OK", true, in.is("{"));
+                               assertEquals("Item 1 KO_1", false, in.is("|"));
+                               assertEquals("Item 1 KO_2", false, in.is("{}"));
+                               in.skip(1);
+                               in.next();
+                               assertEquals("Item 2 OK", true, in.is("REF: fanfan"));
+                               assertEquals("Item 2 KO", false, in.is("REF: fanfan."));
+                               IOUtils.readSmallStream(in);
+                               in.next();
+                               assertEquals("Item 3 OK", true, in.is("}"));
+
+                               in.close();
                        }
                });
        }