• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include "base/json/uobject.h"
17 
18 #include <cstring>
19 #include <stack>
20 
21 #include "securec.h"
22 
23 #include "base/log/log_wrapper.h"
24 
25 namespace OHOS {
26 namespace {
27 template<typename T>
HashItem(const std::string & key,const T & value)28 size_t HashItem(const std::string& key, const T& value)
29 {
30     return std::hash<std::string>()(key) + std::hash<T>()(value);
31 }
32 } // namespace
33 
AddItemToObject(const std::string & key,const char * value)34 void UObject::AddItemToObject(const std::string& key, const char* value)
35 {
36     if (value) {
37         stringItems_[key] = value;
38     }
39 }
40 
AddItemToObject(const std::string & key,const std::string & value)41 void UObject::AddItemToObject(const std::string& key, const std::string& value)
42 {
43     stringItems_[key] = value;
44 }
45 
AddItemToObject(const std::string & key,size_t value)46 void UObject::AddItemToObject(const std::string& key, size_t value)
47 {
48     sizetItems_[key] = value;
49 }
50 
AddItemToObject(const std::string & key,int32_t value)51 void UObject::AddItemToObject(const std::string& key, int32_t value)
52 {
53     int32Items_[key] = value;
54 }
55 
AddItemToObject(const std::string & key,int64_t value)56 void UObject::AddItemToObject(const std::string& key, int64_t value)
57 {
58     int64Items_[key] = value;
59 }
60 
AddItemToObject(const std::string & key,double value)61 void UObject::AddItemToObject(const std::string& key, double value)
62 {
63     doubleItems_[key] = value;
64 }
65 
AddItemToObject(const std::string & key,bool value)66 void UObject::AddItemToObject(const std::string& key, bool value)
67 {
68     boolItems_[key] = value;
69 }
70 
AddItemToObject(const std::string & key,const std::shared_ptr<UObject> & value)71 void UObject::AddItemToObject(const std::string& key, const std::shared_ptr<UObject>& value)
72 {
73     if (value) {
74         children_[key] = std::move(value);
75     }
76 }
77 
GetString(const std::string & key) const78 std::string UObject::GetString(const std::string& key) const
79 {
80     return stringItems_.count(key) ? stringItems_.at(key) : "";
81 }
82 
GetSizeT(const std::string & key) const83 size_t UObject::GetSizeT(const std::string& key) const
84 {
85     return sizetItems_.count(key)    ? sizetItems_.at(key)
86            : doubleItems_.count(key) ? static_cast<size_t>(doubleItems_.at(key))
87                                      : 0;
88 }
89 
GetInt32(const std::string & key) const90 int32_t UObject::GetInt32(const std::string& key) const
91 {
92     return int32Items_.count(key)    ? int32Items_.at(key)
93            : doubleItems_.count(key) ? static_cast<int32_t>(doubleItems_.at(key))
94                                      : 0;
95 }
96 
GetInt64(const std::string & key) const97 int64_t UObject::GetInt64(const std::string& key) const
98 {
99     return int64Items_.count(key)    ? int64Items_.at(key)
100            : doubleItems_.count(key) ? static_cast<int64_t>(doubleItems_.at(key))
101                                      : 0;
102 }
103 
GetDouble(const std::string & key) const104 double UObject::GetDouble(const std::string& key) const
105 {
106     return doubleItems_.count(key) ? doubleItems_.at(key) : 0;
107 }
108 
GetBool(const std::string & key) const109 bool UObject::GetBool(const std::string& key) const
110 {
111     return boolItems_.count(key) ? boolItems_.at(key) : false;
112 }
113 
GetObject(const std::string & key) const114 std::shared_ptr<UObject> UObject::GetObject(const std::string& key) const
115 {
116     return children_.count(key) ? children_.at(key) : std::make_shared<UObject>();
117 }
118 
Contains(const std::string & key) const119 bool UObject::Contains(const std::string& key) const
120 {
121     return stringItems_.count(key) || sizetItems_.count(key) || int32Items_.count(key) || int64Items_.count(key) ||
122            doubleItems_.count(key) || boolItems_.count(key) || children_.count(key);
123 }
124 
Serialize(char * buffer,int32_t bufferLen)125 void UObject::Serialize(char* buffer, int32_t bufferLen)
126 {
127     if (!buffer) {
128         LOGE("|ERROR| buffer is null");
129         return;
130     }
131 
132     buffer_ = buffer;
133     bufferLen_ = bufferLen;
134     offset_ = 0;
135 
136     for (const auto& item : stringItems_) {
137         WriteKV(item.first, item.second);
138     }
139     for (const auto& item : sizetItems_) {
140         WriteKV(item.first, item.second);
141     }
142     for (const auto& item : int32Items_) {
143         WriteKV(item.first, item.second);
144     }
145     for (const auto& item : int64Items_) {
146         WriteKV(item.first, item.second);
147     }
148     for (const auto& item : doubleItems_) {
149         WriteKV(item.first, item.second);
150     }
151     for (const auto& item : boolItems_) {
152         WriteKV(item.first, item.second);
153     }
154     for (const auto& item : children_) {
155         WriteObj(item.first, item.second);
156     }
157 }
158 
Deserialize(const char * buffer,int32_t bufferLen)159 void UObject::Deserialize(const char* buffer, int32_t bufferLen)
160 {
161     if (!buffer) {
162         LOGE("|ERROR| buffer is null");
163         return;
164     }
165 
166     constBuffer_ = buffer;
167     offset_ = 0;
168 
169     while (offset_ < bufferLen) {
170         ReadKV();
171     }
172 }
173 
Hash()174 size_t UObject::Hash()
175 {
176     hashValue_ = 0;
177 
178     for (const auto& item : stringItems_) {
179         hashValue_ += HashItem(item.first, item.second);
180     }
181     for (const auto& item : sizetItems_) {
182         hashValue_ += HashItem(item.first, item.second);
183     }
184     for (const auto& item : int32Items_) {
185         hashValue_ += HashItem(item.first, item.second);
186     }
187     for (const auto& item : int64Items_) {
188         hashValue_ += HashItem(item.first, item.second);
189     }
190     for (const auto& item : doubleItems_) {
191         hashValue_ += HashItem(item.first, item.second);
192     }
193     for (const auto& item : boolItems_) {
194         hashValue_ += HashItem(item.first, item.second);
195     }
196     for (const auto& item : children_) {
197         hashValue_ += item.second->Hash();
198     }
199 
200     return hashValue_;
201 }
202 
EstimateBufferSize()203 int32_t UObject::EstimateBufferSize()
204 {
205     int32_t buffsize = 0;
206 
207     for (auto& item : stringItems_) {
208         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(int32_t) + item.second.length();
209     }
210     for (auto& item : sizetItems_) {
211         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(size_t);
212     }
213     for (auto& item : int32Items_) {
214         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(int32_t);
215     }
216     for (auto& item : int64Items_) {
217         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(int64_t);
218     }
219     for (auto& item : doubleItems_) {
220         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(double);
221     }
222     for (auto& item : boolItems_) {
223         buffsize += sizeof(uint8_t) + sizeof(int32_t) + item.first.length() + sizeof(bool);
224     }
225     for (auto& child : children_) {
226         buffsize += sizeof(uint8_t) + sizeof(int32_t) + child.first.length() + sizeof(int32_t) +
227                     child.second->EstimateBufferSize();
228     }
229 
230     return buffsize;
231 }
232 
WriteChar(char value)233 void UObject::WriteChar(char value)
234 {
235     buffer_[0] = value;
236     offset_++;
237     buffer_++;
238 }
239 
WriteInt32(int32_t value)240 void UObject::WriteInt32(int32_t value)
241 {
242     if (memcpy_s(buffer_, bufferLen_ - offset_, &value, sizeof(int32_t)) != 0) {
243         LOGE("memcpy overflow.");
244         return;
245     }
246     offset_ += sizeof(int32_t);
247     buffer_ += sizeof(int32_t);
248 }
249 
WriteSizeT(size_t value)250 void UObject::WriteSizeT(size_t value)
251 {
252     if (memcpy_s(buffer_, bufferLen_ - offset_, &value, sizeof(size_t)) != 0) {
253         LOGE("memcpy overflow.");
254         return;
255     }
256     offset_ += sizeof(size_t);
257     buffer_ += sizeof(size_t);
258 }
259 
WriteInt64(int64_t value)260 void UObject::WriteInt64(int64_t value)
261 {
262     if (memcpy_s(buffer_, bufferLen_ - offset_, &value, sizeof(int64_t)) != 0) {
263         LOGE("memcpy overflow.");
264         return;
265     }
266     offset_ += sizeof(int64_t);
267     buffer_ += sizeof(int64_t);
268 }
269 
WriteDouble(double value)270 void UObject::WriteDouble(double value)
271 {
272     if (memcpy_s(buffer_, bufferLen_ - offset_, &value, sizeof(double)) != 0) {
273         LOGE("memcpy overflow.");
274         return;
275     }
276     offset_ += sizeof(double);
277     buffer_ += sizeof(double);
278 }
279 
WriteString(const std::string & value)280 void UObject::WriteString(const std::string& value)
281 {
282     if (value.empty()) {
283         return;
284     }
285     if (memcpy_s(buffer_, bufferLen_ - offset_, value.c_str(), value.length()) != 0) {
286         LOGE("memcpy overflow.");
287         return;
288     }
289     offset_ += value.length();
290     buffer_ += value.length();
291 }
292 
WriteKV(const std::string & key,const std::string & value)293 void UObject::WriteKV(const std::string& key, const std::string& value)
294 {
295     WriteChar(static_cast<char>(ItemType::STRING));
296     WriteInt32(key.length());
297     WriteString(key);
298     WriteInt32(value.length());
299     WriteString(value);
300 }
301 
WriteKV(const std::string & key,size_t value)302 void UObject::WriteKV(const std::string& key, size_t value)
303 {
304     WriteChar(static_cast<char>(ItemType::SIZE_T));
305     WriteInt32(key.length());
306     WriteString(key);
307     WriteSizeT(value);
308 }
309 
WriteKV(const std::string & key,int32_t value)310 void UObject::WriteKV(const std::string& key, int32_t value)
311 {
312     WriteChar(static_cast<char>(ItemType::INT32));
313     WriteInt32(key.length());
314     WriteString(key);
315     WriteInt32(value);
316 }
317 
WriteKV(const std::string & key,int64_t value)318 void UObject::WriteKV(const std::string& key, int64_t value)
319 {
320     WriteChar(static_cast<char>(ItemType::INT64));
321     WriteInt32(key.length());
322     WriteString(key);
323     WriteInt64(value);
324 }
325 
WriteKV(const std::string & key,double value)326 void UObject::WriteKV(const std::string& key, double value)
327 {
328     WriteChar(static_cast<char>(ItemType::DOUBLE));
329     WriteInt32(key.length());
330     WriteString(key);
331     WriteDouble(value);
332 }
333 
WriteKV(const std::string & key,bool value)334 void UObject::WriteKV(const std::string& key, bool value)
335 {
336     WriteChar(static_cast<char>(ItemType::BOOL));
337     WriteInt32(key.length());
338     WriteString(key);
339     WriteChar(value);
340 }
341 
WriteObj(const std::string & key,const std::shared_ptr<UObject> & obj)342 void UObject::WriteObj(const std::string& key, const std::shared_ptr<UObject>& obj)
343 {
344     WriteChar(static_cast<char>(ItemType::UOBJECT));
345     WriteInt32(key.length());
346     WriteString(key);
347     int32_t len = obj->EstimateBufferSize();
348     WriteInt32(len);
349     obj->Serialize(buffer_, len);
350     buffer_ += len;
351     offset_ += len;
352 }
353 
ReadChar()354 char UObject::ReadChar()
355 {
356     char result = constBuffer_[0];
357     offset_++;
358     constBuffer_++;
359     return result;
360 }
361 
ReadInt32()362 int32_t UObject::ReadInt32()
363 {
364     int32_t result;
365     if (memcpy_s(&result, sizeof(int32_t), constBuffer_, sizeof(int32_t)) != 0) {
366         LOGE("memcpy overflow.");
367         return 0;
368     }
369     offset_ += sizeof(int32_t);
370     constBuffer_ += sizeof(int32_t);
371     return result;
372 }
373 
ReadInt64()374 int64_t UObject::ReadInt64()
375 {
376     int64_t result;
377     if (memcpy_s(&result, sizeof(int64_t), constBuffer_, sizeof(int64_t)) != 0) {
378         LOGE("memcpy overflow.");
379         return 0;
380     }
381     offset_ += sizeof(int64_t);
382     constBuffer_ += sizeof(int64_t);
383     return result;
384 }
385 
ReadSizeT()386 size_t UObject::ReadSizeT()
387 {
388     size_t result;
389     if (memcpy_s(&result, sizeof(size_t), constBuffer_, sizeof(size_t)) != 0) {
390         LOGE("memcpy overflow.");
391         return 0;
392     }
393     offset_ += sizeof(size_t);
394     constBuffer_ += sizeof(size_t);
395     return result;
396 }
397 
ReadDouble()398 double UObject::ReadDouble()
399 {
400     double result;
401     if (memcpy_s(&result, sizeof(double), constBuffer_, sizeof(double)) != 0) {
402         LOGE("memcpy overflow.");
403         return 0;
404     }
405     offset_ += sizeof(double);
406     constBuffer_ += sizeof(double);
407     return result;
408 }
409 
ReadString(int32_t len)410 std::string UObject::ReadString(int32_t len)
411 {
412     std::string result(constBuffer_, len);
413     offset_ += len;
414     constBuffer_ += len;
415     return result;
416 }
417 
ReadObj(int32_t len)418 std::shared_ptr<UObject> UObject::ReadObj(int32_t len)
419 {
420     std::shared_ptr<UObject> obj = std::make_shared<UObject>();
421     obj->Deserialize(constBuffer_, len);
422     offset_ += len;
423     constBuffer_ += len;
424     return obj;
425 }
426 
ReadKey()427 std::string UObject::ReadKey()
428 {
429     int32_t keyLen = ReadInt32();
430     std::string key = ReadString(keyLen);
431     return key;
432 }
433 
ReadKV()434 void UObject::ReadKV()
435 {
436     ItemType type = static_cast<ItemType>(ReadChar());
437     if (type == ItemType::STRING) {
438         std::string key = ReadKey();
439         int32_t valueLen = ReadInt32();
440         std::string value = ReadString(valueLen);
441         AddItemToObject(key, value);
442     } else if (type == ItemType::SIZE_T) {
443         std::string key = ReadKey();
444         size_t value = ReadSizeT();
445         AddItemToObject(key, value);
446     } else if (type == ItemType::INT32) {
447         std::string key = ReadKey();
448         int32_t value = ReadInt32();
449         AddItemToObject(key, value);
450     } else if (type == ItemType::INT64) {
451         std::string key = ReadKey();
452         int64_t value = ReadInt64();
453         AddItemToObject(key, value);
454     } else if (type == ItemType::DOUBLE) {
455         std::string key = ReadKey();
456         double value = ReadDouble();
457         AddItemToObject(key, value);
458     } else if (type == ItemType::BOOL) {
459         std::string key = ReadKey();
460         bool value = ReadChar();
461         AddItemToObject(key, value);
462     } else if (type == ItemType::UOBJECT) {
463         std::string key = ReadKey();
464         int32_t objLen = ReadInt32();
465         std::shared_ptr<UObject> obj = ReadObj(objLen);
466         AddItemToObject(key, obj);
467     }
468 }
469 } // namespace OHOS
470