e5539c0fdce8669592a932c819d458b0717c1613
[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
38 try {
39 SerialUtils.write(replace, "custom^");
40 SerialUtils.write(replace, getType());
41 SerialUtils.write(replace, "^");
42 toStream(replace, value);
43 } finally {
44 replace.close(false);
45 }
46 }
47
48 public Object decode(InputStream in) throws IOException {
49 ReplaceInputStream replace = new ReplaceInputStream(in, //
50 new String[] { "\\\\", "\\n" }, //
51 new String[] { "\\", "\n" });
52
53 try {
54 NextableInputStream stream = new NextableInputStream(
55 replace.open(), new NextableInputStreamStep('^'));
56 try {
57 if (!stream.next()) {
58 throw new IOException(
59 "Cannot find the first custom^ element");
60 }
61
62 String custom = IOUtils.readSmallStream(stream);
63 if (!"custom".equals(custom)) {
64 throw new IOException(
65 "Cannot find the first custom^ element, it is: "
66 + custom + "^");
67 }
68
69 if (!stream.next()) {
70 throw new IOException("Cannot find the second custom^"
71 + getType() + " element");
72 }
73
74 String type = IOUtils.readSmallStream(stream);
75 if (!getType().equals(type)) {
76 throw new IOException("Cannot find the second custom^"
77 + getType() + " element, it is: custom^" + type
78 + "^");
79 }
80
81 if (!stream.nextAll()) {
82 throw new IOException("Cannot find the third custom^"
83 + getType() + "^value element");
84 }
85
86 return fromStream(stream);
87 } finally {
88 stream.close();
89 }
90 } finally {
91 replace.close(false);
92 }
93 }
94
95 public static boolean isCustom(String encodedValue) {
96 int pos1 = encodedValue.indexOf('^');
97 int pos2 = encodedValue.indexOf('^', pos1 + 1);
98
99 return pos1 >= 0 && pos2 >= 0 && encodedValue.startsWith("custom^");
100 }
101
102 public static String typeOf(String encodedValue) {
103 int pos1 = encodedValue.indexOf('^');
104 int pos2 = encodedValue.indexOf('^', pos1 + 1);
105 String type = encodedValue.substring(pos1 + 1, pos2);
106
107 return type;
108 }
109
110 public static String contentOf(String encodedValue) {
111 int pos1 = encodedValue.indexOf('^');
112 int pos2 = encodedValue.indexOf('^', pos1 + 1);
113 String encodedContent = encodedValue.substring(pos2 + 1);
114
115 return encodedContent;
116 }
117 }