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 #ifndef VALUE_OBJECT_H
17 #define VALUE_OBJECT_H
18 
19 #include "json_object.h"
20 
21 namespace DistributedDB {
22 // ValueObject is the abstraction of value of KvEntry, a value is not always an json in different solutions.
23 // Thus, ValueObject can't just inherit JsonObject, although their methods are nearly the same.
24 class ValueObject {
25 public:
26     // Support default constructor, copy constructor and copy assignment
27     ValueObject() = default;
28     ~ValueObject() = default;
29     ValueObject(const ValueObject &);
30     ValueObject& operator=(const ValueObject &);
31 
32     // Move constructor and move assignment is not need currently
33     ValueObject(ValueObject &&) = delete;
34     ValueObject& operator=(ValueObject &&) = delete;
35 
36     // Should be called on an invalid ValueObject, create new ValueObject if need to reparse
37     int Parse(const std::string &inString);
38     int Parse(const std::vector<uint8_t> &inData); // Whether ends with '\0' in vector is OK
39 
40     // The end refer to the byte after the last valid byte
41     int Parse(const uint8_t *dataBegin, const uint8_t *dataEnd, uint32_t offset = 0);
42 
43     bool IsValid() const;
44 
45     // Unnecessary spacing will be removed and fieldname resorted by lexicographical order
46     std::string ToString() const;
47     void WriteIntoVector(std::vector<uint8_t> &outData) const; // An vector version ToString
48 
49     bool IsFieldPathExist(const FieldPath &inPath) const;
50     int GetFieldTypeByFieldPath(const FieldPath &inPath, FieldType &outType) const;
51     int GetFieldValueByFieldPath(const FieldPath &inPath, FieldValue &outValue) const;
52 
53     // An empty fieldpath indicate the root, the outSubPath should be empty before call, we will not empty it at first.
54     // If inPath is of multiple path, then outSubPath is combination of result of each inPath.
55     int GetSubFieldPath(const FieldPath &inPath, std::set<FieldPath> &outSubPath) const;
56     int GetSubFieldPath(const std::set<FieldPath> &inPath, std::set<FieldPath> &outSubPath) const;
57     int GetSubFieldPathAndType(const FieldPath &inPath, std::map<FieldPath, FieldType> &outSubPathType) const;
58     int GetSubFieldPathAndType(const std::set<FieldPath> &inPath, std::map<FieldPath, FieldType> &outSubPathType) const;
59 
60     // Can be called no matter ValueObject valid or not. Invalid turn into valid after successful call. An empty inPath
61     // is not allowed. LEAF_FIELD_ARRAY and INTERNAL_FIELD_OBJECT is not supported. infinite double is not support.
62     // inValue is ignored for LEAF_FIELD_NULL. If inPath already exist or nearest path ends with type not object,
63     // returns not E_OK. Otherwise insert field as well as filling up intermediate field, then returns E_OK;
64     int InsertField(const FieldPath &inPath, FieldType inType, const FieldValue &inValue);
65 
66     // Should be called on an valid ValueObject. Never turn into invalid after call. An empty inPath is not allowed.
67     // If inPath not exist, returns not E_OK. Otherwise delete field from its parent returns E_OK;
68     int DeleteField(const FieldPath &inPath);
69 private:
70     bool isValid_ = false;
71     JsonObject value_;
72     std::vector<uint8_t> dataBeforeOffset_;
73 };
74 } // namespace DistributedDB
75 #endif // VALUE_OBJECT_H