...
[nikiroo-utils.git] / src / be / nikiroo / utils / serial / CustomSerializer.java
1 package be.nikiroo.utils.serial;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6
7 import be.nikiroo.utils.IOUtils;
8 import be.nikiroo.utils.streams.NextableInputStream;
9 import be.nikiroo.utils.streams.NextableInputStreamStep;
10 import be.nikiroo.utils.streams.ReplaceInputStream;
11 import be.nikiroo.utils.streams.ReplaceOutputStream;
12
13 public abstract class CustomSerializer {
14
15 protected abstract void toStream(OutputStream out, Object value)
16 throws IOException;
17
18 protected abstract Object fromStream(InputStream in) throws IOException;
19
20 protected abstract String getType();
21
22 /**
23 * Encode the object into the given {@link OutputStream} if supported.
24 *
25 * @param out
26 * the builder to append to
27 * @param value
28 * the object to encode
29 *
30 * @throws IOException
31 * in case of I/O error
32 */
33 public void encode(OutputStream out, Object value) throws IOException {
34 ReplaceOutputStream replace = new ReplaceOutputStream(out, //
35 new String[] { "\\", "\n" }, //
36 new String[] { "\\\\", "\\n" });
37 try {
38 SerialUtils.write(replace, "custom^");
39 SerialUtils.write(replace, getType());
40 SerialUtils.write(replace, "^");
41 toStream(replace, value);
42 } finally {
43 replace.close(false);
44 }
45 }
46
47 public Object decode(InputStream in) throws IOException {
48 ReplaceInputStream replace = new ReplaceInputStream(in, //
49 new String[] { "\\\\", "\\n" }, //
50 new String[] { "\\", "\n" });
51
52 try {
53 NextableInputStream stream = new NextableInputStream(
54 replace.open(), new NextableInputStreamStep('^'));
55 try {
56 if (!stream.next()) {
57 throw new IOException(
58 "Cannot find the first custom^ element");
59 }
60
61 String custom = IOUtils.readSmallStream(stream);
62 if (!"custom".equals(custom)) {
63 throw new IOException(
64 "Cannot find the first custom^ element, it is: "
65 + custom + "^");
66 }
67
68 if (!stream.next()) {
69 throw new IOException("Cannot find the second custom^"
70 + getType() + " element");
71 }
72
73 String type = IOUtils.readSmallStream(stream);
74 if (!getType().equals(type)) {
75 throw new IOException("Cannot find the second custom^"
76 + getType() + " element, it is: custom^" + type
77 + "^");
78 }
79
80 if (!stream.nextAll()) {
81 throw new IOException("Cannot find the third custom^"
82 + getType() + "^value element");
83 }
84
85 return fromStream(stream);
86 } finally {
87 stream.close();
88 }
89 } finally {
90 replace.close(false);
91 }
92 }
93
94 public static boolean isCustom(String encodedValue) {
95 int pos1 = encodedValue.indexOf('^');
96 int pos2 = encodedValue.indexOf('^', pos1 + 1);
97
98 return pos1 >= 0 && pos2 >= 0 && encodedValue.startsWith("custom^");
99 }
100
101 public static String typeOf(String encodedValue) {
102 int pos1 = encodedValue.indexOf('^');
103 int pos2 = encodedValue.indexOf('^', pos1 + 1);
104 String type = encodedValue.substring(pos1 + 1, pos2);
105
106 return type;
107 }
108
109 public static String contentOf(String encodedValue) {
110 int pos1 = encodedValue.indexOf('^');
111 int pos2 = encodedValue.indexOf('^', pos1 + 1);
112 String encodedContent = encodedValue.substring(pos2 + 1);
113
114 return encodedContent;
115 }
116 }