The InputStream Interface in Java Compat

On this page:

Initializing an InputStream in Java

The InputStream class provides a number of overloaded constructors:

Java
package Ice;

public class InputStream
{
    public InputStream();
    public InputStream(byte[] data);
    public InputStream(java.nio.ByteBuffer buf);
    public InputStream(Communicator communicator);
    public InputStream(Communicator communicator, byte[] data);
    public InputStream(Communicator communicator, java.nio.ByteBuffer buf);
    public InputStream(EncodingVersion encoding);
    public InputStream(EncodingVersion encoding, byte[] data);
    public InputStream(EncodingVersion encoding, java.nio.ByteBuffer buf);
    public InputStream(Communicator communicator, EncodingVersion encoding);
    public InputStream(Communicator communicator, EncodingVersion encoding, byte[] data);
    public InputStream(Communicator communicator, EncodingVersion encoding, java.nio.ByteBuffer buf);

    ...
}

The constructors accept three types of arguments:

  • A communicator instance
  • An encoding version
  • The encoded data that you intend to decode

You'll normally supply the encoded data argument, which the stream accepts as either an array of bytes or a ByteBuffer. In either case, the stream does not make a copy of the data; rather, it uses the data as supplied and assumes it remains unmodified for the lifetime of the stream object.

We recommend supplying a communicator instance, otherwise you will not be able to decode proxy objects. The stream also inspects the communicator's settings to configure several of its own default settings, but you can optionally configure these settings manually using methods that we'll describe later.

If you omit an encoding version, the stream uses the default encoding version of the communicator (if provided) or the most recent encoding version.

If a communicator instance is not available at the time you construct the stream, you can optionally supply it later using one of the overloaded initialize methods:

Java
package Ice;

public class InputStream
{
   public void initialize(Communicator communicator);
   public void initialize(Communicator communicator, EncodingVersion encoding);
   ...
}

Invoking initialize causes the stream to re-initialize its settings based on the configuration of the given communicator.

Use the following methods to manually configure the stream:

Java
package Ice;

public class InputStream
{
    public void setValueFactoryManager(ValueFactoryManager vfm);
    public void setLogger(Logger logger);
    public void setCompactIdResolver(CompactIdResolver r);
    public void setClassResolver(ClassResolver r);
    public void setSliceValues(bool);
    public void setTraceSlicing(bool);

    ...
}

The settings include:

  • Logger
    The stream uses a logger to record warning and trace messages.
  • Compact ID resolver
    A compact ID resolver for translating numeric values into Slice type IDs. The stream invokes the resolver by passing it the numeric compact ID. The resolver is expected to return the Slice type ID associated with that numeric ID or an empty string if the numeric ID is unknown. The application must supply an object that implements CompactIdResolver:

    Java
    package Ice;
    
    public interface CompactIdResolver
    {
        String resolve(int id);
    }
  • Class resolver
    Translates Slice type IDs into Java classes. The resolver is expected to return the class corresponding to the Slice type ID or null if the ID is unknown. The application must supply an object that implements ClassResolver:

    Java
    package Ice;
    
    public interface ClassResolver
    {
        Class<?> resolveClass(String typeId);
    }

    If you initialized the stream with a communicator, the stream uses the communicator's class resolver by default. The built-in class resolver supports package metadata and configuration properties that allow you to customize the Java mapping.

  • Slice values
    The flag indicates whether to slice instances of Slice classes to a known Slice type when a more derived type is unknown. An instance is "sliced" when no static information is available for a Slice type ID and no factory can be found for that type, resulting in the creation of an instance of a less-derived type. If slicing is disabled in this situation, the stream raises the exception NoValueFactoryException. The default behavior is to allow slicing.
  • Trace slicing
    The flag indicates whether to log messages when instances of Slice classes are sliced. If the stream is initialized with a communicator, this setting defaults to the value of the Ice.Trace.Slicing property, otherwise the setting defaults to false.

Extracting from an InputStream in Java

InputStream provides a number of read methods that allow you to extract Slice types from the stream.

For example, you can extract a boolean and a sequence of strings from a stream as follows:

Java
byte[] data = ...
Ice.InputStream in = new Ice.InputStream(communicator, data);
boolean b = in.readBool();
String[] seq = in.readStringSeq();

Here are the methods for extracting data from a stream:

Java
package Ice;

public class InputStream
{
    public boolean readBool();
    public void readBool(int tag, BooleanOptional v);
    public boolean[] readBoolSeq();
    public void readBoolSeq(int tag, Optional<boolean[]> v);

