X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fserial%2FSerialUtils.java;h=b083e3461e2b63d3c6d2a6e702d8cf60ef5d32b0;hb=4d31956549a05df6dca42d58a1150a348a58dcd1;hp=e88337b0a7f68ac03fd10ce2696909bb0cf8a187;hpb=143a64f4c6804d0cd17595ffcf7a44f4a151ffdc;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/serial/SerialUtils.java b/src/be/nikiroo/utils/serial/SerialUtils.java index e88337b..b083e34 100644 --- a/src/be/nikiroo/utils/serial/SerialUtils.java +++ b/src/be/nikiroo/utils/serial/SerialUtils.java @@ -1,5 +1,6 @@ package be.nikiroo.utils.serial; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.NotSerializableException; @@ -16,7 +17,11 @@ import java.util.List; import java.util.Map; import java.util.UnknownFormatConversionException; +import be.nikiroo.utils.IOUtils; import be.nikiroo.utils.Image; +import be.nikiroo.utils.NextableInputStream; +import be.nikiroo.utils.NextableInputStreamStep; +import be.nikiroo.utils.StringUtils; /** * Small class to help with serialisation. @@ -58,51 +63,55 @@ public class SerialUtils { @Override protected void toStream(OutputStream out, Object value) throws IOException { + // TODO: we use \n to separate, and b64 to un-\n -- but we could + // use \\n ? String type = value.getClass().getCanonicalName(); type = type.substring(0, type.length() - 2); // remove the [] - write(out,type); - write(out,"\n"); + write(out, type); + write(out, "\r"); try { for (int i = 0; true; i++) { Object item = Array.get(value, i); // encode it normally if direct value if (!SerialUtils.encode(out, item)) { try { - // TODO: use ZIP: if not? - new Exporter(out).append(item); + // TODO: bad escaping? + write(out, "B64:"); + OutputStream bout = StringUtils.base64(out, + false, false); + new Exporter(bout).append(item); } catch (NotSerializableException e) { throw new UnknownFormatConversionException(e .getMessage()); } } - write(out,"\n"); + write(out, "\r"); } } catch (ArrayIndexOutOfBoundsException e) { // Done. } } - @Override - protected String getType() { - return "[]"; - } - @Override protected Object fromStream(InputStream in) throws IOException { - return null; - } - - @Override - protected Object fromString(String content) throws IOException { - String[] tab = content.split("\n"); + NextableInputStream stream = new NextableInputStream(in, + new NextableInputStreamStep('\r')); try { + List list = new ArrayList(); + stream.next(); + String type = IOUtils.readSmallStream(stream); + + while (stream.next()) { + Object value = new Importer().read(stream).getValue(); + list.add(value); + } + Object array = Array.newInstance( - SerialUtils.getClass(tab[0]), tab.length - 1); - for (int i = 1; i < tab.length; i++) { - Object value = new Importer().read(tab[i]).getValue(); - Array.set(array, i - 1, value); + SerialUtils.getClass(type), list.size()); + for (int i = 0; i < list.size(); i++) { + Array.set(array, i, list.get(i)); } return array; @@ -113,23 +122,33 @@ public class SerialUtils { throw new IOException(e.getMessage()); } } + + @Override + protected String getType() { + return "[]"; + } }); // URL: customTypes.put("java.net.URL", new CustomSerializer() { @Override - protected String toString(Object value) { + protected void toStream(OutputStream out, Object value) + throws IOException { + String val = ""; if (value != null) { - return ((URL) value).toString(); + val = ((URL) value).toString(); } - return null; + + out.write(val.getBytes("UTF-8")); } @Override - protected Object fromString(String content) throws IOException { - if (content != null) { - return new URL(content); + protected Object fromStream(InputStream in) throws IOException { + String val = IOUtils.readSmallStream(in); + if (!val.isEmpty()) { + return new URL(val); } + return null; } @@ -142,8 +161,20 @@ public class SerialUtils { // Images (this is currently the only supported image type by default) customTypes.put("be.nikiroo.utils.Image", new CustomSerializer() { @Override - protected String toString(Object value) { - return ((Image) value).toBase64(); + protected void toStream(OutputStream out, Object value) + throws IOException { + Image img = (Image) value; + OutputStream encoded = StringUtils.base64(out, false, false); + try { + InputStream in = img.newInputStream(); + try { + IOUtils.write(in, encoded); + } finally { + in.close(); + } + } finally { + encoded.close(); + } } @Override @@ -152,9 +183,9 @@ public class SerialUtils { } @Override - protected Object fromString(String content) { + protected Object fromStream(InputStream in) throws IOException { try { - return new Image(content); + return new Image(in); } catch (IOException e) { throw new UnknownFormatConversionException(e.getMessage()); } @@ -218,7 +249,7 @@ public class SerialUtils { ctor = clazz.getDeclaredConstructor(classes .toArray(new Class[] {})); } catch (NoSuchMethodException nsme) { - // TODO: it seems e do not always need a parameter for each + // TODO: it seems we do not always need a parameter for each // level, so we currently try "ALL" levels or "FIRST" level // only -> we should check the actual rule and use it ctor = clazz.getDeclaredConstructor(classes.get(0)); @@ -441,7 +472,14 @@ public class SerialUtils { // custom:TYPE_NAME:"content is String-encoded" String type = CustomSerializer.typeOf(encodedValue); if (customTypes.containsKey(type)) { - return customTypes.get(type).decode(encodedValue); + // TODO: we should start with a stream + InputStream streamEncodedValue = new ByteArrayInputStream( + encodedValue.getBytes("UTF-8")); + try { + return customTypes.get(type).decode(streamEncodedValue); + } finally { + streamEncodedValue.close(); + } } throw new IOException("Unknown custom type: " + type); } else if (encodedValue.equals("NULL") @@ -578,7 +616,7 @@ public class SerialUtils { static void encodeString(OutputStream out, InputStream raw) throws IOException { out.write('\"'); - byte buffer[] = new byte[4069]; + byte buffer[] = new byte[4096]; for (int len = 0; (len = raw.read(buffer)) > 0;) { for (int i = 0; i < len; i++) { // TODO: not 100% correct, look up howto for UTF-8