From e570f7eb0843d1074c3fc46dd759125715d68df0 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 2 Jul 2017 00:46:09 +0200 Subject: [PATCH] Serial: enums and BufferedImages --- VERSION | 2 +- changelog | 6 ++ src/be/nikiroo/utils/StringUtils.java | 27 ++++++++- src/be/nikiroo/utils/serial/SerialUtils.java | 61 +++++++++++++++++++- src/be/nikiroo/utils/test/SerialTest.java | 18 ++++++ 5 files changed, 107 insertions(+), 7 deletions(-) diff --git a/VERSION b/VERSION index dc1e644..9c6d629 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.0 +1.6.1 diff --git a/changelog b/changelog index 4096205..771fac9 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,9 @@ +Version 1.6.1 +------------- + +Serialisation utilities + Now supports enums and BufferedImages + Version 1.6.0 ------------- diff --git a/src/be/nikiroo/utils/StringUtils.java b/src/be/nikiroo/utils/StringUtils.java index dc40e87..af69845 100644 --- a/src/be/nikiroo/utils/StringUtils.java +++ b/src/be/nikiroo/utils/StringUtils.java @@ -4,7 +4,6 @@ import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -17,7 +16,6 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; import java.util.regex.Pattern; -import java.util.zip.ZipInputStream; import javax.imageio.ImageIO; @@ -216,10 +214,33 @@ public class StringUtils { * in case of IO error */ static public String fromImage(BufferedImage image) throws IOException { + return fromImage(image, null); + } + + /** + * Convert the given {@link Image} object into a Base64 representation of + * the same {@link Image}. object. + * + * @param image + * the {@link Image} object to convert + * @param format + * the image format to use to serialise it (default is PNG) + * + * @return the Base64 representation + * + * @throws IOException + * in case of IO error + */ + static public String fromImage(BufferedImage image, String format) + throws IOException { + if (format == null) { + format = "png"; + } + String imageString = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); - ImageIO.write(image, "jpeg", out); + ImageIO.write(image, format, out); byte[] imageBytes = out.toByteArray(); imageString = new String(Base64.encodeBytes(imageBytes)); diff --git a/src/be/nikiroo/utils/serial/SerialUtils.java b/src/be/nikiroo/utils/serial/SerialUtils.java index 7bf1b17..c28faed 100644 --- a/src/be/nikiroo/utils/serial/SerialUtils.java +++ b/src/be/nikiroo/utils/serial/SerialUtils.java @@ -1,14 +1,18 @@ package be.nikiroo.utils.serial; +import java.awt.image.BufferedImage; +import java.io.IOException; import java.io.NotSerializableException; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.util.ArrayList; +import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.UnknownFormatConversionException; +import be.nikiroo.utils.StringUtils; + /** * Small class to help with serialisation. *

@@ -22,7 +26,6 @@ public class SerialUtils { static { customTypes = new HashMap(); - // TODO: add "default" custom serialisers if any (Bitmap?) // Array types: customTypes.put("[]", new CustomSerializer() { @@ -79,6 +82,32 @@ public class SerialUtils { } } }); + + // Images (this is currently the only supported image type by default) + customTypes.put("java.awt.image.BufferedImage", new CustomSerializer() { + @Override + protected String toString(Object value) { + try { + return StringUtils.fromImage((BufferedImage) value); + } catch (IOException e) { + throw new UnknownFormatConversionException(e.getMessage()); + } + } + + @Override + protected String getType() { + return "java.awt.image.BufferedImage"; + } + + @Override + protected Object fromString(String content) { + try { + return StringUtils.toImage(content); + } catch (IOException e) { + throw new UnknownFormatConversionException(e.getMessage()); + } + } + }); } /** @@ -188,8 +217,12 @@ public class SerialUtils { for (Field field : fields) { field.setAccessible(true); - if (field.getName().startsWith("this$")) { + if (field.getName().startsWith("this$") + || field.isSynthetic() + || (field.getModifiers() & Modifier.STATIC) == Modifier.STATIC) { // Do not keep this links of nested classes + // Do not keep synthetic fields + // Do not keep final fields continue; } @@ -244,6 +277,10 @@ public class SerialUtils { builder.append(value).append('F'); } else if (value instanceof Double) { builder.append(value).append('d'); + } else if (value instanceof Enum) { + String type = value.getClass().getCanonicalName(); + builder.append(type).append(".").append(((Enum) value).name()) + .append(";"); } else { return false; } @@ -286,6 +323,8 @@ public class SerialUtils { return Float.parseFloat(cut); } else if (encodedValue.endsWith("d")) { return Double.parseDouble(cut); + } else if (encodedValue.endsWith(";")) { + return decodeEnum(encodedValue); } else { return Integer.parseInt(encodedValue); } @@ -341,6 +380,22 @@ public class SerialUtils { return clazz; } + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static Enum decodeEnum(String escaped) { + // escaped: be.xxx.EnumType.VALUE; + int pos = escaped.lastIndexOf("."); + String type = escaped.substring(0, pos); + String name = escaped.substring(pos + 1, escaped.length() - 1); + + try { + return Enum.valueOf((Class) getClass(type), name); + } catch (Exception e) { + e.printStackTrace(); + throw new UnknownFormatConversionException("Unknown enum: <" + type + + "> " + name); + } + } + // aa bb -> "aa\tbb" private static void encodeString(StringBuilder builder, String raw) { builder.append('\"'); diff --git a/src/be/nikiroo/utils/test/SerialTest.java b/src/be/nikiroo/utils/test/SerialTest.java index 22d1206..517d286 100644 --- a/src/be/nikiroo/utils/test/SerialTest.java +++ b/src/be/nikiroo/utils/test/SerialTest.java @@ -100,6 +100,20 @@ class SerialTest extends TestLauncher { reencoded.replaceAll("@[0-9]*", "@REF")); } }); + + addTest(new TestCase("Enum Import/Export") { + @Override + public void test() throws Exception { + Object data = EnumToSend.FANFAN; + String encoded = new Exporter().append(data).toString(false); + Object redata = new Importer().read(encoded).getValue(); + String reencoded = new Exporter().append(redata) + .toString(false); + + assertEquals(encoded.replaceAll("@[0-9]*", "@REF"), + reencoded.replaceAll("@[0-9]*", "@REF")); + } + }); } class DataArray { @@ -146,4 +160,8 @@ class SerialTest extends TestLauncher { this.value = value; } } + + enum EnumToSend { + FANFAN, TULIPE, + } } -- 2.27.0