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#define LOG_TAG "Blob" 17 18#include "blob.h" 19#include <securec.h> 20 21namespace OHOS { 22namespace DistributedKv { 23Blob::Blob() { } 24 25Blob::Blob(const Blob &blob) 26{ 27 blob_ = blob.Data(); 28} 29 30Blob::Blob(Blob &&blob) 31{ 32 blob_.swap(blob.blob_); 33} 34 35Blob &Blob::operator=(const Blob &blob) 36{ 37 // Self-assignment detection 38 if (&blob == this) { 39 return *this; 40 } 41 42 blob_ = blob.Data(); 43 44 return *this; 45} 46 47Blob &Blob::operator=(Blob &&blob) 48{ 49 // Self-assignment detection 50 if (&blob == this) { 51 return *this; 52 } 53 54 blob_.swap(blob.blob_); 55 56 return *this; 57} 58 59Blob::Blob(const char *str, size_t n) 60 : blob_() 61{ 62 if (str != nullptr) { 63 blob_ = std::vector<uint8_t>(str, str + n); 64 } 65} 66 67Blob::Blob(const std::string &str) 68 : blob_(str.begin(), str.end()) 69{ 70} 71 72Blob::Blob(const char *str) 73 : blob_() 74{ 75 if (str != nullptr) { 76 blob_ = std::vector<uint8_t>(str, str + strlen(str)); 77 } 78} 79 80Blob::Blob(const std::vector<uint8_t> &bytes) 81 : blob_(bytes) 82{ 83} 84 85Blob::Blob(std::vector<uint8_t> &&bytes) 86 : blob_(std::move(bytes)) 87{ 88} 89 90const std::vector<uint8_t> &Blob::Data() const 91{ 92 return blob_; 93} 94 95size_t Blob::Size() const 96{ 97 return blob_.size(); 98} 99 100int Blob::RawSize() const 101{ 102 return sizeof(int) + blob_.size(); 103} 104 105bool Blob::Empty() const 106{ 107 return blob_.empty(); 108} 109 110uint8_t Blob::operator[](size_t n) const 111{ 112 if (n >= Size()) { 113 return 0; 114 } 115 return blob_[n]; 116} 117 118bool Blob::operator==(const Blob &blob) const 119{ 120 return blob_ == blob.blob_; 121} 122 123void Blob::Clear() 124{ 125 blob_.clear(); 126} 127 128std::string Blob::ToString() const 129{ 130 std::string str(blob_.begin(), blob_.end()); 131 return str; 132} 133 134int Blob::Compare(const Blob &blob) const 135{ 136 if (blob_ < blob.blob_) { 137 return -1; 138 } 139 if (blob_ == blob.blob_) { 140 return 0; 141 } 142 return 1; 143} 144 145bool Blob::StartsWith(const Blob &blob) const 146{ 147 size_t len = blob.Size(); 148 if (Size() < len) { 149 return false; 150 } 151 152 for (size_t i = 0; i < len; ++i) { 153 if (blob_[i] != blob.blob_[i]) { 154 return false; 155 } 156 } 157 return true; 158} 159 160/* write blob size and data to memory buffer. return error when bufferLeftSize not enough. */ 161bool Blob::WriteToBuffer(uint8_t *&cursorPtr, int &bufferLeftSize) const 162{ 163 if (cursorPtr == nullptr || bufferLeftSize < static_cast<int>(blob_.size() + sizeof(int))) { 164 return false; 165 } 166 *reinterpret_cast<int32_t *>(cursorPtr) = static_cast<int32_t>(blob_.size()); 167 bufferLeftSize -= sizeof(int32_t); 168 cursorPtr += sizeof(int32_t); 169 errno_t err = memcpy_s(cursorPtr, bufferLeftSize, blob_.data(), blob_.size()); 170 if (err != EOK) { 171 return false; 172 } 173 cursorPtr += blob_.size(); 174 bufferLeftSize -= blob_.size(); 175 return true; 176} 177 178/* read a blob from memory buffer. */ 179bool Blob::ReadFromBuffer(const uint8_t *&cursorPtr, int &bufferLeftSize) 180{ 181 if (cursorPtr == nullptr || bufferLeftSize < static_cast<int>(sizeof(int))) { 182 return false; 183 } 184 int blobSize = *reinterpret_cast<const int *>(cursorPtr); 185 bufferLeftSize -= sizeof(int) + blobSize; 186 if (blobSize < 0 || bufferLeftSize < 0) { 187 return false; 188 } 189 cursorPtr += sizeof(int); 190 blob_ = std::vector<uint8_t>(cursorPtr, cursorPtr + blobSize); 191 cursorPtr += blobSize; 192 return true; 193} 194} // namespace DistributedKv 195} // namespace OHOS 196