Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members  

OutputStream.java

Go to the documentation of this file.
00001 /**************************************************************************
00002  Copyright (c) 2000-2001, Tony Garnock-Jones
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without
00006  modification, are permitted provided that the following conditions are
00007  met:
00008 
00009      * Redistributions of source code must retain the above copyright
00010        notice, this list of conditions and the following disclaimer.
00011 
00012      * Redistributions in binary form must reproduce the above
00013        copyright notice, this list of conditions and the following
00014        disclaimer in the documentation and/or other materials provided
00015        with the distribution.
00016 
00017      * Neither the names of the copyright holders nor the names of this
00018        software's contributors may be used to endorse or promote
00019        products derived from this software without specific prior
00020        written permission.
00021 
00022  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00025  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
00026  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00027  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00028  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00029  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00030  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00031  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 **************************************************************************/
00034 
00035 package org.hebe.mps;
00036 
00037 import java.io.*;
00038 import java.net.*;
00039 
00040 /**
00041  * Flattens the bitstream going to an MPS server from MPS primitive
00042  * types. Uses a Connection object to talk to the other end.
00043  *
00044  * @author Tony Garnock-Jones <tonyg@kcbbs.gen.nz>
00045  * @see org.hebe.mps.Connection
00046  * @see org.hebe.mps.InputStream
00047  */
00048 public class OutputStream {
00049     private Connection connection;
00050     private java.io.OutputStream output;
00051     private StringBuffer buffer;
00052 
00053     /**
00054      * Construct an OutputStream which encodes the bits going to a
00055      * Connection object.
00056      *
00057      * @param c the raw connection to use
00058      */
00059     public OutputStream(Connection c) {
00060         connection = c;
00061         output = null;
00062         setupBuffer();
00063     }
00064 
00065     /**
00066      * Creates and initialises a fresh StringBuffer in member variable buffer.
00067      */
00068     private void setupBuffer() {
00069         buffer = new StringBuffer();
00070     }
00071 
00072         /**
00073          * Resets our internal buffer to empty. */
00074         public void resetBuffer() {
00075                 setupBuffer();
00076         }
00077 
00078     /**
00079      * Construct an OutputStream which sends bits to an arbitrary
00080      * inputstream.
00081      *
00082      * @param o the raw outputstream to use
00083      */
00084     public OutputStream(java.io.OutputStream o) {
00085         connection = null;
00086         output = o;
00087         setupBuffer();
00088     }
00089 
00090     /**
00091      * Buffer up a single byte to send. The buffer is not flushed to
00092      * the server until the flush() method is called.
00093      *
00094      * @param ch the byte to buffer up
00095      * @see org.hebe.mps.OutputStream#flush
00096      */
00097     private void write(int ch) {
00098         //System.out.println("Write: " + ch);
00099         buffer.append((char) ch);
00100 
00101         /*
00102         byte[] ba = buffer.toString().getBytes();
00103         for (int i = 0; i < ba.length; i++) {
00104             System.out.print((int) ba[i]);
00105             System.out.print(" ");
00106         }
00107         System.out.println(""); */
00108     }
00109 
00110     /**
00111      * Causes the connection to the server to open, if it isn't
00112      * already open.
00113      *
00114      * @exception MPSException from connection.getOutputStream() if there's a problem
00115      * @see org.hebe.mps.Connection#getOutputStream
00116      */
00117     private void open() throws MPSException {
00118         if (output == null)
00119             output = connection.getOutputStream();
00120     }
00121 
00122     /**
00123      * Writes a single <i>int</i> to the server.
00124      *
00125      * @param i the 32-bit signed value to write
00126      */
00127     public void writeint(int i) {
00128         write((i >> 24) & 255);
00129         write((i >> 16) & 255);
00130         write((i >> 8) & 255);
00131         write(i & 255);
00132     }
00133 
00134     /**
00135      * Writes a single <i>java.lang.String</i> to the server.
00136      *
00137      * @param s the string to write
00138      */
00139     public void writestring(String s) {
00140         for (int i = 0; i < s.length(); i++) {
00141             char c = s.charAt(i);
00142             if (c == 0)
00143                 break;
00144             write(c);
00145         }
00146         write(0);
00147     }
00148 
00149     /**
00150      * Writes a single <i>boolean</i> to the server.
00151      *
00152      * @param b the boolean to write
00153      */
00154     public void writebool(boolean b) {
00155         write(b ? 1 : 0);
00156     }
00157 
00158     /**
00159      * Writes a single <i>long</i> to the server.
00160      *
00161      * @param i the long to write
00162      */
00163     public void writelong(long i) {
00164         write((int) (i >> 56) & 255);
00165         write((int) (i >> 48) & 255);
00166         write((int) (i >> 40) & 255);
00167         write((int) (i >> 32) & 255);
00168         write((int) (i >> 24) & 255);
00169         write((int) (i >> 16) & 255);
00170         write((int) (i >> 8) & 255);
00171         write((int) i & 255);
00172     }
00173 
00174     /**
00175      * Writes a single <i>char</i> to the server.
00176      *
00177      * @param ch the char to write
00178      */
00179     public void writechar(char ch) {
00180         write(ch);
00181     }
00182 
00183     /**
00184      * Writes a reference to an MPS object to the remote end. Sends a
00185      * canonical name for the object as a string. The remote end will
00186      * then construct a proxy on the other side of the connection to
00187      * make use of the reference that has been sent to it.
00188      *
00189      * @param o the MPS Interface to write
00190      * @exception MPSException if there's a problem writing
00191      * @exception MPSException if <code>o</code> is not being
00192      * served by an instance of Server and <code>o</code> is not an
00193      * instance of <code>Proxy</code>
00194      *
00195      * @see org.hebe.mps.Proxy
00196      * @see org.hebe.mps.InputStream#readReference
00197      */
00198     public void writeReference(Object o) throws MPSException {
00199         Server svr = Server.serverFor(o);
00200 
00201         if (svr == null) {
00202           // No local server for this object. Perhaps we're a Proxy
00203           // for some remote object?
00204           try {
00205             Proxy p = (Proxy) o;
00206             writestring(p.getReference());
00207           } catch (ClassCastException cce) {
00208             // Nope.
00209             throw new MPSException("Cannot write reference to unserved, non-Proxy object");
00210           }
00211         } else {
00212           // We have a local server. Send one of its addresses over
00213           // the link.
00214           writestring(svr.getBoundName());
00215         }
00216     }
00217 
00218     /**
00219      * Writes a single <i>float</i> to the server.
00220      *
00221      * @param f the float to write
00222      * @exception MPSException if there's a problem writing
00223      */
00224     public void writefloat(float f) throws MPSException {
00225         writeint(Float.floatToIntBits(f));
00226     }
00227 
00228     /**
00229      * Sends the total accumulated buffer of bytes over the
00230      * connection. Empties the buffer ready for the next batch of
00231      * bytes.
00232      *
00233      * @exception MPSException if there's a problem writing.
00234      */
00235     public void flush() throws MPSException {
00236         if (buffer.length() > 0) {
00237             try {
00238                 //System.out.println("Flushing OutputStream...");
00239                 open();
00240                 output.write(buffer.toString().getBytes());
00241                 setupBuffer();
00242             } catch (IOException ioe) {
00243                 throw new MPSException("Error flushing OutputStream buffer");
00244             }
00245         }
00246     }
00247 }

Generated at Wed Aug 15 01:05:34 2001 for mps-java by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001