package org.unsynchronized;
import java.io.*;
import java.util.*;
/**
* Represents a serialized string object. This is primarily used in serialized streams;
* however, it is also used internally by other objects, since string objects have
* handles as well.
*/
public class StringObject extends ContentBase {
public String value;
private int readorthrow(ByteArrayInputStream bais) throws EOFException {
int x = bais.read();
if(x == -1) {
throw new EOFException("unexpected eof in modified utf-8 string");
}
return x;
}
public String toString() {
return "[String " + JDeserialize.hex(handle) + ": \"" + value + "\"]";
}
/**
* Constructor.
*
* @param handle the string object's handle
* @param data the bytes corresponding to the string
* @throws IOException if an I/O or validity error occurs
*/
public StringObject(int handle, byte[] data) throws IOException {
super(ContentType.STRING);
this.handle = handle;
ByteArrayInputStream bais = new ByteArrayInputStream(data);
StringBuffer sb = new StringBuffer();
while(true) {
int ba = bais.read();
if(ba == -1) {
break;
}
if((ba & 0x80) == 0) { /* U+0001..U+007F */
if(ba == 0) {
throw new IOException("improperly-encoded null in modified UTF8 string!");
}
sb.append((char)ba);
} else if((ba & 0xf0) == 0xe0) { /* U+0800..U+FFFF */
int bb = readorthrow(bais);
if((bb & 0xc0) != 0x80) {
throw new IOException("byte b in 0800-FFFF seq doesn't begin with correct prefix");
}
int bc = readorthrow(bais);
if((bc & 0xc0) != 0x80) {
throw new IOException("byte c in 0800-FFFF seq doesn't begin with correct prefix");
}
int cp =
((ba & 0xf) << 12)
| ((bb & 0x3f) << 6)
| (bc & 0x3f);
sb.append((char)cp);
} else if((ba & 0xe0) == 0xc0) { /* U+0080..U+07FF */
int bb = readorthrow(bais);
if((bb & 0xc0) != 0x80) {
throw new IOException("byte b in 0080-07FF seq doesn't begin with correct prefix");
}
int cp = ((ba & 0x1f) << 6) | (bb & 0x3f);
sb.append((char)cp);
} else {
throw new IOException("invalid byte in modified utf-8 string: " + JDeserialize.hex(ba));
}
}
this.value = sb.toString();
}
}