Java's built-in read/writeUTF() methods in ObjectInput/OutputStream use 'Modified UTF-8' for its encoding, which is cleverly designed to be almost exactly like UTF-8, until it's not and it bites you in the behind. Two new methods read/writeUnmodifiedUTF() may be used when real UTF-8 is required. At the current time Narya provides no further wiring-in of this functionality. See Whirled for a brilliant hack that does make use of it.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6040 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -24,9 +24,11 @@ package com.threerings.io;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -305,6 +307,27 @@ public class ObjectInputStream extends DataInputStream
|
||||
_streamer.readObject(_current, this, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a string encoded as real UTF-8 (rather than the modified format handled by
|
||||
* {link #readUTF}).
|
||||
*/
|
||||
public String readUnmodifiedUTF ()
|
||||
throws IOException
|
||||
{
|
||||
// find out how many raw bytes of UTF8 data there is
|
||||
int utflen = readUnsignedShort();
|
||||
// read precisely that many into a buffer
|
||||
byte[] bbuf = new byte[utflen];
|
||||
in.read(bbuf);
|
||||
|
||||
// decode the UTF-8 stream into a character buffer
|
||||
char[] cbuf = new char[utflen];
|
||||
int read = new InputStreamReader(new ByteArrayInputStream(bbuf), "UTF-8").read(cbuf);
|
||||
|
||||
// create and return the string given the number of decoded characters
|
||||
return String.copyValueOf(cbuf, 0, read);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
|
||||
@@ -23,9 +23,11 @@ package com.threerings.io;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@@ -289,6 +291,29 @@ public class ObjectOutputStream extends DataOutputStream
|
||||
_streamer.writeObject(_current, this, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a string encoded as real UTF-8 (rather than the modified format handled by
|
||||
* {link #writeUTF}).
|
||||
*/
|
||||
public void writeUnmodifiedUTF (String str)
|
||||
throws IOException
|
||||
{
|
||||
// prepare a buffer to accept the encoded UTF-8
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(baos, "UTF-8");
|
||||
|
||||
// do the deed
|
||||
osw.write(str);
|
||||
osw.flush();
|
||||
|
||||
// now that we know how many bytes we'll need, write that number to the stream
|
||||
writeShort(baos.size());
|
||||
|
||||
// then finally the bytes themselves
|
||||
write(baos.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
/** Used to map classes to numeric codes and the {@link Streamer} instance used to write
|
||||
* them. */
|
||||
protected Map<Class<?>, ClassMapping> _classmap;
|
||||
|
||||
Reference in New Issue
Block a user