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