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 "db_errno.h" 23 #include "macro_utils.h" 24 #include "object_holder.h" 25 #include "object_holder_typed.h" 26 #include "communicator_type_define.h" 27 28 namespace DistributedDB { 29 constexpr uint32_t INVALID_MESSAGE_ID = 0; 30 constexpr uint16_t TYPE_INVALID = 0; 31 constexpr uint16_t TYPE_REQUEST = 1; 32 constexpr uint16_t TYPE_RESPONSE = 2; 33 constexpr uint16_t TYPE_NOTIFY = 3; 34 constexpr uint32_t NO_ERROR = 0; 35 constexpr uint16_t MSG_VERSION_BASE = 0; 36 constexpr uint16_t MSG_VERSION_EXT = 1; 37 38 class Message { 39 public: 40 Message() = default; 41 Message(uint32_t inMsgId)42 explicit Message(uint32_t inMsgId) 43 { 44 messageId_ = inMsgId; 45 } 46 ~Message()47 ~Message() 48 { 49 if (holderPtr_ != nullptr) { 50 delete holderPtr_; 51 holderPtr_ = nullptr; 52 } 53 } 54 55 DISABLE_COPY_ASSIGN_MOVE(Message); 56 57 // For user convenience, inObj can be a stack object, provided that it supports copy construct 58 // Set Object again will delete object that set before if successfully, otherwise impact no change 59 template<typename T> SetCopiedObject(const T & inObj)60 int SetCopiedObject(const T &inObj) 61 { 62 T *copiedObject = new (std::nothrow) T(inObj); 63 if (copiedObject == nullptr) { 64 return -E_OUT_OF_MEMORY; 65 } 66 ObjectHolder *tmpHolderPtr = new (std::nothrow) ObjectHolderTyped<T>(copiedObject); 67 if (tmpHolderPtr == nullptr) { 68 delete copiedObject; 69 return -E_OUT_OF_MEMORY; 70 } 71 if (holderPtr_ != nullptr) { 72 delete holderPtr_; 73 } 74 holderPtr_ = tmpHolderPtr; 75 return E_OK; 76 } 77 78 // By calling this method successfully, The ownership of inObj will be taken up by this class 79 // Thus this class is responsible for delete the inObj 80 // If calling this method unsuccessfully, The ownership of inObj is not changed 81 // Set Object again will delete object that set before if successfully, otherwise impact no change 82 template<typename T> SetExternalObject(T * & inObj)83 int SetExternalObject(T *&inObj) 84 { 85 if (inObj == nullptr) { 86 return -E_INVALID_ARGS; 87 } 88 ObjectHolder *tmpHolderPtr = new (std::nothrow) ObjectHolderTyped<T>(inObj); 89 if (tmpHolderPtr == nullptr) { 90 return -E_OUT_OF_MEMORY; 91 } 92 if (holderPtr_ != nullptr) { 93 delete holderPtr_; 94 } 95 holderPtr_ = tmpHolderPtr; 96 inObj = nullptr; 97 return E_OK; 98 } 99 100 // Calling this method in form of GetObject<T>() to specify return type based on the MessageId 101 template<typename T> GetObject()102 const T *GetObject() const 103 { 104 if (holderPtr_ == nullptr) { 105 return nullptr; 106 } 107 ObjectHolderTyped<T> *realHolderPtr = static_cast<ObjectHolderTyped<T> *>(holderPtr_); 108 return realHolderPtr->GetObject(); 109 } 110 SetMessageType(uint16_t inMsgType)111 int SetMessageType(uint16_t inMsgType) 112 { 113 if (inMsgType != TYPE_REQUEST && inMsgType != TYPE_RESPONSE && inMsgType != TYPE_NOTIFY) { 114 return -E_INVALID_ARGS; 115 } 116 messageType_ = inMsgType; 117 return E_OK; 118 } 119 SetMessageId(uint32_t inMessageId)120 void SetMessageId(uint32_t inMessageId) 121 { 122 messageId_ = inMessageId; 123 } 124 SetSessionId(uint32_t inSessionId)125 void SetSessionId(uint32_t inSessionId) 126 { 127 sessionId_ = inSessionId; 128 } 129 SetSequenceId(uint32_t inSequenceId)130 void SetSequenceId(uint32_t inSequenceId) 131 { 132 sequenceId_ = inSequenceId; 133 } 134 SetErrorNo(uint32_t inErrorNo)135 void SetErrorNo(uint32_t inErrorNo) 136 { 137 errorNo_ = inErrorNo; 138 } 139 SetTarget(const std::string & inTarget)140 void SetTarget(const std::string &inTarget) 141 { 142 target_ = inTarget; 143 } 144 SetPriority(Priority inPriority)145 void SetPriority(Priority inPriority) 146 { 147 prio_ = inPriority; 148 } 149 SetVersion(uint16_t inVersion)150 void SetVersion(uint16_t inVersion) 151 { 152 if (inVersion != MSG_VERSION_BASE && inVersion != MSG_VERSION_EXT) { 153 return; 154 } 155 version_ = inVersion; 156 } 157 GetMessageType()158 uint16_t GetMessageType() const 159 { 160 return messageType_; 161 } 162 GetMessageId()163 uint32_t GetMessageId() const 164 { 165 return messageId_; 166 } 167 GetSessionId()168 uint32_t GetSessionId() const 169 { 170 return sessionId_; 171 } 172 GetSequenceId()173 uint32_t GetSequenceId() const 174 { 175 return sequenceId_; 176 } 177 GetErrorNo()178 uint32_t GetErrorNo() const 179 { 180 return errorNo_; 181 } 182 GetTarget()183 std::string GetTarget() const 184 { 185 return target_; 186 } 187 GetPriority()188 Priority GetPriority() const 189 { 190 return prio_; 191 } 192 GetVersion()193 uint16_t GetVersion() const 194 { 195 return version_; 196 } 197 IsFeedbackError()198 bool IsFeedbackError() const 199 { 200 return (errorNo_ == E_FEEDBACK_UNKNOWN_MESSAGE || errorNo_ == E_FEEDBACK_COMMUNICATOR_NOT_FOUND); 201 } 202 203 private: 204 // Field or content that will be serialized for bytes transfer 205 uint16_t version_ = MSG_VERSION_BASE; 206 uint16_t messageType_ = TYPE_INVALID; 207 uint32_t messageId_ = INVALID_MESSAGE_ID; 208 uint32_t sessionId_ = 0; // Distinguish different conversation 209 uint32_t sequenceId_ = 0; // Distinguish different message even in same session with same content in retry case 210 uint32_t errorNo_ = NO_ERROR; 211 ObjectHolder *holderPtr_ = nullptr; 212 213 // Field carry supplemental info 214 std::string target_; 215 Priority prio_ = Priority::LOW; 216 }; 217 } // namespace DistributedDB 218 219 #endif // MESSAGE_H 220