// Path: src/main/java/com/healthmarketscience/rmiio/PacketInputStream.java
// public abstract class PacketInputStream extends InputStream
// {
//   /** target size of packets returned from packet related methods */
//   public static final int DEFAULT_PACKET_SIZE = 1024;
// 
//   /** empty packet.  useful for returns from partial reads where no data is
//       currently available, but it's not EOF. */
//   protected static final byte[] EMPTY_PACKET = new byte[0];
// 
//   /** the packet size for buffers created in the overflow buffer list */
//   private final int _packetSize;
//   /** whether or not packet reading should accept partial packets by default.
//       allowing partial packet reads will generally cause more remote calls, but
//       should reduce latency per-object */
//   private final boolean _noDelay;
// 
//   public PacketInputStream() {
//     this(DEFAULT_PACKET_SIZE);
//   }
// 
//   public PacketInputStream(int packetSize) {
//     this(packetSize, false);
//   }
// 
//   public PacketInputStream(int packetSize, boolean noDelay) {
//     _packetSize = packetSize;
//     _noDelay = noDelay;
//   }
// 
//   public int getPacketSize() {
//     return _packetSize;
//   }
// 
//   public boolean getNoDelay() {
//     return _noDelay;
//   }
// 
//   /**
//    * Gets the next "packet" from the internal buffer and returns it (if any).
//    * By default, this method will block until a fully filled packet is created
//    * (equivalent to calling <code>readPacket(false)</code>).  If noDelay is
//    * enabled, this method will allow partial packet reads (equivalent to
//    * calling <code>readPacket(true)</code>).
//    *
//    * @return a fully filled array of byte's or <code>null</code> if the end of
//    *         stream has been reached
//    */
//   public byte[] readPacket()
//     throws IOException
//   {
//     return readPacket(_noDelay);
//   }
// 
//   /**
//    * Gets the next "packet" from the internal buffer and returns it (if any).
//    * This method may block until a full packet is read, depending on the value
//    * of readPartial.
//    *
//    * @param readPartial iff <code>false</code>, may block until a full packet
//    *                    is read (or EOF), otherwise will return as much data
//    *                    as is currently available (which may be 0).
//    * @return a fully filled array of byte's or <code>null</code> if the end of
//    *         stream has been reached.  if no data is available but EOF has not
//    *         been reached, the returned buffer will have length 0.
//    */
//   public abstract byte[] readPacket(boolean readPartial)
//     throws IOException;
// 
// 
//   /**
//    * Returns the number of full packets which can be read without blocking.
//    */
//   public abstract int packetsAvailable()
//     throws IOException;
// 
// 
//   /**
//    * Reads a packet of data from the given input stream.  The given packet is
//    * filled and returned if possible.  If not enough bytes are available, a
//    * new packet will be created and returned.  If the stream is empty, {@code
//    * null} will be returned.
//    *
//    * @param in the InputStream from which to read data
//    * @param packet the potential output packet (if enough data is available)
//    * @return a filled packet of data if any available, {@code null} if the
//    *         stream is empty
//    */
//   public static byte[] readPacket(InputStream in, byte[] packet)
//     throws IOException
//   {
//     int readLen = in.read(packet, 0, packet.length);
//     if(readLen > 0) {
// 
//       if(readLen < packet.length) {
//         // shrink buffer for output
//         byte[] tmpPacket = new byte[readLen];
//         System.arraycopy(packet, 0, tmpPacket, 0, readLen);
//         packet = tmpPacket;
//       }
//       return packet;
// 
//     } else if(readLen == 0) {
// 
//       return PacketInputStream.EMPTY_PACKET;
//     }
//     return null;
//   }
// 
// }


import java.io.IOException;
import java.io.InputStream;
import com.healthmarketscience.rmiio.PacketInputStream;
/*
Copyright (c) 2007 Health Market Science, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.healthmarketscience.rmiio.util;



/**
 * Utility class for optimizing different read strategies based on the type of
 * the underlying InputStream.
 *
 * @author James Ahlborn
 */
public abstract class InputStreamAdapter
{

  private InputStreamAdapter() {
  }

  /**
   * @return the underlying InputStream
   */
  public abstract InputStream getInputStream();

  /**
   * Gets the next "packet" from the internal buffer and returns it (if any).
   * This method will probably block until a fully filled packet is created
   * (equivalent to calling <code>readPacket(false)</code>).
   * <p>
   * Note, this method is slightly optimized for current usage, so an
   * implementation caveat is that the returned packet must be "consumed"
   * before another call to readPacket is made.
   *
   * @return a fully filled array of byte's or <code>null</code> if the end of
   *         stream has been reached
   */
  public abstract byte[] readPacket() throws IOException;

  /**
   * @return a buffer containing the bytes read by the last successful
   *         {@link #readTemp} call
   */
  public abstract byte[] getTempBuffer();

  /**
   * Reads some number of bytes from the underlying stream and puts them in a
   * buffer available from the {@link #getTempBuffer} call.
   *
   * @return the number of bytes read, or -1 if end of stream was reached
   */
  public abstract int readTemp() throws IOException;

