On this page:

The InputStream API in C++

An InputStream is created using the following function:

{zcode:cpp}
namespace Ice {
    InputStreamPtr createInputStream(
        const Ice::CommunicatorPtr& communicator,
        const std::vector<Ice::Byte>& data);
}
{zcode}

The InputStream class is shown below.

{zcode:cpp}
namespace Ice {
    class InputStream : ... {
    public:
        virtual CommunicatorPtr communicator() const = 0;

        virtual void sliceObjects(bool slice) = 0;

        virtual void read(bool& v) = 0;
        virtual void read(Byte& v) = 0;
        virtual void read(Short& v) = 0;
        virtual void read(Int& v) = 0;
        virtual void read(Long& v) = 0;
        virtual void read(Float& v) = 0;
        virtual void read(Double& v) = 0;
        virtual void read(std::string& s, bool convert = true) = 0;
        virtual void read(std::wstring& s) = 0;

        template<typename T> inline void read(T& v) {
            StreamReader< StreamTrait<T>::type>::read(this, v);
        }

        virtual void read(std::vector<std::string>& v, bool convert) = 0;

        virtual void read(std::pair<const bool*, const bool*>&,
                          IceUtil::ScopedArray<bool>&) = 0;

        virtual void read(std::pair<const Byte*, const Byte*>&) = 0;

        virtual void read(std::pair<const Short*, const Short*>&,
                          IceUtil::ScopedArray<Short>&) = 0;

        virtual void read(std::pair<const Int*, const Int*>&,
                          IceUtil::ScopedArray<Int>&) = 0;

        virtual void read(std::pair<const Long*, const Long*>&,
                          IceUtil::ScopedArray<Long>&) = 0;

        virtual void read(std::pair<const Float*, const Float*>&,
                          IceUtil::ScopedArray<Float>&) = 0;

        virtual void read(std::pair<const Double*, const Double*>&,
                          IceUtil::ScopedArray<Double>&) = 0;

        virtual Int readSize() = 0;
        virtual Int readAndCheckSeqSize(int minWireSize) = 0;

        virtual ObjectPrx readProxy() = 0;

        template<typename T> inline void
        read(IceInternal::ProxyHandle<T>& v) {
            // ...
        }

        virtual void readObject(const ReadObjectCallbackPtr& cb) = 0;

        template<typename T> inline void
        read(IceInternal::Handle<T>& v) {
            // ...
        }

        virtual std::string readTypeId() = 0;

        virtual void throwException() = 0;

        virtual void startSlice() = 0;
        virtual void endSlice() = 0;
        virtual void skipSlice() = 0;

        virtual void startEncapsulation() = 0;
        virtual void endEncapsulation() = 0;
        virtual void skipEncapsulation() = 0;

        virtual void readPendingObjects() = 0;

        virtual void rewind() = 0;
    };
    typedef ... InputStreamPtr;
}
{zcode}

Extracting Built-In Types in C++

Member functions are provided to extract any of the built-in types. For example, you can extract a double value followed by a string from a stream as follows:

{zcode:cpp}
vector<Ice::Byte> data = ...;
in = Ice::createInputStream(communicator, data);
double d;
in->read(d);
string s;
in->read(s);
{zcode}

Extracting Sequences of Built-In Types in C++

For types other than built-in types, the following template member function performs the extraction:

{zcode:cpp}
template<typename T> inline void
read(T& v) {
    StreamReader<StreamTrait<T>::type>::read(this, v);
}
{zcode}

For example, you can extract a sequence of integers as follows:

{zcode:cpp}
vector<Ice::Byte> data = ...;
in = Ice::createInputStream(communicator, data);
// ...
IntSeq s; // Slice: sequence<int> IntSeq;
in->read(s);
{zcode}

The Ice run time provides an implementation of the StreamReader template whose read method reads a sequence of any of the built-in types. Note that, when reading a sequence, this reads both the sequence size that precedes the sequence elements as well as the sequence elements that follow the size.

If you are using a custom container for your sequence of built-in type, you must provide a specialization of the StreamTrait template in order to extract your sequence. For example, the following definition allows you to use the QVector container from the Qt library:

