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