More progress.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3849 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package com.threerings.io {
|
||||
|
||||
import flash.events.Event;
|
||||
|
||||
import flash.util.ByteArray;
|
||||
|
||||
public class FrameAvailableEvent extends Event
|
||||
{
|
||||
/** The event code for a frame available. */
|
||||
public static const FRAME_AVAILABLE :String = "frameAvail";
|
||||
|
||||
public function FrameAvailableEvent (frameData :ByteArray)
|
||||
{
|
||||
super(FRAME_AVAILABLE);
|
||||
_frameData = frameData;
|
||||
}
|
||||
|
||||
public function getFrameData () :ByteArray
|
||||
{
|
||||
return _frameData;
|
||||
}
|
||||
|
||||
protected var _frameData :ByteArray;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.threerings.io {
|
||||
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.events.ProgressEvent;
|
||||
|
||||
import flash.net.Socket;
|
||||
|
||||
import flash.util.ByteArray;
|
||||
import flash.util.Endian;
|
||||
|
||||
/**
|
||||
* Reads socket data until a complete frame is available.
|
||||
* This dispatches a FrameAvailableEvent.FRAME_AVAILABLE once a frame
|
||||
* has been fully read off the socket and is ready for decoding.
|
||||
*/
|
||||
public class FrameReader extends EventDispatcher
|
||||
{
|
||||
public function FrameReader (socket :Socket)
|
||||
{
|
||||
_socket = socket;
|
||||
_socket.addEventListener(ProgressEvent.SOCKET_DATA, socketHasData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when our socket has data that we can read.
|
||||
*/
|
||||
protected function socketHasData (event :ProgressEvent) :void
|
||||
{
|
||||
if (_curData == null) {
|
||||
if (_socket.bytesAvailable < HEADER_SIZE) {
|
||||
// if there are less bytes available than a header, let's
|
||||
// just leave them on the socket until we can read the length
|
||||
// all at once
|
||||
return;
|
||||
}
|
||||
_length = _socket.readInt();
|
||||
_curData = new ByteArray();
|
||||
_curData.endian = Endian.BIG_ENDIAN;
|
||||
}
|
||||
|
||||
// read bytes: either as much as possible or up to the end of the frame
|
||||
var toRead :int = Math.min(_length - _curData.length,
|
||||
_socket.bytesAvailable);
|
||||
_socket.readBytes(_curData, _curData.length, toRead);
|
||||
|
||||
if (_length === _curData.length) {
|
||||
// we have now read a complete frame, let us dispatch the data
|
||||
_curData.position = 0; // move the read pointer to the beginning
|
||||
dispatchEvent(new FrameAvailableEvent(_curData));
|
||||
_curData = null; // clear, so we know we need to first read length
|
||||
|
||||
// there's a good chance there's more on the socket, recurse
|
||||
// now to read it
|
||||
socketHasData(event);
|
||||
}
|
||||
}
|
||||
|
||||
protected var _socket :Socket;
|
||||
protected var _curData :ByteArray;
|
||||
protected var _length :int;
|
||||
|
||||
/** The number of bytes in the frame header (a 32-bit integer). */
|
||||
protected const HEADER_SIZE :int = 4;
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,20 @@ import com.threerings.util.SimpleMap;
|
||||
|
||||
public class ObjectInputStream
|
||||
{
|
||||
public function ObjectInputStream (targ:IDataInput)
|
||||
public function ObjectInputStream (source :IDataInput = null)
|
||||
{
|
||||
_targ = targ;
|
||||
if (source == null) {
|
||||
source = new ByteArray();
|
||||
}
|
||||
_source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new source from which to read our data.
|
||||
*/
|
||||
public function setSource (source :IDataInput)
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public function readObject () :*
|
||||
@@ -104,50 +115,50 @@ public class ObjectInputStream
|
||||
public function readBoolean () :Boolean
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readBoolean();
|
||||
return _source.readBoolean();
|
||||
}
|
||||
|
||||
public function readByte () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readByte();
|
||||
return _source.readByte();
|
||||
}
|
||||
|
||||
public function readBytes (bytes :ByteArray, offset :uint = 0,
|
||||
length :uint = 0) :void
|
||||
//throws IOError
|
||||
{
|
||||
_targ.readBytes(bytes, offset, length);
|
||||
_source.readBytes(bytes, offset, length);
|
||||
}
|
||||
|
||||
public function readDouble () :Number
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readDouble();
|
||||
return _source.readDouble();
|
||||
}
|
||||
|
||||
public function readFloat () :Number
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readFloat();
|
||||
return _source.readFloat();
|
||||
}
|
||||
|
||||
public function readInt () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readInt();
|
||||
return _source.readInt();
|
||||
}
|
||||
|
||||
public function readShort () :int
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readShort();
|
||||
return _source.readShort();
|
||||
}
|
||||
|
||||
public function readUTF () :String
|
||||
//throws IOError
|
||||
{
|
||||
return _targ.readUTF();
|
||||
return _source.readUTF();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +171,7 @@ public class ObjectInputStream
|
||||
}
|
||||
|
||||
/** The target DataInput that we route input from. */
|
||||
protected var _targ :IDataInput;
|
||||
protected var _source :IDataInput;
|
||||
|
||||
/** The object currently being read from the stream. */
|
||||
protected var _current :*;
|
||||
|
||||
Reference in New Issue
Block a user