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