1 /*
2  * Copyright (c) 2011-2014, Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation and/or
13  * other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #pragma once
31 
32 #include <stdint.h>
33 #include <string>
34 
35 class CSocket;
36 
37 class CMessage
38 {
39 public:
40     CMessage(uint8_t ucMsgId);
41     CMessage();
42     virtual ~CMessage();
43 
44     enum Result {
45         success,
46         peerDisconnected,
47         error
48     };
49 
50     /** Write or read the message on pSocket.
51      *
52      * @param[in,out] pSocket is the socket on wich IO operation will be made.
53      * @param[in] bOut if true message should be read,
54      *                 if false it should be written.
55      * @param[out] strError on failure, a string explaining the error,
56      *                      on success, undefined.
57      *
58      * @return success if a correct message could be recv/send
59      *         peerDisconnected if the peer disconnected before the first socket access.
60      *         error if the message could not be read/write for any other reason
61      */
62     Result serialize(CSocket* pSocket, bool bOut, std::string &strError);
63 
64 protected:
65     // Msg Id
66     uint8_t getMsgId() const;
67 
68     /** Write raw data to the message
69     *
70     * @param[in] pvData pointer to the data array
71     * @param[in] uiSize array size in bytes
72     */
73     void writeData(const void* pvData, size_t uiSize);
74 
75     /** Read raw data from the message
76     *
77     * @param[out] pvData pointer to the data array
78     * @param[in] uiSize array size in bytes
79     */
80     void readData(void* pvData, size_t uiSize);
81 
82     /** Write string to the message
83     *
84     * @param[in] strData the string to write
85     */
86     void writeString(const std::string& strData);
87 
88     /** Write string to the message
89     *
90     * @param[out] strData the string to read to
91     */
92     void readString(std::string& strData);
93 
94     /** @return string length plus room to store its length
95     *
96     * @param[in] strData the string to get the size from
97     */
98     size_t getStringSize(const std::string& strData) const;
99 
100     /** @return remaining data size to read or to write depending on the context
101     * (request: write, answer: read)
102     */
103     size_t getRemainingDataSize() const;
104 private:
105     CMessage(const CMessage&);
106     CMessage& operator=(const CMessage&);
107 
108     /** Allocate room to store the message
109     *
110     * @param[int] uiDataSize the szie to allocate in bytes
111     */
112     void allocateData(size_t uiDataSize);
113     // Fill data to send
114     virtual void fillDataToSend() = 0;
115     // Collect received data
116     virtual void collectReceivedData() = 0;
117 
118     /** @return size of the transaction data in bytes
119     */
120     virtual size_t getDataSize() const = 0;
121 
122     // Checksum
123     uint8_t computeChecksum() const;
124 
125     // MsgId
126     uint8_t _ucMsgId;
127     // Data
128     uint8_t* _pucData;
129     /** Size of the allocated memory to store the message */
130     size_t _uiDataSize;
131     /** Read/Write Index used to iterate across the message data */
132     size_t _uiIndex;
133 };
134