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 OMIT_MULTI_VER
17 #include "multi_ver_value_object.h"
18 #include "parcel.h"
19 
20 namespace DistributedDB {
21 namespace {
22     const size_t SLICE_HASH_VALUE_SIZE = 32;
23 }
24 
GetValueHash(std::vector<ValueSliceHash> & valueHashes) const25 int MultiVerValueObject::GetValueHash(std::vector<ValueSliceHash> &valueHashes) const
26 {
27     if (!IsHash()) {
28         return E_OK;
29     }
30 
31     for (size_t i = 0; i < valueHashVector_.size() / SLICE_HASH_VALUE_SIZE; i++) {
32         ValueSliceHash sliceHash;
33         sliceHash.assign(valueHashVector_.begin() + i * SLICE_HASH_VALUE_SIZE,
34                          valueHashVector_.begin() + (i + 1) * SLICE_HASH_VALUE_SIZE);
35         valueHashes.push_back(std::move(sliceHash));
36     }
37     return E_OK;
38 }
39 
SetValueHash(const std::vector<ValueSliceHash> & valueHashes)40 int MultiVerValueObject::SetValueHash(const std::vector<ValueSliceHash> &valueHashes)
41 {
42     valueHashVector_.clear();
43     valueHashVector_.shrink_to_fit();
44     for (const auto &item : valueHashes) {
45         valueHashVector_.insert(valueHashVector_.end(), item.begin(), item.end());
46     }
47     head_.flag = HASH_FLAG;
48     return E_OK;
49 }
50 
GetSerialData(std::vector<uint8_t> & data) const51 int MultiVerValueObject::GetSerialData(std::vector<uint8_t> &data) const
52 {
53     const uint32_t serialIntNum = 4; // 4 int
54     size_t totalLength = Parcel::GetIntLen() * serialIntNum + Parcel::GetVectorCharLen(valueHashVector_);
55     data.resize(totalLength);
56     Parcel parcel(data.data(), data.size());
57 
58     int errCode = parcel.WriteInt(head_.flag);
59     if (errCode != E_OK) {
60         return errCode;
61     }
62 
63     errCode = parcel.WriteInt(head_.reserved);
64     if (errCode != E_OK) {
65         return errCode;
66     }
67 
68     errCode = parcel.WriteInt(head_.hashNum);
69     if (errCode != E_OK) {
70         return errCode;
71     }
72 
73     errCode = parcel.WriteInt(head_.length);
74     if (errCode != E_OK) {
75         return errCode;
76     }
77 
78     errCode = parcel.WriteVectorChar(valueHashVector_);
79     if (errCode != E_OK) {
80         return errCode;
81     }
82 
83     return E_OK;
84 }
85 
DeSerialData(const std::vector<uint8_t> & data)86 int MultiVerValueObject::DeSerialData(const std::vector<uint8_t> &data)
87 {
88     Parcel parcel(const_cast<uint8_t *>(data.data()), data.size());
89     int32_t readValue = 0;
90     parcel.ReadInt(readValue);
91     head_.flag = static_cast<uint8_t>(readValue);
92     parcel.ReadInt(readValue);
93     head_.reserved = static_cast<uint8_t>(readValue);
94     parcel.ReadInt(readValue);
95     head_.hashNum = static_cast<uint16_t>(readValue);
96     parcel.ReadInt(readValue);
97     head_.length = static_cast<uint32_t>(readValue);
98     parcel.ReadVectorChar(valueHashVector_);
99     if (parcel.IsError()) {
100         LOGE("Deserial the multi ver value object error");
101         return -E_PARSE_FAIL;
102     }
103     if (((head_.flag & HASH_FLAG) == HASH_FLAG) && ((valueHashVector_.size() % SLICE_HASH_VALUE_SIZE) != 0)) {
104         LOGE("Value hash list total size is unexpected:%zu", valueHashVector_.size());
105         return -E_PARSE_FAIL;
106     }
107     return E_OK;
108 }
109 
GetDataLength() const110 uint32_t MultiVerValueObject::GetDataLength() const
111 {
112     return head_.length;
113 }
114 
SetDataLength(uint32_t length)115 void MultiVerValueObject::SetDataLength(uint32_t length)
116 {
117     head_.length = length;
118 }
119 
GetValue(Value & value) const120 int MultiVerValueObject::GetValue(Value &value) const
121 {
122     if ((head_.flag & HASH_FLAG) == HASH_FLAG) {
123         return -E_NOT_SUPPORT;
124     }
125     value.assign(valueHashVector_.begin(), valueHashVector_.end());
126     return E_OK;
127 }
128 
SetValue(const Value & value)129 int MultiVerValueObject::SetValue(const Value &value)
130 {
131     head_.flag = 0;
132     valueHashVector_.clear();
133     valueHashVector_.shrink_to_fit();
134     valueHashVector_.assign(value.begin(), value.end());
135     return E_OK;
136 }
137 
IsHash() const138 bool MultiVerValueObject::IsHash() const
139 {
140     return (head_.flag & HASH_FLAG) == HASH_FLAG;
141 }
142 
SetFlag(uint8_t flag)143 void MultiVerValueObject::SetFlag(uint8_t flag)
144 {
145     head_.flag = flag;
146 }
147 }
148 #endif
149