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