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