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