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