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