    public byte readByte();
    public void readByte(int tag, ByteOptional v);
    public byte[] readByteSeq();
    public void readByteSeq(int tag, Optional<byte[]> v);
    public java.nio.ByteBuffer readByteBuffer();

    public short readShort();
    public void readShort(int tag, ShortOptional v);
    public short[] readShortSeq();
    public void readShortSeq(int tag, Optional<short[]> v);
    public java.nio.ShortBuffer readShortBuffer();

    public int readInt();
    public void readInt(int tag, IntOptional v);
    public int[] readIntSeq();
    public void readIntSeq(int tag, Optional<int[]> v);
    public java.nio.IntBuffer readIntBuffer();

    public long readLong();
    public void readLong(int tag, LongOptional v);
    public long[] readLongSeq();
    public void readLongSeq(int tag, Optional<long[]> v);
    public java.nio.LongBuffer readLongBuffer();

    public float readFloat();
    public void readFloat(int tag, FloatOptional v);
    public float[] readFloatSeq();
    public void readFloatSeq(int tag, Optional<float[]> v);
    public java.nio.FloatBuffer readFloatBuffer();

    public double readDouble();
    public void readDouble(int tag, DoubleOptional v);
    public double[] readDoubleSeq();
    public void readDoubleSeq(int tag, Optional<double[]> v);
    public java.nio.DoubleBuffer readDoubleBuffer();

    public String readString();
    public void readString(int tag, Optional<String> v);
    public String[] readStringSeq();
    public void readStringSeq(int tag, Optional<String[]> v);

    public int readSize();
    public int readAndCheckSeqSize(int minSizeWireSize);

    public ObjectPrx readProxy();
    public void readProxy(int tag, Optional<ObjectPrx> v);

    public void readValue(ReadValueCallback cb);
    public void readValue(int tag, Optional<Ice.Object> v);

    public int readEnum(int maxValue);
 
    public void throwException() throws UserException;
    public void throwException(UserExceptionFactory factory) throws UserException;
 
    public void startValue();
    public SlicedData endValue(boolean preserve);
 
    public void startException();
    public SlicedData endException(boolean preserve);

    public String startSlice();
    public void endSlice();
    public void skipSlice();

    public EncodingVersion startEncapsulation();
    public void endEncapsulation();
    public EncodingVersion skipEncapsulation();
    public EncodingVersion skipEmptyEncapsulation();
    public int getEncapsulationSize();

    public EncodingVersion getEncoding();
 
    public void readPendingValues();

    public java.io.Serializable readSerializable();
    public byte[] readBlob(int sz);

    public void skip(int sz);
    public void skipSize();
 
    public boolean readOptional(int tag, OptionalFormat format);
 
    public int pos();
    public void pos(int n);
}

