465b680aa2
subtracting 4 from the length of the frame and fixing the reading of fields for which we have a basic streamer. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3885 542714f4-19e9-0310-aa3c-eee0fc999fb1
71 lines
2.4 KiB
ActionScript
71 lines
2.4 KiB
ActionScript
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;
|
|
}
|
|
// the length specified is the length of the entire frame,
|
|
// including the length of the bytes used to encode the length.
|
|
// (I think this is pretty silly).
|
|
// So for our purposes we subtract 4 bytes so we know how much
|
|
// more data is in the frame.
|
|
_length = _socket.readInt() - HEADER_SIZE;
|
|
_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;
|
|
}
|
|
}
|