{zcode:cpp}
//
// StreamTrait specialization for QVector
//
template<typename T>
struct StreamTrait< QVector<T> >
{
    static const StreamTraitType type = StreamTraitTypeSequence;
    static const int minWireSize = 1;
};
{zcode}

Extracting Sequences of Built-In Types using Zero-Copy in C++

InputStream provides a number of overloads that accept a pair of pointers. For example, you can extract a sequence of bytes as follows:

{zcode:cpp}
vector<Ice::Byte> data = ...;
in = Ice::createInputStream(communicator, data);
std::pair<const Ice::Byte*, const Ice::Byte*> p;
in->read(p);
{zcode}

The same extraction works for the other built-in integral and floating-point types, such int and double.

If the extraction is for a byte sequence, the returned pointers always point at memory in the stream's internal marshaling buffer.

For the other built-in types, the pointers refer to the internal marshaling buffer only if the Ice encoding is compatible with the machine and compiler representation of the type, otherwise the pointers refer to a temporary array allocated to hold the unmarshaled data. The overloads for zero-copy extraction accept an additional parameter of type IceUtil::ScopedArray that holds this temporary array when necessary.

Here is an example to illustrate how to extract a sequence of integers, regardless of whether the machine's encoding of integers matches the on-the-wire representation or not:

{zcode:cpp}
#include <IceUtil/ScopedArray.h>
...
in = Ice::createInputStream(communicator, data);
std::pair<const Ice::Int*, const Ice::Int*> p;
IceUtil::ScopedArray<Ice::Int> a;
in->read(p, a);

for(const Ice::Int* i = p.first; i != p.second; ++i) {
    cout << *i << endl;
}
{zcode}

If the on-the-wire encoding matches that of the machine, and therefore zero-copy is possible, the returned pair of pointers points into the run time's internal marshaling buffer. Otherwise, the run time allocates an array, unmarshals the data into the array, and sets the pair of pointers to point into that array. Use of the ScopedArray helper template ensures that the array is deallocated once you let the ScopedArray go out of scope, so there is no need to call delete[]. (ScopedArray is conceptually the same as the Ptr smart pointer types for classes.

Extracting Structures in C++

Without the --stream option to slice2cpp, you must extract structures member by member according to the data encoding rules. Otherwise, with --stream, slice2cpp generates code that allows you to extract the structure directly. For example, here is how you can extract a Slice structure called MyStruct from a stream:

{zcode:cpp}
in = Ice::createInputStream(communicator, data);
MyStruct myStruct;
in->read(myStruct);
{zcode}

Extracting Dictionaries in C++

Without the --stream option to slice2cpp, you can extract any dictionary whose key and value types are built-in types; for any other dictionary, you must extract it as a size followed by its entries according to the data encoding rules. If you are using a custom container for your dictionary of built-in types, you must provide a specialization of the StreamTrait template in order to extract your dictionary. For example, the following definition allows you to use the QMap container from the Qt library:

{zcode:cpp}
//
// StreamTrait specialization for QMap
//
template<typename K, typename V>
struct StreamTrait< QMap<K, V> >
{
    static const StreamTraitType type = StreamTraitTypeDictionary;
    static const int minWireSize = 1;
};
{zcode}

With the --stream option, slice2cpp generates code that allows you to extract any dictionary directly, for example:

{zcode:cpp}
in = Ice::createInputStream(communicator, data);
MyDict myDict; // Slice: dictionary<string, SomeType> MyDict;
in->read(myDict);
{zcode}

Extracting Sequences of User-Defined Types in C++

Without the --stream option to slice2cpp, you must extract sequences of user-defined type as a size followed by the element type according to the data encoding rules. Otherwise, with --stream, slice2cpp generates code that allows you to extract a sequence directly, for example:

{zcode:cpp}
in = Ice::createInputStream(communicator, data);
MyEnumS myEnumS; // Slice: sequence<MyEnum> myEnumS;
in->read(myEnumS);
{zcode}

Other InputStream Methods in C++

The remaining member functions of InputStream have the following semantics:

See Also