hessian2output.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,662 行 · 第 1/3 页
JAVA
1,662 行
/* * 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 Scott Ferguson */package com.caucho.hessian.io;import com.caucho.hessian.util.IdentityIntMap;import java.io.IOException;import java.io.OutputStream;import java.util.HashMap;/** * Output stream for Hessian 2 requests. * * <p>Since HessianOutput does not depend on any classes other than * in the JDK, it can be extracted independently into a smaller package. * * <p>HessianOutput is unbuffered, so any client needs to provide * its own buffering. * * <pre> * OutputStream os = ...; // from http connection * Hessian2Output out = new Hessian11Output(os); * String value; * * out.startCall("hello"); // start hello call * out.writeString("arg1"); // write a string argument * out.completeCall(); // complete the call * </pre> */public class Hessian2Output extends AbstractHessianOutput implements Hessian2Constants{ // the output stream/ protected OutputStream _os; // map of references private IdentityIntMap _refs = new IdentityIntMap(); private boolean _isCloseStreamOnClose; // map of classes private HashMap _classRefs; // map of types private HashMap _typeRefs; private final static int SIZE = 1024; private final byte []_buffer = new byte[SIZE]; private int _offset; private boolean _isStreaming; /** * Creates a new Hessian output stream, initialized with an * underlying output stream. * * @param os the underlying output stream. */ public Hessian2Output(OutputStream os) { _os = os; } public void setCloseStreamOnClose(boolean isClose) { _isCloseStreamOnClose = isClose; } public boolean isCloseStreamOnClose() { return _isCloseStreamOnClose; } /** * Writes a complete method call. */ public void call(String method, Object []args) throws IOException { startCall(method); if (args != null) { for (int i = 0; i < args.length; i++) writeObject(args[i]); } completeCall(); } /** * Starts the method call. Clients would use <code>startCall</code> * instead of <code>call</code> if they wanted finer control over * writing the arguments, or needed to write headers. * * <code><pre> * c major minor * m b16 b8 method-name * </pre></code> * * @param method the method name to call. */ public void startCall(String method) throws IOException { int offset = _offset; if (SIZE < offset + 32) { flush(); offset = _offset; } byte []buffer = _buffer; buffer[offset++] = (byte) 'c'; buffer[offset++] = (byte) 2; buffer[offset++] = (byte) 0; buffer[offset++] = (byte) 'm'; int len = method.length(); buffer[offset++] = (byte) (len >> 8); buffer[offset++] = (byte) len; _offset = offset; printString(method, 0, len); } /** * Writes the call tag. This would be followed by the * headers and the method tag. * * <code><pre> * c major minor * </pre></code> * * @param method the method name to call. */ public void startCall() throws IOException { flushIfFull(); int offset = _offset; byte []buffer = _buffer; buffer[offset++] = (byte) 'c'; buffer[offset++] = (byte) 2; buffer[offset++] = (byte) 0; } /** * Writes the streaming call tag. This would be followed by the * headers and the method tag. * * <code><pre> * C major minor * </pre></code> * * @param method the method name to call. */ public void startStreamingCall() throws IOException { flushIfFull(); int offset = _offset; byte []buffer = _buffer; buffer[offset++] = (byte) 'C'; buffer[offset++] = (byte) 2; buffer[offset++] = (byte) 0; } /** * Starts an envelope. * * <code><pre> * E major minor * m b16 b8 method-name * </pre></code> * * @param method the method name to call. */ public void startEnvelope(String method) throws IOException { int offset = _offset; if (SIZE < offset + 32) { flush(); offset = _offset; } byte []buffer = _buffer; buffer[offset++] = (byte) 'E'; buffer[offset++] = (byte) 2; buffer[offset++] = (byte) 0; buffer[offset++] = (byte) 'm'; int len = method.length(); buffer[offset++] = (byte) (len >> 8); buffer[offset++] = (byte) len; _offset = offset; printString(method, 0, len); } /** * Completes an envelope. * * <p>A successful completion will have a single value: * * <pre> * z * </pre> */ public void completeEnvelope() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'z'; } /** * Writes the method tag. * * <code><pre> * m b16 b8 method-name * </pre></code> * * @param method the method name to call. */ public void writeMethod(String method) throws IOException { flushIfFull(); byte []buffer = _buffer; int offset = _offset; buffer[offset++] = (byte) 'm'; int len = method.length(); buffer[offset++] = (byte) (len >> 8); buffer[offset++] = (byte) len; _offset = offset; printString(method, 0, len); } /** * Completes. * * <code><pre> * z * </pre></code> */ public void completeCall() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'z'; } /** * Starts the reply * * <p>A successful completion will have a single value: * * <pre> * r * </pre> */ public void startReply() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'r'; _buffer[_offset++] = (byte) 2; _buffer[_offset++] = (byte) 0; } /** * Starts the streaming reply * * <p>A successful completion will have a single value: * * <pre> * r * </pre> */ public void startStreamingReply() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'R'; _buffer[_offset++] = (byte) 2; _buffer[_offset++] = (byte) 0; } /** * Completes reading the reply * * <p>A successful completion will have a single value: * * <pre> * z * </pre> */ public void completeReply() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'z'; } /** * Starts the message * * <p>A message contains several objects followed by a 'z'</p> * * <pre> * p x02 x00 * </pre> */ public void startMessage() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'p'; _buffer[_offset++] = (byte) 2; _buffer[_offset++] = (byte) 0; } /** * Completes reading the message * * <p>A successful completion will have a single value: * * <pre> * z * </pre> */ public void completeMessage() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'z'; } /** * Writes a header name. The header value must immediately follow. * * <code><pre> * H b16 b8 foo <em>value</em> * </pre></code> */ public void writeHeader(String name) throws IOException { int len = name.length(); flushIfFull(); _buffer[_offset++] = (byte) 'H'; _buffer[_offset++] = (byte) (len >> 8); _buffer[_offset++] = (byte) (len); printString(name); } /** * Writes a fault. 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> * * @param code the fault code, a three digit */ public void writeFault(String code, String message, Object detail) throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'f' ; writeString("code"); writeString(code); writeString("message"); writeString(message); if (detail != null) { writeString("detail"); writeObject(detail); } flushIfFull(); _buffer[_offset++] = (byte) ('z'); } /** * Writes any object to the output stream. */ public void writeObject(Object object) throws IOException { if (object == null) { writeNull(); return; } Serializer serializer; serializer = findSerializerFactory().getSerializer(object.getClass()); serializer.writeObject(object, this); } /** * 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>. * * <code><pre> * V * t b16 b8 type * l b32 b24 b16 b8 * </pre></code> */ public boolean writeListBegin(int length, String type) throws IOException { flushIfFull(); if (_typeRefs != null) { Integer refV = (Integer) _typeRefs.get(type); if (refV != null) { _buffer[_offset++] = (byte) (LIST_FIXED); writeInt(refV.intValue()); writeInt(length); return false; } } _buffer[_offset++] = (byte) 'V'; writeType(type); flushIfFull(); if (length < 0) { } else if (length < 0x100) { _buffer[_offset++] = (byte) (LENGTH_BYTE); _buffer[_offset++] = (byte) (length); } else { _buffer[_offset++] = (byte) ('l'); _buffer[_offset++] = (byte) (length >> 24); _buffer[_offset++] = (byte) (length >> 16); _buffer[_offset++] = (byte) (length >> 8); _buffer[_offset++] = (byte) (length); } return true; } /** * Writes the tail of the list to the stream. */ public void writeListEnd() throws IOException { flushIfFull(); _buffer[_offset++] = (byte) 'z'; } /** * Writes the map header to the stream. Map writers will call
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?