Member functions are provided for extracting all of the primitive types, as well as sequences of primitive types; these are self-explanatory. The remaining member functions have the following semantics:

  • void readType(int tag, TypeOptional v)
    void readTypeSeq(int tag, Optional<type[]> v)
    Extracts an optional value, or an optional sequence, respectively. The given Optional parameter must be non-null; if the optional value is present in the stream, the parameter is marked as set and its value is also unmarshaled.

  • java.nio.TypeBuffer readTypeBuffer()
    A more efficient way of extracting a sequence without making a copy of the data. The returned buffer object is read-only.

  • int readSize()
    The Ice encoding has a compact representation to indicate size. This function extracts a size and returns it as an integer.
  • int readAndCheckSeqSize(int minWireSize)
    Like readSize, this function reads a size and returns it, but also verifies that there is enough data remaining in the unmarshaling buffer to successfully unmarshal the elements of the sequence. The minWireSize parameter indicates the smallest possible on-the-wire representation of a single sequence element. If the unmarshaling buffer contains insufficient data to unmarshal the sequence, the function throws UnmarshalOutOfBoundsException.
  • Ice.ObjectPrx readProxy()
    This function returns an instance of the base proxy type, ObjectPrx. The Slice compiler optionally generates helper functions to extract proxies of user-defined types.
  • void readValue(ReadValueCallback cb)
    The Ice encoding for class instances requires extraction to occur in stages. The readValue function accepts a callback object of type ReadValueCallback, whose definition is shown below:

    Java
    package Ice;
    
    public interface ReadValueCallback
    {
        void valueReady(Ice.Object obj);
    }
    

    When the class instance is available, the callback's valueReady member function is called. The application must call readPendingValues on the stream to ensure that all instances are properly extracted. Note that applications rarely need to invoke this member function directly; the helper functions generated by the Slice compiler are easier to use.

  • int readEnum(int maxValue)
    Unmarshals the integer value of an enumerator. The maxValue argument represents the highest enumerator value in the enumeration. Consider the following definitions:

    Slice
    enum Color { red, green, blue }
    enum Fruit { Apple, Pear=3, Orange }
    

    The maximum value for Color is 2, and the maximum value for Fruit is 4.

  • void throwException() throws UserException
    void throwException(UserExceptionFactory factory) throws UserException
    These functions extract a user exception from the stream and throw it. If the stored exception is of an unknown type, the functions attempt to extract and throw a less-derived exception. If that also fails, an exception is thrown: for the 1.0 encoding, the exception is UnmarshalOutOfBoundsException, for the 1.1 encoding, the exception is UnknownUserException. You can optionally supply an object implementing UserExceptionFactory:

    Java
    package Ice;
    
    public interface UserExceptionFactory
    {
        void createAndThrow(String typeId)
            throws UserException;
    }

    As the stream decodes each slice of a user exception, it will invoke the factory first to give it an opportunity to raise an exception corresponding to the given Slice type ID. If the factory does not recognize the type ID, it must return without throwing. In this case, the stream will make its own attempt to locate a class for the type ID; if that fails, the stream skips the slice and tries again for the next slice.

  • String startSlice()
    void endSlice()
    void skipSlice()
    Start, end, and skip a slice of member data, respectively. These functions are used when manually extracting the slices of an class instance or user exception. The startSlice method returns the type ID of the next slice, which may be an empty string depending on the format used to encode the instance or exception.
  • void startValue()
    SlicedData endValue(boolean preserve)
    The startValue method must be called prior to reading the slices of a class instance. The endValue method must be called after all slices have been read. Pass true to endValue in order to preserve the slices of any unknown more-derived types, or false to discard the slices. If preserve is true and the stream actually preserved any slices, the return value of endValue is a non-nil SlicedData object that encapsulates the slice data. If the caller later wishes to forward the instance with any preserved slices intact, it must supply this SlicedData object to the output stream.
  • void startException()
    SlicedData endException(boolean preserve)
    The startException method must be called prior to reading the slices of an exception. The endException method must be called after all slices have been read. Pass true to endException in order to preserve the slices of any unknown more-derived types, or false to discard the slices. If preserve is true and the stream actually preserved any slices, the return value of endException is a non-nil SlicedData object that encapsulates the slice data. If the caller later wishes to forward the exception with any preserved slices intact, it must supply this SlicedData object to the output stream.
  • EncodingVersion startEncapsulation()
    void endEncapsulation()
    EncodingVersion skipEncapsulation()
    EncodingVersion skipEmptyEncapsulation()
    Start, end, and skip an encapsulation, respectively. For methods that return EncodingVersion, the return value represents the encoding version used to encode the contents of the encapsulation.
  • int getEncapsulationSize()
    Returns the size of the current encapsulation.
  • EncodingVersion getEncoding()
    Returns the encoding version currently in use by the stream.
  • void readPendingValues()
    With encoding version 1.0, an application must call this method after all other data has been extracted, but only if class instances were encoded. This method extracts the state of class instances and invokes their corresponding callback objects (see readValue). This method is no-op with encoding version 1.1.
  • byte[] readBlob(int sz)
    Extracts an array of sz bytes from the stream at its current position. The returned byte array contains undecoded data from the stream's internal buffer. The stream's position is advanced by sz.

  • void skip(int sz)
    Skips the given number of bytes.
  • void skipSize()
    Reads a size at the current position and skips that number of bytes.
  • boolean readOptional(int tag, OptionalFormat fmt)
    Returns true if an optional value with the given tag and format is present, or false otherwise. If this method returns true, the data associated with that optional value must be read next. Optional values must be read in order by tag from least to greatest. The OptionalFormat enumeration is defined as follows:

    Java
    package Ice;
    public enum OptionalFormat
    {
        OptionalFormatF1, OptionalFormatF2, OptionalFormatF4, OptionalFormatF8,
        OptionalFormatSize, OptionalFormatVSize, OptionalFormatFSize,
        OptionalFormatEndMarker
    }
    

    Refer to the encoding discussion for more information on the meaning of these values.

  • int pos()
    void pos(int n)

    Returns or modifies the stream's current position, respectively.

See Also