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
21 namespace OHOS {
22 namespace DistributedKv {
Blob()23 Blob::Blob() { }
24
Blob(const Blob & blob)25 Blob::Blob(const Blob &blob)
26 {
27 blob_ = blob.Data();
28 }
29
Blob(Blob && blob)30 Blob::Blob(Blob &&blob)
31 {
32 blob_.swap(blob.blob_);
33 }
34
operator =(const Blob & blob)35 Blob &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
operator =(Blob && blob)47 Blob &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
Blob(const char * str,size_t n)59 Blob::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
Blob(const std::string & str)67 Blob::Blob(const std::string &str)
68 : blob_(str.begin(), str.end())
69 {
70 }
71
Blob(const char * str)72 Blob::Blob(const char *str)
73 : blob_()
74 {
75 if (str != nullptr) {
76 blob_ = std::vector<uint8_t>(str, str + strlen(str));
77 }
78 }
79
Blob(const std::vector<uint8_t> & bytes)80 Blob::Blob(const std::vector<uint8_t> &bytes)
81 : blob_(bytes)
82 {
83 }
84
Blob(std::vector<uint8_t> && bytes)85 Blob::Blob(std::vector<uint8_t> &&bytes)
86 : blob_(std::move(bytes))
87 {
88 }
89
Data() const90 const std::vector<uint8_t> &Blob::Data() const
91 {
92 return blob_;
93 }
94
Size() const95 size_t Blob::Size() const
96 {
97 return blob_.size();
98 }
99
RawSize() const100 int Blob::RawSize() const
101 {
102 return sizeof(int) + blob_.size();
103 }
104
Empty() const105 bool Blob::Empty() const
106 {
107 return blob_.empty();
108 }
109
operator [](size_t n) const110 uint8_t Blob::operator[](size_t n) const
111 {
112 if (n >= Size()) {
113 return 0;
114 }
115 return blob_[n];
116 }
117
operator ==(const Blob & blob) const118 bool Blob::operator==(const Blob &blob) const
119 {
120 return blob_ == blob.blob_;
121 }
122
Clear()123 void Blob::Clear()
124 {
125 blob_.clear();
126 }
127
ToString() const128 std::string Blob::ToString() const
129 {
130 std::string str(blob_.begin(), blob_.end());
131 return str;
132 }
133
Compare(const Blob & blob) const134 int 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
StartsWith(const Blob & blob) const145 bool 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. */
WriteToBuffer(uint8_t * & cursorPtr,int & bufferLeftSize) const161 bool 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. */
ReadFromBuffer(const uint8_t * & cursorPtr,int & bufferLeftSize)179 bool 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