• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "json_object.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <queue>
21 
22 #include "db_errno.h"
23 #include "log_print.h"
24 
25 namespace DistributedDB {
26 #ifndef OMIT_JSON
27 namespace {
28     const uint32_t MAX_NEST_DEPTH = 100;
29 #ifdef JSONCPP_USE_BUILDER
30     const int JSON_VALUE_PRECISION = 16;
31     const std::string JSON_CONFIG_INDENTATION = "indentation";
32     const std::string JSON_CONFIG_COLLECT_COMMENTS = "collectComments";
33     const std::string JSON_CONFIG_PRECISION = "precision";
34     const std::string JSON_CONFIG_REJECT_DUP_KEYS = "rejectDupKeys";
35 #endif
36 }
37 uint32_t JsonObject::maxNestDepth_ = MAX_NEST_DEPTH;
38 
SetMaxNestDepth(uint32_t nestDepth)39 uint32_t JsonObject::SetMaxNestDepth(uint32_t nestDepth)
40 {
41     uint32_t preValue = maxNestDepth_;
42     // No need to check the reasonability, only test code will use this method
43     maxNestDepth_ = nestDepth;
44     return preValue;
45 }
46 
CalculateNestDepth(const std::string & inString,int & errCode)47 uint32_t JsonObject::CalculateNestDepth(const std::string &inString, int &errCode)
48 {
49     auto begin = reinterpret_cast<const uint8_t *>(inString.c_str());
50     auto end = begin + inString.size();
51     return CalculateNestDepth(begin, end, errCode);
52 }
53 
CalculateNestDepth(const uint8_t * dataBegin,const uint8_t * dataEnd,int & errCode)54 uint32_t JsonObject::CalculateNestDepth(const uint8_t *dataBegin, const uint8_t *dataEnd, int &errCode)
55 {
56     if (dataBegin == nullptr || dataEnd == nullptr || dataBegin >= dataEnd) {
57         errCode = -E_INVALID_ARGS;
58         return maxNestDepth_ + 1; // return a invalid depth
59     }
60     bool isInString = false;
61     uint32_t maxDepth = 0;
62     uint32_t objectDepth = 0;
63     uint32_t arrayDepth = 0;
64     uint32_t numOfEscape = 0;
65 
66     for (auto ptr = dataBegin; ptr < dataEnd; ptr++) {
67         if (*ptr == '"' && numOfEscape % 2 == 0) { // 2 used to detect parity
68             isInString = !isInString;
69             continue;
70         }
71         if (!isInString) {
72             if (*ptr == '{') {
73                 objectDepth++;
74                 maxDepth = std::max(maxDepth, objectDepth + arrayDepth);
75             }
76             if (*ptr == '}') {
77                 objectDepth = ((objectDepth > 0) ? (objectDepth - 1) : 0);
78             }
79             if (*ptr == '[') {
80                 arrayDepth++;
81                 maxDepth = std::max(maxDepth, objectDepth + arrayDepth);
82             }
83             if (*ptr == ']') {
84                 arrayDepth = ((arrayDepth > 0) ? (arrayDepth - 1) : 0);
85             }
86         }
87         numOfEscape = ((*ptr == '\\') ? (numOfEscape + 1) : 0);
88     }
89     return maxDepth;
90 }
91 
JsonObject(const JsonObject & other)92 JsonObject::JsonObject(const JsonObject &other)
93 {
94     isValid_ = other.isValid_;
95     value_ = other.value_;
96 }
97 
operator =(const JsonObject & other)98 JsonObject& JsonObject::operator=(const JsonObject &other)
99 {
100     if (&other != this) {
101         isValid_ = other.isValid_;
102         value_ = other.value_;
103     }
104     return *this;
105 }
106 
JsonObject(const Json::Value & value)107 JsonObject::JsonObject(const Json::Value &value) : isValid_(true), value_(value)
108 {
109 }
110 
Parse(const std::string & inString)111 int JsonObject::Parse(const std::string &inString)
112 {
113     // The jsoncpp lib parser in strict mode will still regard root type jsonarray as valid, but we require jsonobject
114     if (isValid_) {
115         LOGE("[Json][Parse] Already Valid.");
116         return -E_NOT_PERMIT;
117     }
118     int errCode = E_OK;
119     uint32_t nestDepth = CalculateNestDepth(inString, errCode);
120     if (errCode != E_OK || nestDepth > maxNestDepth_) {
121         LOGE("[Json][Parse] Json calculate nest depth failed %d, depth=%" PRIu32 " exceed max allowed:%" PRIu32,
122             errCode, nestDepth, maxNestDepth_);
123         return -E_JSON_PARSE_FAIL;
124     }
125 #ifdef JSONCPP_USE_BUILDER
126     JSONCPP_STRING errs;
127     Json::CharReaderBuilder builder;
128     Json::CharReaderBuilder::strictMode(&builder.settings_);
129     builder[JSON_CONFIG_COLLECT_COMMENTS] = false;
130     builder[JSON_CONFIG_REJECT_DUP_KEYS] = false;
131     std::unique_ptr<Json::CharReader> const jsonReader(builder.newCharReader());
132 
133     auto begin = reinterpret_cast<const std::string::value_type *>(inString.c_str());
134     auto end = reinterpret_cast<const std::string::value_type *>(inString.c_str() + inString.length());
135     if (!jsonReader->parse(begin, end, &value_, &errs)) {
136         value_ = Json::Value();
137         LOGE("[Json][Parse] Parse string to JsonValue fail, reason=%s.", errs.c_str());
138         return -E_JSON_PARSE_FAIL;
139     }
140 #else
141     Json::Reader reader(Json::Features::strictMode());
142     if (!reader.parse(inString, value_, false)) {
143         value_ = Json::Value();
144         LOGE("[Json][Parse] Parse string to JsonValue fail, reason=%s.", reader.getFormattedErrorMessages().c_str());
145         return -E_JSON_PARSE_FAIL;
146     }
147 #endif
148     // The jsoncpp lib parser in strict mode will still regard root type jsonarray as valid, but we require jsonobject
149     if (value_.type() != Json::ValueType::objectValue) {
150         value_ = Json::Value();
151         LOGE("[Json][Parse] Not an object at root.");
152         return -E_JSON_PARSE_FAIL;
153     }
154     isValid_ = true;
155     return E_OK;
156 }
157 
Parse(const std::vector<uint8_t> & inData)158 int JsonObject::Parse(const std::vector<uint8_t> &inData)
159 {
160     if (inData.empty()) {
161         return -E_INVALID_ARGS;
162     }
163     return Parse(inData.data(), inData.data() + inData.size());
164 }
165 
Parse(const uint8_t * dataBegin,const uint8_t * dataEnd)166 int JsonObject::Parse(const uint8_t *dataBegin, const uint8_t *dataEnd)
167 {
168     if (isValid_) {
169         LOGE("[Json][Parse] Already Valid.");
170         return -E_NOT_PERMIT;
171     }
172     if (dataBegin == nullptr || dataEnd == nullptr || dataBegin >= dataEnd) {
173         return -E_INVALID_ARGS;
174     }
175     int errCode = E_OK;
176     uint32_t nestDepth = CalculateNestDepth(dataBegin, dataEnd, errCode);
177     if (errCode != E_OK || nestDepth > maxNestDepth_) {
178         LOGE("[Json][Parse] Json calculate nest depth failed %d, depth:%" PRIu32 " exceed max allowed:%" PRIu32,
179             errCode, nestDepth, maxNestDepth_);
180         return -E_JSON_PARSE_FAIL;
181     }
182 #ifdef JSONCPP_USE_BUILDER
183     auto begin = reinterpret_cast<const std::string::value_type *>(dataBegin);
184     auto end = reinterpret_cast<const std::string::value_type *>(dataEnd);
185 
186     JSONCPP_STRING errs;
187     Json::CharReaderBuilder builder;
188     Json::CharReaderBuilder::strictMode(&builder.settings_);
189     builder[JSON_CONFIG_COLLECT_COMMENTS] = false;
190     builder[JSON_CONFIG_REJECT_DUP_KEYS] = false;
191     std::unique_ptr<Json::CharReader> const jsonReader(builder.newCharReader());
192     // The endDoc parameter of reader::parse refer to the byte after the string itself
193     if (!jsonReader->parse(begin, end, &value_, &errs)) {
194         value_ = Json::Value();
195         LOGE("[Json][Parse] Parse dataRange to JsonValue fail, reason=%s.", errs.c_str());
196         return -E_JSON_PARSE_FAIL;
197     }
198 #else
199     Json::Reader reader(Json::Features::strictMode());
200     auto begin = reinterpret_cast<const std::string::value_type *>(dataBegin);
201     auto end = reinterpret_cast<const std::string::value_type *>(dataEnd);
202     // The endDoc parameter of reader::parse refer to the byte after the string itself
203     if (!reader.parse(begin, end, value_, false)) {
204         value_ = Json::Value();
205         LOGE("[Json][Parse] Parse dataRange to JsonValue fail, reason=%s.", reader.getFormattedErrorMessages().c_str());
206         return -E_JSON_PARSE_FAIL;
207     }
208 #endif
209     // The jsoncpp lib parser in strict mode will still regard root type jsonarray as valid, but we require jsonobject
210     if (value_.type() != Json::ValueType::objectValue) {
211         value_ = Json::Value();
212         LOGE("[Json][Parse] Not an object at root.");
213         return -E_JSON_PARSE_FAIL;
214     }
215     isValid_ = true;
216     return E_OK;
217 }
218 
IsValid() const219 bool JsonObject::IsValid() const
220 {
221     return isValid_;
222 }
223 
ToString() const224 std::string JsonObject::ToString() const
225 {
226     if (!isValid_) {
227         LOGE("[Json][ToString] Not Valid Yet.");
228         return std::string();
229     }
230 #ifdef JSONCPP_USE_BUILDER
231     Json::StreamWriterBuilder writerBuilder;
232     writerBuilder[JSON_CONFIG_INDENTATION] = "";
233     writerBuilder[JSON_CONFIG_PRECISION] = JSON_VALUE_PRECISION;
234     std::unique_ptr<Json::StreamWriter> const jsonWriter(writerBuilder.newStreamWriter());
235     std::stringstream ss;
236     jsonWriter->write(value_, &ss);
237     // The endingLineFeedSymbol is left empty by default.
238     return ss.str();
239 #else
240     Json::FastWriter fastWriter;
241     // Call omitEndingLineFeed to let JsonCpp not append an \n at the end of string. If not doing so, when passing a
242     // minified jsonString, the result of this function will be one byte longer then the original, which may cause the
243     // result checked as length invalid by upper logic when the original length is just at the limitation boundary.
244     fastWriter.omitEndingLineFeed();
245     return fastWriter.write(value_);
246 #endif
247 }
248 
IsFieldPathExist(const FieldPath & inPath) const249 bool JsonObject::IsFieldPathExist(const FieldPath &inPath) const
250 {
251     if (!isValid_) {
252         LOGE("[Json][isExisted] Not Valid Yet.");
253         return false;
254     }
255     int errCode = E_OK;
256     (void)GetJsonValueByFieldPath(inPath, errCode); // Ignore return const reference
257     return (errCode == E_OK);
258 }
259 
GetFieldTypeByFieldPath(const FieldPath & inPath,FieldType & outType) const260 int JsonObject::GetFieldTypeByFieldPath(const FieldPath &inPath, FieldType &outType) const
261 {
262     if (!isValid_) {
263         LOGE("[Json][GetType] Not Valid Yet.");
264         return -E_NOT_PERMIT;
265     }
266     int errCode = E_OK;
267     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
268     if (errCode != E_OK) {
269         return errCode;
270     }
271     return GetFieldTypeByJsonValue(valueNode, outType);
272 }
273 
GetFieldValueByFieldPath(const FieldPath & inPath,FieldValue & outValue) const274 int JsonObject::GetFieldValueByFieldPath(const FieldPath &inPath, FieldValue &outValue) const
275 {
276     if (!isValid_) {
277         LOGE("[Json][GetValue] Not Valid Yet.");
278         return -E_NOT_PERMIT;
279     }
280     int errCode = E_OK;
281     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
282     if (errCode != E_OK) {
283         return errCode;
284     }
285     FieldType valueType;
286     errCode = GetFieldTypeByJsonValue(valueNode, valueType);
287     if (errCode != E_OK) {
288         return errCode;
289     }
290     switch (valueType) {
291         case FieldType::LEAF_FIELD_BOOL:
292             outValue.boolValue = valueNode.asBool();
293             break;
294         case FieldType::LEAF_FIELD_INTEGER:
295             outValue.integerValue = valueNode.asInt();
296             break;
297         case FieldType::LEAF_FIELD_LONG:
298             outValue.longValue = valueNode.asInt64();
299             break;
300         case FieldType::LEAF_FIELD_DOUBLE:
301             outValue.doubleValue = valueNode.asDouble();
302             break;
303         case FieldType::LEAF_FIELD_STRING:
304             outValue.stringValue = valueNode.asString();
305             break;
306         default:
307             return -E_NOT_SUPPORT;
308     }
309     return E_OK;
310 }
311 
GetSubFieldPath(const FieldPath & inPath,std::set<FieldPath> & outSubPath) const312 int JsonObject::GetSubFieldPath(const FieldPath &inPath, std::set<FieldPath> &outSubPath) const
313 {
314     if (!isValid_) {
315         LOGE("[Json][GetSubPath] Not Valid Yet.");
316         return -E_NOT_PERMIT;
317     }
318     int errCode = E_OK;
319     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
320     if (errCode != E_OK) {
321         return errCode;
322     }
323     if (valueNode.type() != Json::ValueType::objectValue) {
324         return -E_NOT_SUPPORT;
325     }
326     // Note: the subFields JsonCpp returnout will be different from each other
327     std::vector<std::string> subFields = valueNode.getMemberNames();
328     for (const auto &eachSubField : subFields) {
329         FieldPath eachSubPath = inPath;
330         eachSubPath.push_back(eachSubField);
331         outSubPath.insert(eachSubPath);
332     }
333     return E_OK;
334 }
335 
GetSubFieldPath(const std::set<FieldPath> & inPath,std::set<FieldPath> & outSubPath) const336 int JsonObject::GetSubFieldPath(const std::set<FieldPath> &inPath, std::set<FieldPath> &outSubPath) const
337 {
338     for (const auto &eachPath : inPath) {
339         int errCode = GetSubFieldPath(eachPath, outSubPath);
340         if (errCode != E_OK) {
341             return errCode;
342         }
343     }
344     return E_OK;
345 }
346 
GetSubFieldPathAndType(const FieldPath & inPath,std::map<FieldPath,FieldType> & outSubPathType) const347 int JsonObject::GetSubFieldPathAndType(const FieldPath &inPath, std::map<FieldPath, FieldType> &outSubPathType) const
348 {
349     if (!isValid_) {
350         LOGE("[Json][GetSubPathType] Not Valid Yet.");
351         return -E_NOT_PERMIT;
352     }
353     int errCode = E_OK;
354     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
355     if (errCode != E_OK) {
356         return errCode;
357     }
358     if (valueNode.type() != Json::ValueType::objectValue) {
359         return -E_NOT_SUPPORT;
360     }
361     // Note: the subFields JsonCpp returnout will be different from each other
362     std::vector<std::string> subFields = valueNode.getMemberNames();
363     for (const auto &eachSubField : subFields) {
364         FieldPath eachSubPath = inPath;
365         eachSubPath.push_back(eachSubField);
366         FieldType eachSubType;
367         errCode = GetFieldTypeByJsonValue(valueNode[eachSubField], eachSubType);
368         if (errCode != E_OK) {
369             return errCode;
370         }
371         outSubPathType[eachSubPath] = eachSubType;
372     }
373     return E_OK;
374 }
375 
GetSubFieldPathAndType(const std::set<FieldPath> & inPath,std::map<FieldPath,FieldType> & outSubPathType) const376 int JsonObject::GetSubFieldPathAndType(const std::set<FieldPath> &inPath,
377     std::map<FieldPath, FieldType> &outSubPathType) const
378 {
379     for (const auto &eachPath : inPath) {
380         int errCode = GetSubFieldPathAndType(eachPath, outSubPathType);
381         if (errCode != E_OK) {
382             return errCode;
383         }
384     }
385     return E_OK;
386 }
387 
GetArraySize(const FieldPath & inPath,uint32_t & outSize) const388 int JsonObject::GetArraySize(const FieldPath &inPath, uint32_t &outSize) const
389 {
390     if (!isValid_) {
391         LOGE("[Json][GetArraySize] Not Valid Yet.");
392         return -E_NOT_PERMIT;
393     }
394     int errCode = E_OK;
395     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
396     if (errCode != E_OK) {
397         return errCode;
398     }
399     if (valueNode.type() != Json::ValueType::arrayValue) {
400         return -E_NOT_SUPPORT;
401     }
402     outSize = valueNode.size();
403     return E_OK;
404 }
405 
GetArrayContentOfStringOrStringArray(const FieldPath & inPath,std::vector<std::vector<std::string>> & outContent) const406 int JsonObject::GetArrayContentOfStringOrStringArray(const FieldPath &inPath,
407     std::vector<std::vector<std::string>> &outContent) const
408 {
409     if (!isValid_) {
410         LOGE("[Json][GetArrayContent] Not Valid Yet.");
411         return -E_NOT_PERMIT;
412     }
413     int errCode = E_OK;
414     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
415     if (errCode != E_OK) {
416         LOGW("[Json][GetArrayContent] Get JsonValue Fail=%d.", errCode);
417         return errCode;
418     }
419     if (valueNode.type() != Json::ValueType::arrayValue) {
420         LOGE("[Json][GetArrayContent] Not an array.");
421         return -E_NOT_SUPPORT;
422     }
423     for (uint32_t index = 0; index < valueNode.size(); index++) {
424         const Json::Value &eachArrayItem = valueNode[index];
425         if (eachArrayItem.isString()) {
426             outContent.emplace_back(std::vector<std::string>({eachArrayItem.asString()}));
427             continue;
428         }
429         if (eachArrayItem.isArray()) {
430             if (eachArrayItem.empty()) {
431                 continue; // Ignore empty array-type member
432             }
433             outContent.emplace_back(std::vector<std::string>());
434             errCode = GetStringArrayContentByJsonValue(eachArrayItem, outContent.back());
435             if (errCode == E_OK) {
436                 continue; // Everything ok
437             }
438         }
439         // If reach here, then something is not ok
440         outContent.clear();
441         LOGE("[Json][GetArrayContent] Not string or array fail=%d at index:%" PRIu32, errCode, index);
442         return -E_NOT_SUPPORT;
443     }
444     return E_OK;
445 }
446 
447 namespace {
InsertFieldCheckParameter(const FieldPath & inPath,FieldType inType,const FieldValue & inValue,uint32_t maxNestDepth)448 bool InsertFieldCheckParameter(const FieldPath &inPath, FieldType inType, const FieldValue &inValue,
449     uint32_t maxNestDepth)
450 {
451     if (inPath.empty() || inPath.size() > maxNestDepth || inType == FieldType::LEAF_FIELD_ARRAY ||
452         inType == FieldType::INTERNAL_FIELD_OBJECT) {
453         return false;
454     }
455     // Infinite double not support
456     return !(inType == FieldType::LEAF_FIELD_DOUBLE && !std::isfinite(inValue.doubleValue));
457 }
458 
LeafJsonNodeAppendValue(Json::Value & leafNode,FieldType inType,const FieldValue & inValue)459 void LeafJsonNodeAppendValue(Json::Value &leafNode, FieldType inType, const FieldValue &inValue)
460 {
461     if (inType == FieldType::LEAF_FIELD_STRING) {
462         leafNode.append(Json::Value(inValue.stringValue));
463     }
464 }
465 
466 // Function design for InsertField call on an null-type Json::Value
LeafJsonNodeAssignValue(Json::Value & leafNode,FieldType inType,const FieldValue & inValue)467 void LeafJsonNodeAssignValue(Json::Value &leafNode, FieldType inType, const FieldValue &inValue)
468 {
469     switch (inType) {
470         case FieldType::LEAF_FIELD_BOOL:
471             leafNode = Json::Value(inValue.boolValue);
472             break;
473         case FieldType::LEAF_FIELD_INTEGER:
474             // Cast to Json::Int to avoid "ambiguous call of overloaded function"
475             leafNode = Json::Value(static_cast<Json::Int>(inValue.integerValue));
476             break;
477         case FieldType::LEAF_FIELD_LONG:
478             // Cast to Json::Int64 to avoid "ambiguous call of overloaded function"
479             leafNode = Json::Value(static_cast<Json::Int64>(inValue.longValue));
480             break;
481         case FieldType::LEAF_FIELD_DOUBLE:
482             leafNode = Json::Value(inValue.doubleValue);
483             break;
484         case FieldType::LEAF_FIELD_STRING:
485             leafNode = Json::Value(inValue.stringValue);
486             break;
487         case FieldType::LEAF_FIELD_OBJECT:
488             leafNode = Json::Value(Json::ValueType::objectValue);
489             break;
490         default:
491             // For LEAF_FIELD_NULL, Do nothing.
492             // For LEAF_FIELD_ARRAY and INTERNAL_FIELD_OBJECT, Not Support, had been excluded by InsertField
493             return;
494     }
495 }
496 }
497 
498 // move the nearest to the leaf of inPath, if not exist, will create it, else it should be an array object.
MoveToPath(const FieldPath & inPath,Json::Value * & exact,Json::Value * & nearest)499 int JsonObject::MoveToPath(const FieldPath &inPath, Json::Value *&exact, Json::Value *&nearest)
500 {
501     uint32_t nearDepth = 0;
502     int errCode = LocateJsonValueByFieldPath(inPath, exact, nearest, nearDepth);
503     if (errCode != -E_NOT_FOUND) { // Path already exist and it's not an array object
504         return -E_JSON_INSERT_PATH_EXIST;
505     }
506     // nearDepth 0 represent for root value. nearDepth equal to inPath.size indicate an exact path match
507     if (nearest == nullptr || nearDepth >= inPath.size()) { // Impossible
508         return -E_INTERNAL_ERROR;
509     }
510     if (nearest->type() != Json::ValueType::objectValue) { // path ends with type not object
511         return -E_JSON_INSERT_PATH_CONFLICT;
512     }
513     // Use nearDepth as startIndex pointing to the first field that lacked
514     for (uint32_t lackFieldIndex = nearDepth; lackFieldIndex < inPath.size(); lackFieldIndex++) {
515         // The new JsonValue is null-type, we can safely add members to an null-type JsonValue which will turn into
516         // object-type after member adding. Then move "nearest" to point to the new JsonValue.
517         nearest = &((*nearest)[inPath[lackFieldIndex]]);
518     }
519     return E_OK;
520 }
521 
InsertField(const FieldPath & inPath,const JsonObject & inValue,bool isAppend)522 int JsonObject::InsertField(const FieldPath &inPath, const JsonObject &inValue, bool isAppend)
523 {
524     if (inPath.empty() || inPath.size() > maxNestDepth_ || !inValue.IsValid()) {
525         return -E_INVALID_ARGS;
526     }
527     if (!isValid_) {
528         value_ = Json::Value(Json::ValueType::objectValue);
529         isValid_ = true;
530     }
531     Json::Value *exact = nullptr;
532     Json::Value *nearest = nullptr;
533     int errCode = MoveToPath(inPath, exact, nearest);
534     if (errCode != E_OK) {
535         return errCode;
536     }
537     LOGD("nearest type is %d", nearest->type());
538     if (isAppend || nearest->type() == Json::ValueType::arrayValue) {
539         nearest->append(inValue.value_);
540     } else {
541         *nearest = inValue.value_;
542     }
543     return E_OK;
544 }
545 
InsertField(const FieldPath & inPath,FieldType inType,const FieldValue & inValue,bool isAppend)546 int JsonObject::InsertField(const FieldPath &inPath, FieldType inType, const FieldValue &inValue, bool isAppend)
547 {
548     if (!InsertFieldCheckParameter(inPath, inType, inValue, maxNestDepth_)) {
549         return -E_INVALID_ARGS;
550     }
551     if (!isValid_) {
552         // Insert on invalid object never fail after parameter check ok, so here no need concern rollback.
553         value_ = Json::Value(Json::ValueType::objectValue);
554         isValid_ = true;
555     }
556     Json::Value *exact = nullptr;
557     Json::Value *nearest = nullptr;
558     int errCode = MoveToPath(inPath, exact, nearest);
559     if (errCode != E_OK) {
560         return errCode;
561     }
562     // Here "nearest" points to the JsonValue(null-type now) corresponding to the last field
563     if (isAppend || nearest->type() == Json::ValueType::arrayValue) {
564         LeafJsonNodeAppendValue(*nearest, inType, inValue);
565     } else {
566         LeafJsonNodeAssignValue(*nearest, inType, inValue);
567     }
568     return E_OK;
569 }
570 
DeleteField(const FieldPath & inPath)571 int JsonObject::DeleteField(const FieldPath &inPath)
572 {
573     if (!isValid_) {
574         LOGE("[Json][DeleteField] Not Valid Yet.");
575         return -E_NOT_PERMIT;
576     }
577     if (inPath.empty()) {
578         return -E_INVALID_ARGS;
579     }
580     Json::Value *exact = nullptr;
581     Json::Value *nearest = nullptr;
582     uint32_t nearDepth = 0;
583     int errCode = LocateJsonValueByFieldPath(inPath, exact, nearest, nearDepth);
584     if (errCode != E_OK) { // Path not exist
585         return -E_JSON_DELETE_PATH_NOT_FOUND;
586     }
587     // nearDepth should be equal to inPath.size() - 1, because nearest is at the parent path of inPath
588     if (nearest == nullptr || nearest->type() != Json::ValueType::objectValue || nearDepth != inPath.size() - 1) {
589         return -E_INTERNAL_ERROR; // Impossible
590     }
591     // Remove member from nearest, ignore returned removed Value, use nearDepth as index pointing to last field of path.
592     (void)nearest->removeMember(inPath[nearDepth]);
593     return E_OK;
594 }
595 
GetStringArrayContentByJsonValue(const Json::Value & value,std::vector<std::string> & outStringArray) const596 int JsonObject::GetStringArrayContentByJsonValue(const Json::Value &value,
597     std::vector<std::string> &outStringArray) const
598 {
599     if (value.type() != Json::ValueType::arrayValue) {
600         LOGE("[Json][GetStringArrayByValue] Not an array.");
601         return -E_NOT_SUPPORT;
602     }
603     for (uint32_t index = 0; index < value.size(); index++) {
604         const Json::Value &eachArrayItem = value[index];
605         if (!eachArrayItem.isString()) {
606             LOGE("[Json][GetStringArrayByValue] Index=%u in Array is not string.", index);
607             outStringArray.clear();
608             return -E_NOT_SUPPORT;
609         }
610         outStringArray.push_back(eachArrayItem.asString());
611     }
612     return E_OK;
613 }
614 
GetFieldTypeByJsonValue(const Json::Value & value,FieldType & outType) const615 int JsonObject::GetFieldTypeByJsonValue(const Json::Value &value, FieldType &outType) const
616 {
617     Json::ValueType valueType = value.type();
618     switch (valueType) {
619         case Json::ValueType::nullValue:
620             outType = FieldType::LEAF_FIELD_NULL;
621             break;
622         case Json::ValueType::booleanValue:
623             outType = FieldType::LEAF_FIELD_BOOL;
624             break;
625         // The case intValue and uintValue cover from INT64_MIN to UINT64_MAX. Inside this range, isInt() take range
626         // from INT32_MIN to INT32_MAX, which should be regard as LEAF_FIELD_INTEGER; isInt64() take range from
627         // INT64_MIN to INT64_MAX, which should be regard as LEAF_FIELD_LONG if it is not LEAF_FIELD_INTEGER;
628         // INT64_MAX + 1 to UINT64_MAX will be regard as LEAF_FIELD_DOUBLE, therefore lose its precision when read out
629         // as double value.
630         case Json::ValueType::intValue:
631         case Json::ValueType::uintValue:
632             if (value.isInt()) {
633                 outType = FieldType::LEAF_FIELD_INTEGER;
634             } else if (value.isInt64()) {
635                 outType = FieldType::LEAF_FIELD_LONG;
636             } else {
637                 outType = FieldType::LEAF_FIELD_DOUBLE; // The isDouble() judge is always true in this case.
638             }
639             break;
640         // Integral value beyond range INT64_MIN to UINT64_MAX will be recognized as realValue and lose its precision.
641         // Value in scientific notation or has decimal point will be recognized as realValue without exception,
642         // no matter whether the value is large or small, no matter with or without non-zero decimal part.
643         // In a word, when regard as DOUBLE type, a value can not guarantee its presision
644         case Json::ValueType::realValue:
645             // The isDouble() judge is always true in this case. A value exceed double range is not support.
646             outType = FieldType::LEAF_FIELD_DOUBLE;
647             if (!std::isfinite(value.asDouble())) {
648                 LOGE("[Json][GetTypeByJson] Infinite double not support.");
649                 return -E_NOT_SUPPORT;
650             }
651             break;
652         case Json::ValueType::stringValue:
653             outType = FieldType::LEAF_FIELD_STRING;
654             break;
655         case Json::ValueType::arrayValue:
656             outType = FieldType::LEAF_FIELD_ARRAY;
657             break;
658         case Json::ValueType::objectValue:
659             if (value.getMemberNames().empty()) {
660                 outType = FieldType::LEAF_FIELD_OBJECT;
661                 break;
662             }
663             outType = FieldType::INTERNAL_FIELD_OBJECT;
664             break;
665         default:
666             LOGE("[Json][GetTypeByJson] no such type.");
667             return -E_NOT_SUPPORT;
668     }
669     return E_OK;
670 }
671 
GetJsonValueByFieldPath(const FieldPath & inPath,int & errCode) const672 const Json::Value &JsonObject::GetJsonValueByFieldPath(const FieldPath &inPath, int &errCode) const
673 {
674     // Root path always exist
675     if (inPath.empty()) {
676         errCode = E_OK;
677         return value_;
678     }
679     const Json::Value *valueNode = &value_;
680     for (const auto &eachPathSegment : inPath) {
681         if ((valueNode->type() != Json::ValueType::objectValue) || (!valueNode->isMember(eachPathSegment))) {
682             // Current JsonValue is not an object, or no such member field
683             errCode = -E_INVALID_PATH;
684             return value_;
685         }
686         valueNode = &((*valueNode)[eachPathSegment]);
687     }
688     errCode = E_OK;
689     return *valueNode;
690 }
691 
LocateJsonValueByFieldPath(const FieldPath & inPath,Json::Value * & exact,Json::Value * & nearest,uint32_t & nearDepth)692 int JsonObject::LocateJsonValueByFieldPath(const FieldPath &inPath, Json::Value *&exact,
693     Json::Value *&nearest, uint32_t &nearDepth)
694 {
695     if (!isValid_) {
696         return -E_NOT_PERMIT;
697     }
698     exact = &value_;
699     nearest = &value_;
700     nearDepth = 0;
701     if (inPath.empty()) {
702         return E_OK;
703     }
704     for (const auto &eachPathSegment : inPath) {
705         nearest = exact; // Let "nearest" trace "exact" before "exact" go deeper
706         if (nearest != &value_) {
707             nearDepth++; // For each "nearest" trace up "exact", increase nearDepth to indicate where it is.
708         }
709         if ((exact->type() != Json::ValueType::objectValue) || (!exact->isMember(eachPathSegment))) {
710             // "exact" is not an object, or no such member field
711             exact = nullptr; // Set "exact" to nullptr indicate exact path not exist
712             return -E_NOT_FOUND;
713         }
714         exact = &((*exact)[eachPathSegment]); // "exact" go deeper
715     }
716     if (exact->type() == Json::ValueType::arrayValue) {
717         return -E_NOT_FOUND; // could append value if path is an array field.
718     }
719     // Here, JsonValue exist at exact path, "nearest" is "exact" parent.
720     return E_OK;
721 }
722 
GetObjectArrayByFieldPath(const FieldPath & inPath,std::vector<JsonObject> & outArray) const723 int JsonObject::GetObjectArrayByFieldPath(const FieldPath &inPath, std::vector<JsonObject> &outArray) const
724 {
725     if (!isValid_) {
726         LOGE("[Json][GetValue] Not Valid Yet.");
727         return -E_NOT_PERMIT;
728     }
729     int errCode = E_OK;
730     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
731     if (errCode != E_OK) {
732         LOGE("[Json][GetValue] Get json value failed. %d", errCode);
733         return errCode;
734     }
735 
736     if (!valueNode.isArray()) {
737         LOGE("[Json][GetValue] Not Array type.");
738         return -E_NOT_PERMIT;
739     }
740     for (Json::ArrayIndex i = 0; i < valueNode.size(); ++i) {
741         outArray.emplace_back(JsonObject(valueNode[i]));
742     }
743     return E_OK;
744 }
745 
GetObjectByFieldPath(const FieldPath & inPath,JsonObject & outObj) const746 int JsonObject::GetObjectByFieldPath(const FieldPath &inPath, JsonObject &outObj) const
747 {
748     if (!isValid_) {
749         LOGE("[Json][GetValue] Not Valid Yet.");
750         return -E_NOT_PERMIT;
751     }
752     int errCode = E_OK;
753     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
754     if (errCode != E_OK) {
755         LOGE("[Json][GetValue] Get json value failed. %d", errCode);
756         return errCode;
757     }
758 
759     if (!valueNode.isObject()) {
760         LOGE("[Json][GetValue] Not Object type.");
761         return -E_NOT_PERMIT;
762     }
763     outObj = JsonObject(valueNode);
764     return E_OK;
765 }
766 
GetStringArrayByFieldPath(const FieldPath & inPath,std::vector<std::string> & outArray) const767 int JsonObject::GetStringArrayByFieldPath(const FieldPath &inPath, std::vector<std::string> &outArray) const
768 {
769     if (!isValid_) {
770         LOGE("[Json][GetValue] Not Valid Yet.");
771         return -E_NOT_PERMIT;
772     }
773     int errCode = E_OK;
774     const Json::Value &valueNode = GetJsonValueByFieldPath(inPath, errCode);
775     if (errCode != E_OK) {
776         LOGE("[Json][GetValue] Get json value failed. %d", errCode);
777         return errCode;
778     }
779 
780     return GetStringArrayContentByJsonValue(valueNode, outArray);
781 }
782 
783 #else // OMIT_JSON
784 uint32_t JsonObject::SetMaxNestDepth(uint32_t nestDepth)
785 {
786     (void)nestDepth;
787     return 0;
788 }
789 
790 uint32_t JsonObject::CalculateNestDepth(const std::string &inString, int &errCode)
791 {
792     (void)inString;
793     (void)errCode;
794     return 0;
795 }
796 
797 uint32_t JsonObject::CalculateNestDepth(const uint8_t *dataBegin, const uint8_t *dataEnd, int &errCode)
798 {
799     (void)dataBegin;
800     (void)dataEnd;
801     (void)errCode;
802     return 0;
803 }
804 
805 JsonObject::JsonObject(const JsonObject &other) = default;
806 
807 JsonObject& JsonObject::operator=(const JsonObject &other) = default;
808 
809 int JsonObject::Parse(const std::string &inString)
810 {
811     (void)inString;
812     LOGW("[Json][Parse] Json Omit From Compile.");
813     return -E_NOT_PERMIT;
814 }
815 
816 int JsonObject::Parse(const std::vector<uint8_t> &inData)
817 {
818     (void)inData;
819     LOGW("[Json][Parse] Json Omit From Compile.");
820     return -E_NOT_PERMIT;
821 }
822 
823 int JsonObject::Parse(const uint8_t *dataBegin, const uint8_t *dataEnd)
824 {
825     (void)dataBegin;
826     (void)dataEnd;
827     LOGW("[Json][Parse] Json Omit From Compile.");
828     return -E_NOT_PERMIT;
829 }
830 
831 bool JsonObject::IsValid() const
832 {
833     return false;
834 }
835 
836 std::string JsonObject::ToString() const
837 {
838     return std::string();
839 }
840 
841 bool JsonObject::IsFieldPathExist(const FieldPath &inPath) const
842 {
843     (void)inPath;
844     return false;
845 }
846 
847 int JsonObject::GetFieldTypeByFieldPath(const FieldPath &inPath, FieldType &outType) const
848 {
849     (void)inPath;
850     (void)outType;
851     return -E_NOT_PERMIT;
852 }
853 
854 int JsonObject::GetFieldValueByFieldPath(const FieldPath &inPath, FieldValue &outValue) const
855 {
856     (void)inPath;
857     (void)outValue;
858     return -E_NOT_PERMIT;
859 }
860 
861 int JsonObject::GetSubFieldPath(const FieldPath &inPath, std::set<FieldPath> &outSubPath) const
862 {
863     (void)inPath;
864     (void)outSubPath;
865     return -E_NOT_PERMIT;
866 }
867 
868 int JsonObject::GetSubFieldPath(const std::set<FieldPath> &inPath, std::set<FieldPath> &outSubPath) const
869 {
870     (void)inPath;
871     (void)outSubPath;
872     return -E_NOT_PERMIT;
873 }
874 
875 int JsonObject::GetSubFieldPathAndType(const FieldPath &inPath, std::map<FieldPath, FieldType> &outSubPathType) const
876 {
877     (void)inPath;
878     (void)outSubPathType;
879     return -E_NOT_PERMIT;
880 }
881 
882 int JsonObject::GetSubFieldPathAndType(const std::set<FieldPath> &inPath,
883     std::map<FieldPath, FieldType> &outSubPathType) const
884 {
885     (void)inPath;
886     (void)outSubPathType;
887     return -E_NOT_PERMIT;
888 }
889 
890 int JsonObject::GetArraySize(const FieldPath &inPath, uint32_t &outSize) const
891 {
892     (void)inPath;
893     (void)outSize;
894     return -E_NOT_PERMIT;
895 }
896 
897 int JsonObject::GetArrayContentOfStringOrStringArray(const FieldPath &inPath,
898     std::vector<std::vector<std::string>> &outContent) const
899 {
900     (void)inPath;
901     (void)outContent;
902     return -E_NOT_PERMIT;
903 }
904 
905 int JsonObject::InsertField(const FieldPath &inPath, FieldType inType, const FieldValue &inValue)
906 {
907     (void)inPath;
908     (void)inType;
909     (void)inValue;
910     return -E_NOT_PERMIT;
911 }
912 
913 int JsonObject::InsertField(const FieldPath &inPath, const JsonObject &inValue, bool isAppend = false)
914 {
915     (void)inPath;
916     (void)inValue;
917     (void)isAppend;
918     return -E_NOT_PERMIT;
919 }
920 
921 int JsonObject::DeleteField(const FieldPath &inPath)
922 {
923     (void)inPath;
924     return -E_NOT_PERMIT;
925 }
926 
927 int JsonObject::GetArrayValueByFieldPath(const FieldPath &inPath, JsonObject &outArray) const
928 {
929     (void)inPath;
930     (void)outArray;
931     return -E_NOT_PERMIT;
932 }
933 #endif // OMIT_JSON
934 } // namespace DistributedDB
935