blob: 47a4eabb5794dd29e4edf9c5ef6a239598b3e047 [file] [log] [blame]
package aQute.lib.json;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
public class StringHandler extends Handler {
@Override
void encode(Encoder app, Object object, Map<Object,Type> visited) throws IOException {
string(app, object.toString());
}
static void string(Appendable app, String s) throws IOException {
app.append('"');
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '"' :
app.append("\\\"");
break;
case '\\' :
app.append("\\\\");
break;
case '\b' :
app.append("\\b");
break;
case '\f' :
app.append("\\f");
break;
case '\n' :
app.append("\\n");
break;
case '\r' :
app.append("\\r");
break;
case '\t' :
app.append("\\t");
break;
default :
if (Character.isISOControl(c)) {
app.append("\\u");
app.append("0123456789ABCDEF".charAt(0xF & (c >> 12)));
app.append("0123456789ABCDEF".charAt(0xF & (c >> 8)));
app.append("0123456789ABCDEF".charAt(0xF & (c >> 4)));
app.append("0123456789ABCDEF".charAt(0xF & (c >> 0)));
} else
app.append(c);
}
}
app.append('"');
}
@Override
Object decode(Decoder dec, String s) throws Exception {
return s;
}
@Override
Object decode(Decoder dec, Number s) {
return s.toString();
}
@Override
Object decode(Decoder dec, boolean s) {
return Boolean.toString(s);
}
@Override
Object decode(Decoder dec ) {
return null;
}
/**
* An object can be assigned to a string. This means that the stream is
* interpreted as the object but stored in its complete in the string.
*/
@Override
Object decodeObject(Decoder r) throws Exception {
return collect(r, '}');
}
/**
* An array can be assigned to a string. This means that the stream is
* interpreted as the array but stored in its complete in the string.
*/
@Override
Object decodeArray(Decoder r) throws Exception {
return collect(r, ']');
}
/**
* Gather the input until you find the the closing character making sure
* that new blocks are are take care of.
* <p>
* This method parses the input for a complete block so that it can be
* stored in a string. This allows envelopes.
*
* @param isr
* @param c
* @return
* @throws Exception
*/
private Object collect(Decoder isr, @SuppressWarnings("unused") char close) throws Exception {
boolean instring = false;
int level = 1;
StringBuilder sb = new StringBuilder();
int c = isr.current();
while (c > 0 && level > 0) {
sb.append((char) c);
if (instring)
switch (c) {
case '"' :
instring = true;
break;
case '[' :
case '{' :
level++;
break;
case ']' :
case '}' :
level--;
break;
}
else
switch (c) {
case '"' :
instring = false;
break;
case '\\' :
sb.append((char) isr.read());
break;
}
c = isr.read();
}
return sb.toString();
}
}