  /**
   * @param istream stream to wrap and for which the implementation is
   *                optimized
   * @param packetSize recommended packet size for any created packets
   * @return a new InputStreamAdapter optimized for the stream type
   */
  public static InputStreamAdapter create(InputStream istream, int packetSize)
  {
// Path: src/main/java/com/healthmarketscience/rmiio/PacketInputStream.java
// public abstract class PacketInputStream extends InputStream
// {
//   /** target size of packets returned from packet related methods */
//   public static final int DEFAULT_PACKET_SIZE = 1024;
// 
//   /** empty packet.  useful for returns from partial reads where no data is
//       currently available, but it's not EOF. */
//   protected static final byte[] EMPTY_PACKET = new byte[0];
// 
//   /** the packet size for buffers created in the overflow buffer list */
//   private final int _packetSize;
//   /** whether or not packet reading should accept partial packets by default.
//       allowing partial packet reads will generally cause more remote calls, but
//       should reduce latency per-object */
//   private final boolean _noDelay;
// 
//   public PacketInputStream() {
//     this(DEFAULT_PACKET_SIZE);
//   }
// 
//   public PacketInputStream(int packetSize) {
//     this(packetSize, false);
//   }
// 
//   public PacketInputStream(int packetSize, boolean noDelay) {
//     _packetSize = packetSize;
//     _noDelay = noDelay;
//   }
// 
//   public int getPacketSize() {
//     return _packetSize;
//   }
// 
//   public boolean getNoDelay() {
//     return _noDelay;
//   }
// 
//   /**
//    * Gets the next "packet" from the internal buffer and returns it (if any).
//    * By default, this method will block until a fully filled packet is created
//    * (equivalent to calling <code>readPacket(false)</code>).  If noDelay is
//    * enabled, this method will allow partial packet reads (equivalent to
//    * calling <code>readPacket(true)</code>).
//    *
//    * @return a fully filled array of byte's or <code>null</code> if the end of
//    *         stream has been reached
//    */
//   public byte[] readPacket()
//     throws IOException
//   {
//     return readPacket(_noDelay);
//   }
// 
//   /**
//    * Gets the next "packet" from the internal buffer and returns it (if any).
//    * This method may block until a full packet is read, depending on the value
//    * of readPartial.
//    *
//    * @param readPartial iff <code>false</code>, may block until a full packet
//    *                    is read (or EOF), otherwise will return as much data
//    *                    as is currently available (which may be 0).
//    * @return a fully filled array of byte's or <code>null</code> if the end of
//    *         stream has been reached.  if no data is available but EOF has not
//    *         been reached, the returned buffer will have length 0.
//    */
//   public abstract byte[] readPacket(boolean readPartial)
//     throws IOException;
// 
// 
//   /**
//    * Returns the number of full packets which can be read without blocking.
//    */
//   public abstract int packetsAvailable()
//     throws IOException;
// 
// 
//   /**
//    * Reads a packet of data from the given input stream.  The given packet is
//    * filled and returned if possible.  If not enough bytes are available, a
//    * new packet will be created and returned.  If the stream is empty, {@code
//    * null} will be returned.
//    *
//    * @param in the InputStream from which to read data
//    * @param packet the potential output packet (if enough data is available)
//    * @return a filled packet of data if any available, {@code null} if the
//    *         stream is empty
//    */
//   public static byte[] readPacket(InputStream in, byte[] packet)
//     throws IOException
//   {
//     int readLen = in.read(packet, 0, packet.length);
//     if(readLen > 0) {
// 
//       if(readLen < packet.length) {
//         // shrink buffer for output
//         byte[] tmpPacket = new byte[readLen];
//         System.arraycopy(packet, 0, tmpPacket, 0, readLen);
//         packet = tmpPacket;
//       }
//       return packet;
// 
//     } else if(readLen == 0) {
// 
//       return PacketInputStream.EMPTY_PACKET;
//     }
//     return null;
//   }
// 
// }


// Path: src/main/java/com/healthmarketscience/rmiio/util/InputStreamAdapter.java
import java.io.IOException;
import java.io.InputStream;
import com.healthmarketscience.rmiio.PacketInputStream;

/*
Copyright (c) 2007 Health Market Science, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.healthmarketscience.rmiio.util;



/**
 * Utility class for optimizing different read strategies based on the type of
 * the underlying InputStream.
 *
 * @author James Ahlborn
 */
public abstract class InputStreamAdapter
{

  private InputStreamAdapter() {
  }

  /**
   * @return the underlying InputStream
   */
  public abstract InputStream getInputStream();

  /**
   * Gets the next "packet" from the internal buffer and returns it (if any).
   * This method will probably block until a fully filled packet is created
   * (equivalent to calling <code>readPacket(false)</code>).
   * <p>
   * Note, this method is slightly optimized for current usage, so an
   * implementation caveat is that the returned packet must be "consumed"
   * before another call to readPacket is made.
   *
   * @return a fully filled array of byte's or <code>null</code> if the end of
   *         stream has been reached
   */
  public abstract byte[] readPacket() throws IOException;

  /**
   * @return a buffer containing the bytes read by the last successful
   *         {@link #readTemp} call
   */
  public abstract byte[] getTempBuffer();

  /**
   * Reads some number of bytes from the underlying stream and puts them in a
   * buffer available from the {@link #getTempBuffer} call.
   *
   * @return the number of bytes read, or -1 if end of stream was reached
   */
  public abstract int readTemp() throws IOException;

  /**
   * @param istream stream to wrap and for which the implementation is
   *                optimized
   * @param packetSize recommended packet size for any created packets
   * @return a new InputStreamAdapter optimized for the stream type
   */
  public static InputStreamAdapter create(InputStream istream, int packetSize)
  {
    if(istream instanceof PacketInputStream) {