it now compiles
[nikiroo-utils.git] / src / be / nikiroo / utils / serial / SerialUtils.java
index e88337b0a7f68ac03fd10ce2696909bb0cf8a187..6a628f3d706563f4140a33e949c39127522c7d2b 100644 (file)
@@ -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,11 +63,13 @@ 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, "\n");
                                try {
                                        for (int i = 0; true; i++) {
                                                Object item = Array.get(value, i);
@@ -76,33 +83,32 @@ public class SerialUtils {
                                                                                .getMessage());
                                                        }
                                                }
-                                               write(out,"\n");
+                                               write(out, "\n");
                                        }
                                } 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('\n'));
 
                                try {
+                                       List<Object> list = new ArrayList<Object>();
+                                       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 +119,34 @@ 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 +159,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 +181,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 +247,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 +470,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 +614,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