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