Initial import to Git
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusInputStream.h
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_
6
7 #include "DBusError.h"
8 #include "DBusMessage.h"
9
10 #include <CommonAPI/InputStream.h>
11
12 #include <stdint.h>
13 #include <cassert>
14 #include <string>
15 #include <vector>
16 #include <stack>
17
18 namespace CommonAPI {
19 namespace DBus {
20
21 /**
22  * Used to mark the position of a pointer within an array of bytes.
23  */
24 typedef uint32_t position_t;
25
26 /**
27  * @class DBusInputMessageStream
28  *
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).
31  */
32 class DBusInputStream: public InputStream {
33  public:
34         virtual bool hasError() const { return isErrorSet(); }
35
36     virtual InputStream& readValue(bool& boolValue);
37
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);
42
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);
47
48         virtual InputStream& readValue(float& floatValue);
49         virtual InputStream& readValue(double& doubleValue);
50
51         virtual InputStream& readValue(std::string& stringValue);
52         virtual InputStream& readValue(ByteBuffer& byteBufferValue);
53
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);
62
63         virtual InputStream& readVersionValue(Version& versionValue);
64
65         virtual void beginReadSerializableStruct(const SerializableStruct& serializableStruct);
66         virtual void endReadSerializableStruct(const SerializableStruct& serializableStruct);
67
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();
85
86         virtual bool hasMoreVectorElements();
87         virtual void endReadVector();
88
89         virtual void beginReadMap();
90         virtual bool hasMoreMapElements();
91         virtual void endReadMap();
92
93
94         /**
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.
97      *
98      * @param message the #DBusMessage from which data should be read.
99      */
100     DBusInputStream(const CommonAPI::DBus::DBusMessage& message);
101     DBusInputStream(const DBusInputStream& imessagestream) = delete;
102
103     /**
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.
106      */
107     ~DBusInputStream();
108
109     /**
110      * Marks the stream as erroneous.
111      */
112     void setError();
113
114     /**
115      * @return An instance of #DBusError if this stream is in an erroneous state, NULL otherwise
116      */
117     const CommonAPI::DBus::DBusError& getError() const;
118
119     /**
120      * @return true if this stream is in an erroneous state, false otherwise.
121      */
122     bool isErrorSet() const;
123
124     /**
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.
127      */
128     void clearError();
129
130     /**
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.
133      *
134      * @param alignBoundary the byte boundary to which the stream needs to be aligned.
135      */
136     void alignToBoundary(const size_t alignBoundary);
137
138     /**
139      * Reads the given number of bytes and returns them as an array of characters.
140      *
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.
146      *
147      * Example use case:
148      * @code
149      * ...
150      * inputMessageStream.alignForBasicType(sizeof(int32_t));
151      * char* const dataPtr = inputMessageStream.read(sizeof(int32_t));
152      * int32_t val = *(reinterpret_cast<int32_t*>(dataPtr));
153      * ...
154      * @endcode
155      */
156     char* readRawData(const size_t numBytesToRead);
157
158     /**
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.
163      *
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
168      */
169     template <typename _BasicType>
170     DBusInputStream& readBasicTypeValue(_BasicType& val) {
171         if (sizeof(val) > 1)
172             alignToBoundary(sizeof(_BasicType));
173
174         val = *(reinterpret_cast<_BasicType*>(readRawData(sizeof(_BasicType))));
175         return *this;
176     }
177
178     /**
179      * Returns the position of the reading pointer, relative to the beginning of the data stream.
180      */
181     position_t getCurrentPosition() const;
182
183  private:
184     inline void beginReadGenericVector() {
185         uint32_t vectorByteSize;
186         readBasicTypeValue(vectorByteSize);
187         bytesToRead_.push(vectorByteSize);
188     }
189
190     char* dataBegin_;
191     position_t currentDataPosition_;
192     size_t dataLength_;
193     CommonAPI::DBus::DBusError* exception_;
194     CommonAPI::DBus::DBusMessage message_;
195
196     std::stack<uint32_t> bytesToRead_;
197     std::stack<position_t> savedStreamPositions_;
198 };
199
200
201 inline void DBusInputStream::setError() {
202     exception_ = new CommonAPI::DBus::DBusError();
203 }
204
205
206 } // namespace DBus
207 } // namespace CommonAPI
208
209 #endif // COMMONAPI_DBUS_DBUS_INPUT_STREAM_H_