1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_
5 #define COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_
8 #include "DBusMessage.h"
10 #include <CommonAPI/InputStream.h>
22 * Used to mark the position of a pointer within an array of bytes.
24 typedef uint32_t position_t;
27 * @class DBusInputMessageStream
29 * Used to deserialize and read data from a #DBusMessage. For all data types that can be read from a #DBusMessage, a ">>"-operator should be defined to handle the reading
30 * (this operator is predefined for all basic data types and for vectors).
32 class DBusInputStream: public InputStream {
34 virtual bool hasError() const { return isErrorSet(); }
36 virtual InputStream& readValue(bool& boolValue);
38 virtual InputStream& readValue(int8_t& int8Value);
39 virtual InputStream& readValue(int16_t& int16Value);
40 virtual InputStream& readValue(int32_t& int32Value);
41 virtual InputStream& readValue(int64_t& int64Value);
43 virtual InputStream& readValue(uint8_t& uint8Value);
44 virtual InputStream& readValue(uint16_t& uint16Value);
45 virtual InputStream& readValue(uint32_t& uint32Value);
46 virtual InputStream& readValue(uint64_t& uint64Value);
48 virtual InputStream& readValue(float& floatValue);
49 virtual InputStream& readValue(double& doubleValue);
51 virtual InputStream& readValue(std::string& stringValue);
52 virtual InputStream& readValue(ByteBuffer& byteBufferValue);
54 virtual InputStream& readEnumValue(int8_t& int8BackingTypeValue);
55 virtual InputStream& readEnumValue(int16_t& int16BackingTypeValue);
56 virtual InputStream& readEnumValue(int32_t& int32BackingTypeValue);
57 virtual InputStream& readEnumValue(int64_t& int64BackingTypeValue);
58 virtual InputStream& readEnumValue(uint8_t& uint8BackingTypeValue);
59 virtual InputStream& readEnumValue(uint16_t& uint16BackingTypeValue);
60 virtual InputStream& readEnumValue(uint32_t& uint32BackingTypeValue);
61 virtual InputStream& readEnumValue(uint64_t& uint64BackingTypeValue);
63 virtual InputStream& readVersionValue(Version& versionValue);
65 virtual void beginReadSerializableStruct(const SerializableStruct& serializableStruct);
66 virtual void endReadSerializableStruct(const SerializableStruct& serializableStruct);
68 virtual void beginReadBoolVector();
69 virtual void beginReadInt8Vector();
70 virtual void beginReadInt16Vector();
71 virtual void beginReadInt32Vector();
72 virtual void beginReadInt64Vector();
73 virtual void beginReadUInt8Vector();
74 virtual void beginReadUInt16Vector();
75 virtual void beginReadUInt32Vector();
76 virtual void beginReadUInt64Vector();
77 virtual void beginReadFloatVector();
78 virtual void beginReadDoubleVector();
79 virtual void beginReadStringVector();
80 virtual void beginReadByteBufferVector();
81 virtual void beginReadVersionVector();
82 virtual void beginReadVectorOfSerializableStructs();
83 virtual void beginReadVectorOfVectors();
84 virtual void beginReadVectorOfMaps();
86 virtual bool hasMoreVectorElements();
87 virtual void endReadVector();
89 virtual void beginReadMap();
90 virtual bool hasMoreMapElements();
91 virtual void endReadMap();
95 * Creates a #DBusInputMessageStream which can be used to deserialize and read data from the given #DBusMessage.
96 * As no message-signature is checked, the user is responsible to ensure that the correct data types are read in the correct order.
98 * @param message the #DBusMessage from which data should be read.
100 DBusInputStream(const CommonAPI::DBus::DBusMessage& message);
101 DBusInputStream(const DBusInputStream& imessagestream) = delete;
104 * Destructor; does not call the destructor of the referred #DBusMessage. Make sure to maintain a reference to the
105 * #DBusMessage outside of the stream if you intend to make further use of the message.
110 * Marks the stream as erroneous.
115 * @return An instance of #DBusError if this stream is in an erroneous state, NULL otherwise
117 const CommonAPI::DBus::DBusError& getError() const;
120 * @return true if this stream is in an erroneous state, false otherwise.
122 bool isErrorSet() const;
125 * Marks the state of the stream as cleared from all errors. Further reading is possible afterwards.
126 * The stream will have maintained the last valid position from before its state became erroneous.
131 * Aligns the stream to the given byte boundary, i.e. the stream skips as many bytes as are necessary to execute the next read
132 * starting from the given boundary.
134 * @param alignBoundary the byte boundary to which the stream needs to be aligned.
136 void alignToBoundary(const size_t alignBoundary);
139 * Reads the given number of bytes and returns them as an array of characters.
141 * Actually, for performance reasons this command only returns a pointer to the current position in the stream,
142 * and then increases the position of this pointer by the number of bytes indicated by the given parameter.
143 * It is the user's responsibility to actually use only the number of bytes he indicated he would use.
144 * It is assumed the user knows what kind of value is stored next in the #DBusMessage the data is streamed from.
145 * Using a reinterpret_cast on the returned pointer should then restore the original value.
150 * inputMessageStream.alignForBasicType(sizeof(int32_t));
151 * char* const dataPtr = inputMessageStream.read(sizeof(int32_t));
152 * int32_t val = *(reinterpret_cast<int32_t*>(dataPtr));
156 char* readRawData(const size_t numBytesToRead);
159 * Handles all reading of basic types from a given #DBusInputMessageStream.
160 * Basic types in this context are: uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t, float, double.
161 * Any types not listed here (especially all complex types, e.g. structs, unions etc.) need to provide a
162 * specialized implementation of this operator.
164 * @tparam _BasicType The type of the value that is to be read from the given stream.
165 * @param val The variable in which the retrieved value is to be stored
166 * @param inputMessageStream The stream which the value is to be read from
167 * @return The given inputMessageStream to allow for successive reading
169 template <typename _BasicType>
170 DBusInputStream& readBasicTypeValue(_BasicType& val) {
172 alignToBoundary(sizeof(_BasicType));
174 val = *(reinterpret_cast<_BasicType*>(readRawData(sizeof(_BasicType))));
179 * Returns the position of the reading pointer, relative to the beginning of the data stream.
181 position_t getCurrentPosition() const;
184 inline void beginReadGenericVector() {
185 uint32_t vectorByteSize;
186 readBasicTypeValue(vectorByteSize);
187 bytesToRead_.push(vectorByteSize);
191 position_t currentDataPosition_;
193 CommonAPI::DBus::DBusError* exception_;
194 CommonAPI::DBus::DBusMessage message_;
196 std::stack<uint32_t> bytesToRead_;
197 std::stack<position_t> savedStreamPositions_;
201 inline void DBusInputStream::setError() {
202 exception_ = new CommonAPI::DBus::DBusError();
207 } // namespace CommonAPI
209 #endif // COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_