• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MESSAGE_H
17 #define MESSAGE_H
18 
19 #include <new>
20 #include <string>
21 #include <cstdint>
22 #include "communicator_type_define.h"
23 #include "db_errno.h"
24 #include "macro_utils.h"
25 #include "object_holder.h"
26 #include "object_holder_typed.h"
27 #include "version.h"
28 
29 namespace DistributedDB {
30 constexpr uint32_t INVALID_MESSAGE_ID = 0;
31 constexpr uint16_t TYPE_INVALID = 0;
32 constexpr uint16_t TYPE_REQUEST = 1;
33 constexpr uint16_t TYPE_RESPONSE = 2;
34 constexpr uint16_t TYPE_NOTIFY = 3;
35 constexpr uint32_t NO_ERROR = 0;
36 constexpr uint16_t MSG_VERSION_BASE = 0;
37 constexpr uint16_t MSG_VERSION_EXT = 1;
38 
39 class Message {
40 public:
41     Message() = default;
42 
Message(uint32_t inMsgId)43     explicit Message(uint32_t inMsgId)
44     {
45         messageId_ = inMsgId;
46     }
47 
~Message()48     ~Message()
49     {
50         if (holderPtr_ != nullptr) {
51             delete holderPtr_;
52             holderPtr_ = nullptr;
53         }
54     }
55 
56     DISABLE_COPY_ASSIGN_MOVE(Message);
57 
58     // For user convenience, inObj can be a stack object, provided that it supports copy construct
59     // Set Object again will delete object that set before if successfully, otherwise impact no change
60     template<typename T>
SetCopiedObject(const T & inObj)61     int SetCopiedObject(const T &inObj)
62     {
63         T *copiedObject = new (std::nothrow) T(inObj);
64         if (copiedObject == nullptr) {
65             return -E_OUT_OF_MEMORY;
66         }
67         ObjectHolder *tmpHolderPtr = new (std::nothrow) ObjectHolderTyped<T>(copiedObject);
68         if (tmpHolderPtr == nullptr) {
69             delete copiedObject;
70             return -E_OUT_OF_MEMORY;
71         }
72         if (holderPtr_ != nullptr) {
73             delete holderPtr_;
74         }
75         holderPtr_ = tmpHolderPtr;
76         return E_OK;
77     }
78 
79     // By calling this method successfully, The ownership of inObj will be taken up by this class
80     // Thus this class is responsible for delete the inObj
81     // If calling this method unsuccessfully, The ownership of inObj is not changed
82     // Set Object again will delete object that set before if successfully, otherwise impact no change
83     template<typename T>
SetExternalObject(T * & inObj)84     int SetExternalObject(T *&inObj)
85     {
86         if (inObj == nullptr) {
87             return -E_INVALID_ARGS;
88         }
89         ObjectHolder *tmpHolderPtr = new (std::nothrow) ObjectHolderTyped<T>(inObj);
90         if (tmpHolderPtr == nullptr) {
91             return -E_OUT_OF_MEMORY;
92         }
93         if (holderPtr_ != nullptr) {
94             delete holderPtr_;
95         }
96         holderPtr_ = tmpHolderPtr;
97         inObj = nullptr;
98         return E_OK;
99     }
100 
101     // Calling this method in form of GetObject<T>() to specify return type based on the MessageId
102     template<typename T>
GetObject()103     const T *GetObject() const
104     {
105         if (holderPtr_ == nullptr) {
106             return nullptr;
107         }
108         ObjectHolderTyped<T> *realHolderPtr = static_cast<ObjectHolderTyped<T> *>(holderPtr_);
109         return realHolderPtr->GetObject();
110     }
111 
SetMessageType(uint16_t inMsgType)112     int SetMessageType(uint16_t inMsgType)
113     {
114         if (inMsgType != TYPE_REQUEST && inMsgType != TYPE_RESPONSE && inMsgType != TYPE_NOTIFY) {
115             return -E_INVALID_ARGS;
116         }
117         messageType_ = inMsgType;
118         return E_OK;
119     }
120 
SetMessageId(uint32_t inMessageId)121     void SetMessageId(uint32_t inMessageId)
122     {
123         messageId_ = inMessageId;
124     }
125 
SetSessionId(uint32_t inSessionId)126     void SetSessionId(uint32_t inSessionId)
127     {
128         sessionId_ = inSessionId;
129     }
130 
SetSequenceId(uint32_t inSequenceId)131     void SetSequenceId(uint32_t inSequenceId)
132     {
133         sequenceId_ = inSequenceId;
134     }
135 
SetErrorNo(uint32_t inErrorNo)136     void SetErrorNo(uint32_t inErrorNo)
137     {
138         errorNo_ = inErrorNo;
139     }
140 
SetTarget(const std::string & inTarget)141     void SetTarget(const std::string &inTarget)
142     {
143         target_ = inTarget;
144     }
145 
SetSenderUserId(const std::string & userId)146     void SetSenderUserId(const std::string &userId)
147     {
148         senderUserId_ = userId;
149     }
150 
SetPriority(Priority inPriority)151     void SetPriority(Priority inPriority)
152     {
153         prio_ = inPriority;
154     }
155 
SetVersion(uint16_t inVersion)156     void SetVersion(uint16_t inVersion)
157     {
158         if (inVersion != MSG_VERSION_BASE && inVersion != MSG_VERSION_EXT) {
159             return;
160         }
161         version_ = inVersion;
162     }
163 
SetRemoteSoftwareVersion(uint32_t sVersion)164     void SetRemoteSoftwareVersion(uint32_t sVersion)
165     {
166         remoteSoftwareVersion_ = sVersion;
167     }
168 
GetMessageType()169     uint16_t GetMessageType() const
170     {
171         return messageType_;
172     }
173 
GetMessageId()174     uint32_t GetMessageId() const
175     {
176         return messageId_;
177     }
178 
GetSessionId()179     uint32_t GetSessionId() const
180     {
181         return sessionId_;
182     }
183 
GetSequenceId()184     uint32_t GetSequenceId() const
185     {
186         return sequenceId_;
187     }
188 
GetErrorNo()189     uint32_t GetErrorNo() const
190     {
191         return errorNo_;
192     }
193 
GetTarget()194     std::string GetTarget() const
195     {
196         return target_;
197     }
198 
GetSenderUserId()199     std::string GetSenderUserId() const
200     {
201         return senderUserId_;
202     }
203 
GetPriority()204     Priority GetPriority() const
205     {
206         return prio_;
207     }
208 
GetVersion()209     uint16_t GetVersion() const
210     {
211         return version_;
212     }
213 
GetRemoteSoftwareVersion()214     uint16_t GetRemoteSoftwareVersion() const
215     {
216         return remoteSoftwareVersion_;
217     }
218 
IsFeedbackError()219     bool IsFeedbackError() const
220     {
221         return (errorNo_ == E_FEEDBACK_UNKNOWN_MESSAGE || errorNo_ == E_FEEDBACK_COMMUNICATOR_NOT_FOUND ||
222             errorNo_ == E_FEEDBACK_DB_CLOSING || errorNo_ == E_NEED_CORRECT_TARGET_USER);
223     }
224 
IsSupportFeedDbClosing()225     bool IsSupportFeedDbClosing() const
226     {
227         return messageType_ == TYPE_REQUEST && remoteSoftwareVersion_ >= SOFTWARE_VERSION_RELEASE_12_0;
228     }
229 
230 private:
231     // Field or content that will be serialized for bytes transfer
232     uint16_t version_ = MSG_VERSION_BASE;
233     uint16_t messageType_ = TYPE_INVALID;
234     uint32_t messageId_ = INVALID_MESSAGE_ID;
235     uint32_t sessionId_ = 0;    // Distinguish different conversation
236     uint32_t sequenceId_ = 0;   // Distinguish different message even in same session with same content in retry case
237     uint32_t errorNo_ = NO_ERROR;
238     uint32_t remoteSoftwareVersion_ = SOFTWARE_VERSION_EARLIEST;
239     ObjectHolder *holderPtr_ = nullptr;
240 
241     // Field carry supplemental info
242     std::string target_;
243     std::string senderUserId_;
244     Priority prio_ = Priority::LOW;
245 };
246 } // namespace DistributedDB
247 
248 #endif // MESSAGE_H
249