📄 hessian2input.as
字号:
/* * Copyright (c) 2001-2008 Caucho Technology, Inc. All rights reserved. * * The Apache Software License, Version 1.1 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Caucho Technology (http://www.caucho.com/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "Burlap", "Resin", and "Caucho" must not be used to * endorse or promote products derived from this software without prior * written permission. For written permission, please contact * info@caucho.com. * * 5. Products derived from this software may not be called "Resin" * nor may "Resin" appear in their names without prior written * permission of Caucho Technology. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @author Emil Ong, Scott Ferguson */package hessian.io{ import flash.errors.EOFError; import flash.errors.IllegalOperationError; import flash.errors.IOError; import flash.utils.ByteArray; import flash.utils.getDefinitionByName; import flash.utils.IDataInput; /** * A reader for the Hessian 2.0 protocol. * */ public class Hessian2Input extends AbstractHessianInput { private static const END_OF_DATA:int = -2; private static const SIZE:int = 256; /** @private */ protected var _di:IDataInput; /** @private */ protected var _method:String; /** @private */ protected var _offset:int = 0; /** @private */ protected var _length:int = 0; /** @private */ protected var _buffer:ByteArray; /** @private */ protected var _isLastChunk:Boolean; /** @private */ protected var _isStreaming:Boolean; /** @private */ protected var _chunkLength:int; /** @private */ protected var _sbuf:String; /** @private */ protected var _replyFault:Error; [ArrayElementType("hessian.io::ObjectDefinition")] /** @private */ protected var _classDefs:Array; [ArrayElementType("String")] /** @private */ protected var _types:Array; /** @private */ protected var _refs:Array; /** * Creates a new Hessian2Input. * * @param di The IDataInput from which this Hessian2Input will read. * * @see #init(IDataInput) * */ public function Hessian2Input(di:IDataInput = null) { init(di); } /** * Initialize the Hessian stream with the underlying IDataInput. This * method will reset the internal data of this instance, meaning this * Hessian2Input may be reused. * * @param di The IDataInput from which this Hessian2Input will read. * */ public override function init(di:IDataInput):void { _di = di; _buffer = new ByteArray(); _offset = 0; _length = 0; } /** * Returns the call's method. */ public override function getMethod():String { return _method; } /** * Returns any reply fault. * * @return The reply fault, if available. */ public function getReplyFault():Error { return _replyFault; } /** * Reads the call. * * <p> * <pre> * c major minor * </pre> * </p> * * @param The version of the call. */ public override function readCall():int { var tag:int = read(); if (tag != 'c'.charCodeAt()) throw new Error("expected hessian call ('c') at code=" + tag + " ch=" + String.fromCharCode(tag)); var major:int = read(); var minor:int = read(); return (major << 16) + minor; } /** * Starts reading the envelope. * * <p> * <pre> * E major minor * </pre> * </p> * * @param The version of the envelope. */ public function readEnvelope():int { var tag:int = read(); if (tag != 'E'.charCodeAt()) throw new Error("expected hessian Envelope ('E') at code=" + tag + " ch=" + String.fromCharCode(tag)); var major:int = read(); var minor:int = read(); return (major << 16) + minor; } /** * Completes reading the envelope. * * <p>A successful completion will have a single value: * <pre> * z * </pre> * </p> */ public function completeEnvelope():void { var tag:int = read(); if (tag != 'z'.charCodeAt()) throw new Error("expected end of envelope"); } /** * Starts reading the call. * * <p>A successful completion will have a single value: * * <pre> * m b16 b8 method * </pre> * </p> * * @return The method name as read. */ public override function readMethod():String { var tag:int = read(); if (tag != 'm'.charCodeAt()) throw new Error("expected hessian method ('m') at code=" + tag + " ch=" + String.fromCharCode(tag)); var d1:int = read(); var d2:int = read(); _isLastChunk = true; _chunkLength = d1 * 256 + d2; _sbuf = ""; var ch:int; while ((ch = parseChar()) >= 0) _sbuf += String.fromCharCode(ch); // XXX verify that this actually copies _sbuf _method = _sbuf; return _method; } /** * Starts reading the call, including the headers. * * <p>The call expects the following protocol data * * <pre> * c major minor * m b16 b8 method * </pre> * </p> */ public override function startCall():void { readCall(); while (readHeader() != null) readObject(); readMethod(); } /** * Completes reading the call. * * <p>The call expects the following protocol data * * <pre> * z * </pre> * </p> */ public override function completeCall():void { var tag:int = read(); if (tag == 'z'.charCodeAt()) { } else if (tag < 0) throw new Error("expected end of call ('z') at end of stream."); else throw new Error("expected end of call ('z') at '" + String.fromCharCode(tag) + "'. Check method arguments and ensure method overloading is enabled if necessary"); } /** * Reads a reply as an object. * If the reply has a fault, throws the exception. * * @param expectedClass The expected class of the reply. * * @return The reply value. */ public override function readReply(expectedClass:Class):Object { var tag:int = read(); if (tag != 'r'.charCodeAt()) throw new Error("expected hessian reply"); var major:int = read(); var minor:int = read(); tag = read(); if (tag == 'f'.charCodeAt()) throw prepareFault(); else { if (tag >= 0) _offset--; var value:Object = readObject(expectedClass); completeValueReply(); return value; } } /** * Starts reading the reply. * * <p>A successful completion will have a single value: * * <pre> * r * v * </pre> * </p> */ public override function startReply():void { var tag:int = read(); if (tag != 'r'.charCodeAt()) throw new Error("expected hessian reply"); var major:int = read(); var minor:int = read(); tag = read(); if (tag == 'f'.charCodeAt()) throw prepareFault(); else if (tag >= 0) _offset--; } /** * Prepares a fault. * * @return The fault. */ private function prepareFault():Error { var fault:Object = readFault(); var detail:Object = fault.detail; var msg:String = fault.message; if (detail is Error) { // XXX will we ever get a detail that is an Error? // (as opposed to a Throwable?) _replyFault = detail as Error; if (msg != null) _replyFault.message = msg; return _replyFault; } else { var code:String = String(fault.code); _replyFault = new HessianServiceError(msg, code, detail); return _replyFault; } } /** * Completes reading the call. * * <p>A successful completion will have a single value: * <pre> * z * </pre> * </p> */ public override function completeReply():void { var tag:int = read(); if (tag != 'z'.charCodeAt()) throw new Error("expected end of reply"); } /** * Completes reading the call. * * <p>A successful completion will have a single value: * <pre> * z * </pre> * </p> */ public function completeValueReply():void { var tag:int = read(); if (tag != 'z'.charCodeAt()) error("expected end of reply"); } /** * Reads a header, returning null if there are no headers. * * <p> * <pre> * H b16 b8 value * </pre> * </p> * * @return The header if available or null otherwise. */ public override function readHeader():String { var tag:int = read(); if (tag == 'H'.charCodeAt()) { _isLastChunk = true; _chunkLength = (read() << 8) + read(); _sbuf = ""; var ch:int; while ((ch = parseChar()) >= 0) _sbuf += String.fromCharCode(ch); return _sbuf; } if (tag >= 0) _offset--; return null; } /** * Starts reading the message. * * <p> * <pre> * p major minor * </pre> * </p> * * @return The version of the message. */ public function startMessage():int { var tag:int = read(); if (tag == 'p'.charCodeAt()) _isStreaming = false; else if (tag == 'P'.charCodeAt()) _isStreaming = true; else throw error("expected Hessian message ('p') at code=" + tag + " ch=" + String.fromCharCode(tag)); var major:int = read(); var minor:int = read(); return (major << 16) + minor; } /** * Completes reading the message. * * <p>A successful completion will have a single value: * <pre> * z * </pre> * </p> */ public function completeMessage():void { var tag:int = read(); if (tag != 'z'.charCodeAt()) error("expected end of message"); } /** * Reads a null. * * <p> * <pre> * N * </pre> * </p> */ public override function readNull():void { var tag:int = read(); switch (String.fromCharCode(tag)) { case 'N'.charCodeAt(): return; default: throw new Error("expected end of reply"); } } /** * Reads a boolean. * * <p> * <pre> * T * F * </pre> * </p> * * @return The boolean value read. */ public override function readBoolean():Boolean { var tag:int = _offset < _length ? (_buffer[_offset++] & 0xff) : read(); switch (tag) { case 'T'.charCodeAt(): return true; case 'F'.charCodeAt(): return false; // direct integer case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -