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