+
+ // Array types:
+ customTypes.put("[]", new CustomSerializer() {
+ @Override
+ protected void toStream(OutputStream out, Object value)
+ throws IOException {
+
+ String type = value.getClass().getCanonicalName();
+ type = type.substring(0, type.length() - 2); // remove the []
+
+ write(out, type);
+ try {
+ for (int i = 0; true; i++) {
+ Object item = Array.get(value, i);
+
+ // encode it normally if direct value
+ write(out, "\r");
+ if (!SerialUtils.encode(out, item)) {
+ try {
+ write(out, "B64:");
+ OutputStream out64 = new Base64OutputStream(
+ out, true);
+ new Exporter(out64).append(item);
+ out64.flush();
+ } catch (NotSerializableException e) {
+ throw new UnknownFormatConversionException(e
+ .getMessage());
+ }
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Done.
+ }
+ }
+
+ @Override
+ protected Object fromStream(InputStream in) throws IOException {
+ NextableInputStream stream = new NextableInputStream(in,
+ new NextableInputStreamStep('\r'));
+
+ 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(type), list.size());
+ for (int i = 0; i < list.size(); i++) {
+ Array.set(array, i, list.get(i));
+ }
+
+ return array;
+ } catch (Exception e) {
+ if (e instanceof IOException) {
+ throw (IOException) e;
+ }
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ @Override
+ protected String getType() {
+ return "[]";
+ }
+ });
+
+ // URL:
+ customTypes.put("java.net.URL", new CustomSerializer() {
+ @Override
+ protected void toStream(OutputStream out, Object value)
+ throws IOException {
+ String val = "";
+ if (value != null) {
+ val = ((URL) value).toString();
+ }
+
+ out.write(StringUtils.getBytes(val));
+ }
+
+ @Override
+ protected Object fromStream(InputStream in) throws IOException {
+ String val = IOUtils.readSmallStream(in);
+ if (!val.isEmpty()) {
+ return new URL(val);
+ }
+
+ return null;
+ }
+
+ @Override
+ protected String getType() {
+ return "java.net.URL";
+ }
+ });
+
+ // Images (this is currently the only supported image type by default)
+ customTypes.put("be.nikiroo.utils.Image", new CustomSerializer() {
+ @Override
+ protected void toStream(OutputStream out, Object value)
+ throws IOException {
+ Image img = (Image) value;
+ OutputStream encoded = new Base64OutputStream(out, true);
+ try {
+ InputStream in = img.newInputStream();
+ try {
+ IOUtils.write(in, encoded);
+ } finally {
+ in.close();
+ }
+ } finally {
+ encoded.flush();
+ // Cannot close!
+ }
+ }
+
+ @Override
+ protected String getType() {
+ return "be.nikiroo.utils.Image";
+ }
+
+ @Override
+ protected Object fromStream(InputStream in) throws IOException {
+ try {
+ // Cannot close it!
+ InputStream decoded = new Base64InputStream(in, false);
+ return new Image(decoded);
+ } catch (IOException e) {
+ throw new UnknownFormatConversionException(e.getMessage());
+ }
+ }
+ });