package org.basex.io.serial;
import static org.basex.query.util.Err.*;
import static org.basex.util.Token.*;
import java.io.IOException;
import java.io.OutputStream;
import org.basex.query.item.Item;
import org.basex.util.Util;
/**
* This class serializes data as described in the
* <a href="http://jsonml.org">JsonML</a> specification.
* JsonML can be used to transform any XML document to JSON and back.
* Note, however, that namespaces, comments and processing instructions will be
* discarded in the transformation process. More details are found in the
* <a href="http://jsonml.org/XML/">JsonML documentation</a>.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class JsonMLSerializer extends OutputSerializer {
/** Indicates serialized attributes. */
private boolean att;
/**
* Constructor.
* @param os output stream reference
* @param props serialization properties
* @throws IOException I/O exception
*/
public JsonMLSerializer(final OutputStream os, final SerializerProp props)
throws IOException {
super(os, props);
}
@Override
protected void startOpen(final byte[] name) throws IOException {
if(level != 0) {
print(',');
indent();
}
print('[');
print('"');
for(final byte ch : local(name)) code(ch);
print('"');
att = false;
}
@Override
public void attribute(final byte[] name, final byte[] value)
throws IOException {
print(", ");
if(!att) {
print("{");
att = true;
}
print('"');
for(final byte ch : name) code(ch);
print("\":\"");
for(final byte ch : value) code(ch);
print("\"");
}
@Override
public void namespace(final byte[] n, final byte[] v) throws IOException {
}
@Override
protected void finishOpen() throws IOException {
if(att) print("}");
}
@Override
public void finishText(final byte[] text) throws IOException {
print(',');
indent();
print('"');
for(final byte ch : text) code(ch);
print('"');
}
@Override
protected void finishEmpty() throws IOException {
finishOpen();
print(']');
}
@Override
protected void finishClose() throws IOException {
print(']');
}
@Override
protected void code(final int ch) throws IOException {
switch(ch) {
case '\b': print("\\b"); break;
case '\f': print("\\f"); break;
case '\n': print("\\n"); break;
case '\r': print("\\r"); break;
case '\t': print("\\t"); break;
case '"': print("\\\""); break;
case '/': print("\\/"); break;
case '\\': print("\\\\"); break;
default: print(ch); break;
}
}
@Override
public void finishComment(final byte[] value) throws IOException {
}
@Override
public void finishPi(final byte[] name, final byte[] value)
throws IOException {
}
@Override
public void finishItem(final Item value) throws IOException {
error("Items cannot be serialized");
}
/**
* Raises an error with the specified message.
* @param msg error message
* @param ext error details
* @throws IOException I/O exception
*/
private static void error(final String msg, final Object... ext)
throws IOException {
throw JSONSER.thrwSerial(Util.inf(msg, ext));
}
}