...
[nikiroo-utils.git] / src / be / nikiroo / utils / serial / CustomSerializer.java
CommitLineData
db31c358
NR
1package be.nikiroo.utils.serial;
2
452f38c8 3import java.io.IOException;
68532958
NR
4import java.io.InputStream;
5import java.io.OutputStream;
452f38c8 6
dc41a952 7import be.nikiroo.utils.IOUtils;
52fb9a56
NR
8import be.nikiroo.utils.streams.NextableInputStream;
9import be.nikiroo.utils.streams.NextableInputStreamStep;
3b4319db
NR
10import be.nikiroo.utils.streams.ReplaceInputStream;
11import be.nikiroo.utils.streams.ReplaceOutputStream;
dc41a952 12
db31c358
NR
13public abstract class CustomSerializer {
14
68532958
NR
15 protected abstract void toStream(OutputStream out, Object value)
16 throws IOException;
db31c358 17
68532958 18 protected abstract Object fromStream(InputStream in) throws IOException;
db31c358
NR
19
20 protected abstract String getType();
21
5bc55b51 22 /**
143a64f4 23 * Encode the object into the given {@link OutputStream} if supported.
5bc55b51 24 *
68532958 25 * @param out
5bc55b51
NR
26 * the builder to append to
27 * @param value
28 * the object to encode
68532958 29 *
68532958
NR
30 * @throws IOException
31 * in case of I/O error
5bc55b51 32 */
3b4319db
NR
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 }
db31c358
NR
45 }
46
dc41a952 47 public Object decode(InputStream in) throws IOException {
3b4319db
NR
48 ReplaceInputStream replace = new ReplaceInputStream(in, //
49 new String[] { "\\\\", "\\n" }, //
50 new String[] { "\\", "\n" });
dc41a952
NR
51
52 try {
3b4319db
NR
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();
dc41a952 88 }
dc41a952 89 } finally {
3b4319db 90 replace.close(false);
dc41a952 91 }
db31c358
NR
92 }
93
94 public static boolean isCustom(String encodedValue) {
f4053377
NR
95 int pos1 = encodedValue.indexOf('^');
96 int pos2 = encodedValue.indexOf('^', pos1 + 1);
db31c358 97
f4053377 98 return pos1 >= 0 && pos2 >= 0 && encodedValue.startsWith("custom^");
db31c358
NR
99 }
100
101 public static String typeOf(String encodedValue) {
f4053377
NR
102 int pos1 = encodedValue.indexOf('^');
103 int pos2 = encodedValue.indexOf('^', pos1 + 1);
db31c358
NR
104 String type = encodedValue.substring(pos1 + 1, pos2);
105
106 return type;
107 }
108
109 public static String contentOf(String encodedValue) {
f4053377
NR
110 int pos1 = encodedValue.indexOf('^');
111 int pos2 = encodedValue.indexOf('^', pos1 + 1);
db31c358
NR
112 String encodedContent = encodedValue.substring(pos2 + 1);
113
114 return encodedContent;
115 }
116}