📄 hessianoutput.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 */package hessian.io{ import flash.errors.IllegalOperationError; import flash.utils.ByteArray; import flash.utils.IDataOutput; import flash.utils.describeType; import flash.utils.getQualifiedClassName; /** * A writer for the Hessian 1.0 protocol. A Hessian 2.0 compatible reader * must be able to read the output of this implementation. * */ public class HessianOutput extends AbstractHessianOutput { private var _out:IDataOutput; private var _version:int = 1; private var _refs:Object; private var _numRefs:int = 0; /** * Creates a new HessianOutput. * * @param out The IDataOutput to which this HessianOutput will write. * * @see #init(IDataOutput) * */ public function HessianOutput(out:IDataOutput = null) { init(out); } /** * Initialize the Hessian stream with the underlying IDataOutput. This * method will reset the internal data of this instance, meaning this * HessianOutput may be reused. * * @param out The IDataOutput to which this HessianOutput will write. */ public override function init(out:IDataOutput):void { _out = out; resetReferences(); } /** * Starts the method call. * * <p> * <code><pre> * c major minor * m b16 b8 method-namek * </pre></code> * </p> * * @param method The method name to call. */ public override function startCall(method:String = null):void { if (method == null) { _out.writeByte('c'.charCodeAt()); _out.writeByte(0); _out.writeByte(1); } else { _out.writeByte('c'.charCodeAt()); _out.writeByte(_version); _out.writeByte(0); _out.writeByte('m'.charCodeAt()); var len:int = method.length; _out.writeByte(len >> 8); _out.writeByte(len); printString(method, 0, len); } } /** * Writes the method tag. * * <p> * <code><pre> * m b16 b8 method-name * </pre></code> * </p> * * @param method The method name to call. */ public override function writeMethod(method:String):void { _out.writeByte('m'.charCodeAt()); var len:int = method.length; _out.writeByte(len >> 8); _out.writeByte(len); printString(method, 0, len); } /** * Completes the method call. * * <p> * <code><pre> * z * </pre></code> * </p> * */ public override function completeCall():void { _out.writeByte('z'.charCodeAt()); } /** * Starts the reply. * * <p>A successful completion will have a single value: * <pre> * r * </pre> * </p> */ public override function startReply():void { _out.writeByte('r'.charCodeAt()); _out.writeByte(1); _out.writeByte(0); } /** * Completes reading the reply. * * <p>A successful completion will have a single value: * <pre> * z * </pre> * </p> */ public override function completeReply():void { _out.writeByte('z'.charCodeAt()); } /** * Writes a header name. The header value must immediately follow. * * <p> * <code><pre> * H b16 b8 foo <em>value</em> * </pre></code> * </p> * * @param name The header name. */ public override function writeHeader(name:String):void { var len:int = name.length; _out.writeByte('H'.charCodeAt()); _out.writeByte(len >> 8); _out.writeByte(len); printString(name); } /** * Writes a fault. * * <p> * The fault will be written * as a descriptive string followed by an object: * <code><pre> * f * <string>code * <string>the fault code * * <string>message * <string>the fault mesage * * <string>detail * mt\x00\xnnjavax.ejb.FinderException * ... * z * z * </pre></code> * </p> * * @param code The fault code, a three digit number. * @param message The fault message. * @param detail The fault detail. */ public override function writeFault(code:String, message:String, detail:Object):void { _out.writeByte('f'.charCodeAt()); writeString("code"); writeString(code); writeString("message"); writeString(message); if (detail != null) { writeString("detail"); writeObject(detail); } _out.writeByte('z'.charCodeAt()); } /** * Writes a generic object to the output stream. * * @param object The object to write. * @param className The name of the class to write to the stream. * May be the name of a primitive or user created class. */ public override function writeObject(object:Object, className:String = null):void { if (object == null) { writeNull(); return; } if (object is Boolean || className == "Boolean") { writeBoolean(object as Boolean); return; } else if (className == "Number") { writeDouble(object as Number); // XXX should this be writeLong? return; } else if (className == "Double") { writeDouble(object as Number); // special hack for double return; } else if (className == "Long") { writeLong(object as Number); // special hack for long return; } else if (object is int || className == "int") { writeInt(object as int); return; } else if (object is Number) { if (isNaN(Number(object))) { writeNull(); } else { writeDouble(object as Number); // XXX should this be writeLong? } return; } else if (object is Date || className == "Date") { writeUTCDate((object as Date).valueOf()); return; } else if (object is Array || className == "Array") { var array:Array = object as Array; var hasEnd:Boolean = writeListBegin(array.length, className); for (var i:int = 0; i < array.length; i++) writeObject(array[i]); if (hasEnd) writeListEnd(); return; } else if (object is String || className == "String") { writeString(object as String); return; } else if (object is ByteArray || className == "ByteArray") { writeBytes(object as ByteArray); return; } /* XXX: Figure out how to get a real associative array in AS that associates objects by their value rather than their toString value if (addRef(object)) return;*/ // writeReplace not supported at this time // to save processing time className = getQualifiedClassName(object) as String; className = className.replace("::", "."); if (object.hasOwnProperty("hessianTypeName")) className = object.hessianTypeName; var ref:int = writeObjectBegin(className); writeObject10(object); } private function writeObject10(obj:Object):void { var type:XML = describeType(obj); var variables:XMLList = type.variable; var accessors:XMLList = type.accessor; var key:String = null; for each(var variable:XML in variables) { key = variable.@name; if (key != "hessianTypeName") { writeObject(key); writeObject(obj[key]); } } // This is needed to handle Bindable properties: // they do not appear as variables, but rather as // <accessor>'s with Bindable metadata children for each(var accessor:XML in accessors) { var metadata:XMLList = accessor.metadata; for each(var metadatum:XML in metadata) { if (metadatum.@name == "Bindable") { key = accessor.@name; if (key != "hessianTypeName") { writeObject(key); writeObject(obj[key]); } break; } } } for (key in obj) { if (key != "hessianTypeName") { writeObject(key); writeObject(obj[key]); } } writeMapEnd(); } /** * Writes the list header to the stream. List writers will call * <code>writeListBegin</code> followed by the list contents and then * call <code>writeListEnd</code>. * * <p> * <code><pre> * <list> * <type>java.util.ArrayList</type> * <length>3</length> * <int>1</int> * <int>2</int> * <int>3</int> * </list> * </pre></code> * </p> * * @param length The length of the list. * @param type The type of the elements in the list. * * @return If this list will have an end. */ public override function writeListBegin(length:int, type:String = null):Boolean { _out.writeByte('V'.charCodeAt()); if (type != null) { _out.writeByte('t'.charCodeAt()); printLenString(type); } if (length >= 0) { _out.writeByte('l'.charCodeAt()); _out.writeByte(length >> 24); _out.writeByte(length >> 16); _out.writeByte(length >> 8); _out.writeByte(length); } return true; } /** * Writes the tail of the list to the stream. */ public override function writeListEnd():void { _out.writeByte('z'.charCodeAt()); } /** * Writes the map header to the stream. Map writers will call * <code>writeMapBegin</code> followed by the map contents and then * call <code>writeMapEnd</code>. * * <p> * <code><pre> * Mt b16 b8 type (<key> <value>)z * </pre></code> * </p> * * @param type The type of the map to write. */ public override function writeMapBegin(type:String):void { _out.writeByte('M'.charCodeAt()); _out.writeByte('t'.charCodeAt()); if (type == null || type == "Object") type = ""; printLenString(type); } /** * Writes the tail of the map to the stream. */ public override function writeMapEnd():void { _out.writeByte('z'.charCodeAt()); } /** * Writes a boolean value to the stream. The boolean will be written * with the following syntax: * * <p> * <code><pre> * T * F * </pre></code> * </p> * * @param value The boolean value to write. */ public override function writeBoolean(value:Boolean):void { if (value) _out.writeByte('T'.charCodeAt()); else _out.writeByte('F'.charCodeAt()); } /** * Writes an integer value to the stream. The integer will be written * with the following syntax: * * <p> * <code><pre> * I b32 b24 b16 b8 * </pre></code> * </p> * * @param value The integer value to write. */ public override function writeInt(value:int):void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -