+ /**
+ * Decode the value back into the supported object type.
+ *
+ * @param in
+ * the encoded value
+ *
+ * @return the object
+ *
+ * @throws IOException
+ * in case of I/O error
+ */
+ public Object decode(InputStream in) throws IOException {
+ ReplaceInputStream replace = new ReplaceInputStream(in, //
+ new String[] { "\\\\", "\\n" }, //
+ new String[] { "\\", "\n" });
+
+ try {
+ NextableInputStream stream = new NextableInputStream(
+ replace.open(), new NextableInputStreamStep('^'));
+ try {
+ if (!stream.next()) {
+ throw new IOException(
+ "Cannot find the first custom^ element");
+ }
+
+ String custom = IOUtils.readSmallStream(stream);
+ if (!"custom".equals(custom)) {
+ throw new IOException(
+ "Cannot find the first custom^ element, it is: "
+ + custom + "^");
+ }
+
+ if (!stream.next()) {
+ throw new IOException("Cannot find the second custom^"
+ + getType() + " element");
+ }
+
+ String type = IOUtils.readSmallStream(stream);
+ if (!getType().equals(type)) {
+ throw new IOException("Cannot find the second custom^"
+ + getType() + " element, it is: custom^" + type
+ + "^");
+ }
+
+ if (!stream.nextAll()) {
+ throw new IOException("Cannot find the third custom^"
+ + getType() + "^value element");
+ }
+
+ return fromStream(stream);
+ } finally {
+ stream.close();
+ }
+ } finally {
+ replace.close(false);
+ }