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