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