1 /*
2 * Copyright (c) 2022-2023 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 #include "tlv_object.h"
16
17 #include "securec.h"
18 namespace OHOS::MiscServices {
Write(std::vector<std::uint8_t> & buffer,uint16_t type,bool value)19 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, bool value)
20 {
21 return WriteBasic(buffer, type, (int8_t)(value));
22 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,int8_t value)23 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, int8_t value)
24 {
25 return WriteBasic(buffer, type, value);
26 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,int16_t value)27 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, int16_t value)
28 {
29 return WriteBasic(buffer, type, value);
30 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,int32_t value)31 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, int32_t value)
32 {
33 return WriteBasic(buffer, type, value);
34 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,int64_t value)35 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, int64_t value)
36 {
37 return WriteBasic(buffer, type, value);
38 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,uint32_t value)39 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, uint32_t value)
40 {
41 return WriteBasic(buffer, type, value);
42 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,const std::string & value)43 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, const std::string &value)
44 {
45 if (!HasExpectBuffer(buffer, sizeof(TLVHead) + value.size())) {
46 return false;
47 }
48 auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + cursor_);
49 tlvHead->tag = HostToNet(type);
50 tlvHead->len = HostToNet((uint32_t)value.size());
51 if (!value.empty()) {
52 auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
53 if (err != EOK) {
54 return false;
55 }
56 }
57
58 cursor_ += sizeof(TLVHead) + value.size();
59 return true;
60 }
61
Write(std::vector<std::uint8_t> & buffer,uint16_t type,const RawMem & value)62 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, const RawMem &value)
63 {
64 if (!HasExpectBuffer(buffer, sizeof(TLVHead) + value.bufferLen)) {
65 return false;
66 }
67 auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + cursor_);
68 tlvHead->tag = HostToNet(type);
69 cursor_ += sizeof(TLVHead);
70
71 if (value.bufferLen != 0 && value.buffer != 0) {
72 auto err = memcpy_s(buffer.data() + cursor_, buffer.size() - cursor_,
73 reinterpret_cast<const void *>(value.buffer), value.bufferLen);
74 if (err != EOK) {
75 return false;
76 }
77 }
78 cursor_ += value.bufferLen;
79 tlvHead->len = HostToNet((uint32_t)value.bufferLen);
80 return true;
81 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,std::map<std::string,std::vector<uint8_t>> & value)82 bool TLVObject::Write(
83 std::vector<std::uint8_t> &buffer, uint16_t type, std::map<std::string, std::vector<uint8_t>> &value)
84 {
85 if (!HasExpectBuffer(buffer, sizeof(TLVHead))) {
86 return false;
87 }
88 auto tagCursor = cursor_;
89 cursor_ += sizeof(TLVHead);
90 auto valueCursor = cursor_;
91
92 bool ret = true;
93 for (auto &item : value) {
94 ret = ret && Write(buffer, TAG_MAP_KEY, item.first);
95 ret = ret && Write(buffer, TAG_MAP_VALUE, item.second);
96 }
97 WriteHead(buffer, type, tagCursor, cursor_ - valueCursor);
98 return ret;
99 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,TLVObject & value)100 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, TLVObject &value)
101 {
102 if (!HasExpectBuffer(buffer, sizeof(TLVHead))) {
103 return false;
104 }
105 auto tagCursor = cursor_;
106 cursor_ += sizeof(TLVHead);
107 auto valueCursor = cursor_;
108 bool ret = value.Encode(buffer, cursor_, buffer.size());
109 WriteHead(buffer, type, tagCursor, cursor_ - valueCursor);
110 return ret;
111 }
Write(std::vector<std::uint8_t> & buffer,uint16_t type,std::vector<uint8_t> & value)112 bool TLVObject::Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::vector<uint8_t> &value)
113 {
114 if (!HasExpectBuffer(buffer, sizeof(TLVHead) + value.size())) {
115 return false;
116 }
117 WriteHead(buffer, type, cursor_, value.size());
118 cursor_ += sizeof(TLVHead);
119
120 if (!value.empty()) {
121 auto err = memcpy_s(buffer.data() + cursor_, buffer.size() - cursor_, value.data(), value.size());
122 if (err != EOK) {
123 return false;
124 }
125 }
126 cursor_ += value.size();
127 return true;
128 }
ReadHead(const std::vector<std::uint8_t> & buffer,TLVHead & head)129 bool TLVObject::ReadHead(const std::vector<std::uint8_t> &buffer, TLVHead &head)
130 {
131 if (!HasExpectBuffer(buffer, sizeof(TLVHead))) {
132 return false;
133 }
134 const auto *pHead = reinterpret_cast<const TLVHead *>(buffer.data() + cursor_);
135 if (!HasExpectBuffer(buffer, NetToHost(pHead->len)) &&
136 !HasExpectBuffer(buffer, NetToHost(pHead->len) + sizeof(TLVHead))) {
137 return false;
138 }
139 head.tag = NetToHost(pHead->tag);
140 head.len = NetToHost(pHead->len);
141 cursor_ += sizeof(TLVHead);
142 return true;
143 }
ReadValue(const std::vector<std::uint8_t> & buffer,bool & value,const TLVHead & head)144 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, bool &value, const TLVHead &head)
145 {
146 return ReadBasicValue(buffer, value, head);
147 }
ReadValue(const std::vector<std::uint8_t> & buffer,int8_t & value,const TLVHead & head)148 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, int8_t &value, const TLVHead &head)
149 {
150 return ReadBasicValue(buffer, value, head);
151 }
ReadValue(const std::vector<std::uint8_t> & buffer,int16_t & value,const TLVHead & head)152 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, int16_t &value, const TLVHead &head)
153 {
154 return ReadBasicValue(buffer, value, head);
155 }
ReadValue(const std::vector<std::uint8_t> & buffer,int32_t & value,const TLVHead & head)156 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, int32_t &value, const TLVHead &head)
157 {
158 return ReadBasicValue(buffer, value, head);
159 }
160
ReadValue(const std::vector<std::uint8_t> & buffer,int64_t & value,const TLVHead & head)161 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, int64_t &value, const TLVHead &head)
162 {
163 return ReadBasicValue(buffer, value, head);
164 }
ReadValue(const std::vector<std::uint8_t> & buffer,uint32_t & value,const TLVHead & head)165 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, uint32_t &value, const TLVHead &head)
166 {
167 return ReadBasicValue(buffer, value, head);
168 }
ReadValue(const std::vector<std::uint8_t> & buffer,std::string & value,const TLVHead & head)169 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, std::string &value, const TLVHead &head)
170 {
171 if (!HasExpectBuffer(buffer, head.len)) {
172 return false;
173 }
174 value.append(reinterpret_cast<const char *>(buffer.data() + cursor_), head.len);
175 cursor_ += head.len;
176 return true;
177 }
ReadValue(const std::vector<std::uint8_t> & buffer,RawMem & rawMem,const TLVHead & head)178 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, RawMem &rawMem, const TLVHead &head)
179 {
180 if (!HasExpectBuffer(buffer, head.len)) {
181 return false;
182 }
183 rawMem.buffer = (uintptr_t)(buffer.data() + cursor_);
184 rawMem.bufferLen = head.len;
185 cursor_ += head.len;
186 return true;
187 }
ReadValue(const std::vector<std::uint8_t> & buffer,TLVObject & value,const TLVHead & head)188 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, TLVObject &value, const TLVHead &head)
189 {
190 return value.Decode(buffer, cursor_, cursor_ + head.len);
191 }
ReadValue(const std::vector<std::uint8_t> & buffer,std::vector<uint8_t> & value,const TLVHead & head)192 bool TLVObject::ReadValue(const std::vector<std::uint8_t> &buffer, std::vector<uint8_t> &value, const TLVHead &head)
193 {
194 if (!HasExpectBuffer(buffer, head.len)) {
195 return false;
196 }
197 std::vector<uint8_t> buff(buffer.data() + cursor_, buffer.data() + cursor_ + head.len);
198 value = std::move(buff);
199 cursor_ += head.len;
200 return true;
201 }
ReadValue(const std::vector<std::uint8_t> & buffer,std::map<std::string,std::vector<uint8_t>> & value,const TLVHead & head)202 bool TLVObject::ReadValue(
203 const std::vector<std::uint8_t> &buffer, std::map<std::string, std::vector<uint8_t>> &value, const TLVHead &head)
204 {
205 auto mapEnd = cursor_ + head.len;
206 for (; cursor_ < mapEnd;) {
207 // item key
208 TLVHead keyHead{};
209 bool ret = ReadHead(buffer, keyHead);
210 std::string itemKey;
211 ret = ret && ReadValue(buffer, itemKey, keyHead);
212
213 // item value
214 TLVHead valueHead{};
215 ret = ret && ReadHead(buffer, valueHead);
216 std::vector<uint8_t> itemValue(0);
217 ret = ret && ReadValue(buffer, itemValue, valueHead);
218 if (!ret) {
219 return false;
220 }
221 value.emplace(itemKey, itemValue);
222 }
223 return true;
224 }
Encode(std::vector<std::uint8_t> & buffer,size_t & cursor,size_t total)225 bool TLVObject::Encode(std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total)
226 {
227 cursor_ = cursor;
228 total_ = total;
229 bool ret = Encode(buffer);
230 cursor = cursor_;
231 return ret;
232 }
Decode(const std::vector<std::uint8_t> & buffer,size_t & cursor,size_t total)233 bool TLVObject::Decode(const std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total)
234 {
235 cursor_ = cursor;
236 total_ = total;
237 bool ret = Decode(buffer);
238 cursor = cursor_;
239 return ret;
240 }
241 } // namespace OHOS::MiscServices
242