X-Git-Url: https://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fserial%2FImporter.java;h=810d694db5a316a4aca1290b5b31650312005f0d;hb=95c5b4f9f95b6b934622393d851fc7e67966a8c2;hp=e7285c42ca329c7a6e84c73fba0189c228493781;hpb=f4053377fa15da2f11e82955bfab86e673fa371c;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/serial/Importer.java b/src/be/nikiroo/utils/serial/Importer.java index e7285c4..810d694 100644 --- a/src/be/nikiroo/utils/serial/Importer.java +++ b/src/be/nikiroo/utils/serial/Importer.java @@ -1,12 +1,15 @@ package be.nikiroo.utils.serial; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import java.util.Scanner; +import be.nikiroo.utils.IOUtils; import be.nikiroo.utils.StringUtils; +import be.nikiroo.utils.streams.NextableInputStream; +import be.nikiroo.utils.streams.NextableInputStreamStep; /** * A simple class that can accept the output of {@link Exporter} to recreate @@ -43,7 +46,7 @@ public class Importer { * content, or a number of lines of it (any given line MUST be * complete though) and accumulate it with the already present data. * - * @param data + * @param in * the data to parse * * @return itself so it can be chained @@ -58,31 +61,50 @@ public class Importer { * if a class described in the serialised data cannot be found * @throws IOException * if the content cannot be read (for instance, corrupt data) + * @throws NullPointerException + * if the stream is empty */ - public Importer read(String data) throws NoSuchFieldException, - NoSuchMethodException, ClassNotFoundException, IOException { + public Importer read(InputStream in) throws NoSuchFieldException, + NoSuchMethodException, ClassNotFoundException, IOException, + NullPointerException { + + NextableInputStream stream = new NextableInputStream(in, + new NextableInputStreamStep('\n')); - Scanner scan = new Scanner(data); try { - scan.useDelimiter("\n"); - while (scan.hasNext()) { - String line = scan.next(); + if (in == null) { + throw new NullPointerException("InputStream is null"); + } + + boolean first = true; + while (stream.next()) { + if (stream.eof()) { + if (first) { + throw new NullPointerException( + "InputStream empty, normal termination"); + } + return this; + } + first = false; + + boolean zip = stream.startsWiths("ZIP:"); + boolean b64 = stream.startsWiths("B64:"); - if (line.startsWith("ZIP:")) { + if (zip || b64) { + stream.skip("XXX:".length()); + InputStream decoded = StringUtils.unbase64(stream.open(), + zip); try { - line = StringUtils.unzip64(line.substring("ZIP:" - .length())); - } catch (IOException e) { - throw new IOException( - "Internal error when decoding ZIP content: input may be corrupt"); + read(decoded); + } finally { + decoded.close(); } - read(line); } else { - processLine(line); + processLine(stream); } } } finally { - scan.close(); + stream.close(false); } return this; @@ -92,7 +114,7 @@ public class Importer { * Read a single (whole) line of serialised data into this {@link Importer} * and accumulate it with the already present data. * - * @param line + * @param in * the line to parse * * @return TRUE if we are just done with one object or sub-object @@ -108,11 +130,12 @@ public class Importer { * @throws IOException * if the content cannot be read (for instance, corrupt data) */ - private boolean processLine(String line) throws NoSuchFieldException, + private boolean processLine(InputStream in) throws NoSuchFieldException, NoSuchMethodException, ClassNotFoundException, IOException { + // Defer to latest child if any if (child != null) { - if (child.processLine(line)) { + if (child.processLine(in)) { if (currentFieldName != null) { setField(currentFieldName, child.getValue()); currentFieldName = null; @@ -123,6 +146,13 @@ public class Importer { return false; } + // TODO use the stream, Luke + String line = IOUtils.readSmallStream(in); + + if (line.isEmpty()) { + return false; + } + if (line.equals("{")) { // START: new child if needed if (link != null) { child = new Importer(map); @@ -141,7 +171,12 @@ public class Importer { } else { if (line.endsWith(":")) { // construct - me = SerialUtils.createObject(type); + try { + me = SerialUtils.createObject(type); + } catch (NoSuchMethodException e) { + System.out.println("LINE: <" + line + ">"); + throw e; + } } else { // direct value int pos = line.indexOf(":");