Files
narya/src/as/com/threerings/io/ObjectInputStream.as
T
Ray Greenwell 4a1fdbbbe8 A few things, now that I'm running again (I downgraded to the older beta).
I'm now pounding my head against new limitations that I'd not seen before, now
that the Client class that I'm using is not in the presents.client package.
Macromedia can go fuck themselves with a hot poker.
The .swf is already 200k and I've barely begun working on UI elements.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3972 542714f4-19e9-0310-aa3c-eee0fc999fb1
2006-03-24 02:28:26 +00:00

209 lines
5.6 KiB
ActionScript

package com.threerings.io {
import flash.errors.IOError;
import flash.util.ByteArray;
import flash.util.IDataInput;
import com.threerings.util.ClassUtil;
import com.threerings.util.SimpleMap;
import com.threerings.presents.Log;
public class ObjectInputStream
{
public function ObjectInputStream (source :IDataInput = null)
{
if (source == null) {
source = new ByteArray();
}
_source = source;
}
/**
* Set a new source from which to read our data.
*/
public function setSource (source :IDataInput) :void
{
_source = source;
}
public function readObject () :Object
//throws IOError
{
try {
// read in the class code for this instance
var code :int = readShort();
// a zero code indicates a null value
if (code == 0) {
return null;
}
var cmap :ClassMapping;
// if the code is negative, that means we've never seen it
// before and class metadata follows
if (code < 0) {
// first swap the code into positive land
code *= -1;
// read in the class metadata
var cname :String = Translations.getFromServer(readUTF());
Log.debug("read cname: " + cname);
var streamer :Streamer = Streamer.getStreamerByJavaName(cname);
if (streamer == Streamer.BAD_STREAMER) {
Log.warning("OMG, cannot stream" + cname);
return null;
}
cmap = new ClassMapping(code, cname, streamer);
_classMap[code] = cmap;
} else {
cmap = (_classMap[code] as ClassMapping);
if (null == cmap) {
throw new IOError("Read object for which we have no " +
"registered class metadata.");
}
}
var target :Object;
if (cmap.streamer === null) {
var clazz :Class = flash.util.getClassByName(cmap.classname);
target = new clazz();
} else {
target = cmap.streamer.createObject(this);
}
readBareObjectImpl(target, cmap.streamer);
return target;
} catch (me :MemoryError) {
throw new IOError("out of memory" + me.message);
}
return null; // not reached: compiler dumb
}
public function readBareObject (obj :Object) :void
//throws IOError
{
readBareObjectImpl(obj, Streamer.getStreamer(obj));
}
public function readBareObjectImpl (obj :Object, streamer :Streamer) :void
{
// streamable objects
if (streamer == null) {
obj.readObject(this); // obj is a Streamable.
return;
}
_current = obj;
_streamer = streamer;
try {
_streamer.readObject(obj, this);
} finally {
// clear out our current object references
_current = null;
_streamer = null;
}
}
/**
* @param type either a String representing the java type,
* or a Class object representing the actionscript type.
*/
// TODO: this is the equivalent of marshalling something for which
// we have a basic streamer. Fill out with all the java types
public function readField (type :Object) :Object
//throws IOError
{
if (readBoolean()) {
var streamer :Streamer = (type is Class)
? Streamer.getStreamerByClass(type as Class)
: Streamer.getStreamerByJavaName(type as String);
var obj :Object = streamer.createObject(this);
streamer.readObject(obj, this);
return obj;
}
return null;
}
public function defaultReadObject () :void
//throws IOError
{
_streamer.readObject(_current, this);
}
public function readBoolean () :Boolean
//throws IOError
{
return _source.readBoolean();
}
public function readByte () :int
//throws IOError
{
return _source.readByte();
}
public function readBytes (bytes :ByteArray, offset :uint = 0,
length :uint = 0) :void
//throws IOError
{
// IDataInput reads all available bytes if a length is not passed
// in. Protect against an easy error to make by using the length of
// the array
if (length === 0) {
length = bytes.length;
}
_source.readBytes(bytes, offset, length);
}
public function readDouble () :Number
//throws IOError
{
return _source.readDouble();
}
public function readFloat () :Number
//throws IOError
{
return _source.readFloat();
}
public function readInt () :int
//throws IOError
{
return _source.readInt();
}
public function readShort () :int
//throws IOError
{
return _source.readShort();
}
public function readUTF () :String
//throws IOError
{
return _source.readUTF();
}
/** The target DataInput that we route input from. */
protected var _source :IDataInput;
/** The object currently being read from the stream. */
protected var _current :Object;
/** The stramer being used currently. */
protected var _streamer :Streamer;
/** A map of short class code to ClassMapping info. */
protected var _classMap :Array = new Array();
}
}