X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fserial%2FImporter.java;h=81814dfdbadf6a71ec2224d14be5926314bbd105;hb=505be508ae7d3fb48122be548b310a238cfb91eb;hp=f7fece064d6028d8fca8ff5a742cf997f52f52b2;hpb=08f80ac5fa60738d3ad74c4b5390a0b79ae313d4;p=fanfix.git diff --git a/src/be/nikiroo/utils/serial/Importer.java b/src/be/nikiroo/utils/serial/Importer.java index f7fece0..81814df 100644 --- a/src/be/nikiroo/utils/serial/Importer.java +++ b/src/be/nikiroo/utils/serial/Importer.java @@ -5,9 +5,11 @@ import java.io.InputStream; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; +import java.util.zip.GZIPInputStream; import be.nikiroo.utils.IOUtils; -import be.nikiroo.utils.StringUtils; +import be.nikiroo.utils.streams.Base64InputStream; +import be.nikiroo.utils.streams.BufferedInputStream; import be.nikiroo.utils.streams.NextableInputStream; import be.nikiroo.utils.streams.NextableInputStreamStep; @@ -87,13 +89,18 @@ 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()); - InputStream decoded = StringUtils.unbase64(stream.open(), - zip); + + InputStream decoded = stream.open(); + if (zip) { + decoded = new GZIPInputStream(decoded); + } + decoded = new Base64InputStream(decoded, false); + try { read(decoded); } finally { @@ -130,8 +137,9 @@ public class Importer { * @throws IOException * if the content cannot be read (for instance, corrupt data) */ - private boolean processLine(InputStream 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) { @@ -146,66 +154,108 @@ 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 + // 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 - String[] tab = line.substring("REF ".length()).split("@"); - String type = tab[0]; - tab = tab[1].split(":"); - String ref = tab[0]; - - link = map.containsKey(ref); - if (link) { - me = map.get(ref); - } else { - if (line.endsWith(":")) { - // construct - me = SerialUtils.createObject(type); + } + + // Custom objects + if (CustomSerializer.isCustom(in)) { + // not a field value but a direct value + me = SerialUtils.decode(in); + return false; + } + + // REF: (object) + if (in.startsWith("REF ")) { // REF: create/link self + // here, line is REF type@999:xxx + // xxx is optional + + NextableInputStream stream = new NextableInputStream(in, + new NextableInputStreamStep(':')); + try { + stream.next(); + + stream.skip("REF ".length()); + String header = IOUtils.readSmallStream(stream); + + String[] tab = header.split("@"); + if (tab.length != 2) { + throw new IOException("Bad import header line: " + header); + } + String type = tab[0]; + String ref = tab[1]; + + stream.nextAll(); + + link = map.containsKey(ref); + if (link) { + me = map.get(ref); + stream.end(); } else { - // direct value - int pos = line.indexOf(":"); - String encodedValue = line.substring(pos + 1); - me = SerialUtils.decode(encodedValue); + if (stream.eof()) { + // construct + me = SerialUtils.createObject(type); + } else { + // direct value + me = SerialUtils.decode(stream); + } + map.put(ref, me); } - map.put(ref, me); + } finally { + stream.close(false); } - } else { // FIELD: new field *or* direct simple value - if (line.endsWith(":")) { - // field value is compound - currentFieldName = line.substring(0, line.length() - 1); - } else if (line.startsWith(":") || !line.contains(":") - || line.startsWith("\"") || CustomSerializer.isCustom(line)) { - // not a field value but a direct value - me = SerialUtils.decode(line); - } else { - // field value is direct - int pos = line.indexOf(":"); - String fieldName = line.substring(0, pos); - String encodedValue = line.substring(pos + 1); - Object value = null; - value = SerialUtils.decode(encodedValue); - - // To support simple types directly: - if (me == null) { - me = value; + + return false; + } + + if (SerialUtils.isDirectValue(in)) { + // not a field value but a direct value + me = SerialUtils.decode(in); + return false; + } + + if (in.startsWith("^")) { + in.skip(1); + + NextableInputStream nameThenContent = new NextableInputStream(in, + new NextableInputStreamStep(':')); + + try { + nameThenContent.next(); + String fieldName = IOUtils.readSmallStream(nameThenContent); + + if (nameThenContent.nextAll() && !nameThenContent.eof()) { + // field value is direct or custom + Object value = null; + value = SerialUtils.decode(nameThenContent); + + // To support simple types directly: + if (me == null) { + me = value; + } else { + setField(fieldName, value); + } } else { - setField(fieldName, value); + // field value is compound + currentFieldName = fieldName; } + } finally { + nameThenContent.close(false); } + + return false; } - return false; + String line = IOUtils.readSmallStream(in); + throw new IOException("Line cannot be processed: <" + line + ">"); } private void setField(String name, Object value)