e89ac79ff22210a7d2ebf7c5c0bd1844f068abe2
[platform/core/base/bundle.git] / src / key-info-internal.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <cstring>
18
19 #include "include/bundle.h"
20
21 #include "exception-internal.h"
22 #include "key-info-internal.h"
23
24 namespace tizen_base {
25 namespace internal {
26
27 KeyInfo::KeyInfo(int type, std::string key,
28     std::vector<unsigned char> value)
29   : type_(type),
30     key_(std::move(key)) {
31   int ret = SetValue(value);
32   if (ret != BUNDLE_ERROR_NONE)
33     THROW(ret);
34 }
35
36 KeyInfo::KeyInfo(int type, std::string key,
37     std::vector<std::vector<unsigned char>> values)
38   : type_(type),
39     key_(std::move(key)) {
40   int ret = SetValues(values);
41   if (ret != BUNDLE_ERROR_NONE)
42     THROW(ret);
43 }
44
45 KeyInfo::KeyInfo(std::vector<unsigned char> encoded_bytes) {
46   int ret = Decode(encoded_bytes);
47   if (ret != BUNDLE_ERROR_NONE)
48     THROW(ret);
49 }
50
51 KeyInfo::~KeyInfo() = default;
52
53 KeyInfo::KeyInfo(const KeyInfo& key_info) {
54   type_ = key_info.type_;
55   key_ = key_info.key_;
56   values_size_ = key_info.values_size_;
57   uvalues_size_ = key_info.uvalues_size_;
58   for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
59     auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
60     if (new_value == nullptr)
61       THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
62
63     std::copy(key_info.values_[i].get(),
64         key_info.values_[i].get() + values_size_[i], new_value);
65     values_.emplace_back(new_value);
66   }
67 }
68
69 KeyInfo& KeyInfo::operator = (const KeyInfo& key_info) {
70   if (this != &key_info) {
71     type_ = key_info.type_;
72     key_ = key_info.key_;
73     values_size_ = key_info.values_size_;
74     uvalues_size_ = key_info.uvalues_size_;
75     for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
76       auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
77       if (new_value == nullptr)
78         THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
79
80       std::copy(key_info.values_[i].get(),
81           key_info.values_[i].get() + values_size_[i], new_value);
82       values_.emplace_back(new_value);
83     }
84   }
85   return *this;
86 }
87
88 KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
89   type_ = key_info.type_;
90   key_info.type_ = 0;
91   key_ = std::move(key_info.key_);
92   values_ = std::move(key_info.values_);
93   values_size_ = std::move(key_info.values_size_);
94   uvalues_size_ = std::move(key_info.uvalues_size_);
95 }
96
97 KeyInfo& KeyInfo::operator = (KeyInfo&& key_info) noexcept {
98   if (this != &key_info) {
99     type_ = key_info.type_;
100     key_info.type_ = 0;
101     key_ = std::move(key_info.key_);
102     values_ = std::move(key_info.values_);
103     values_size_ = std::move(key_info.values_size_);
104     uvalues_size_ = std::move(key_info.uvalues_size_);
105   }
106   return *this;
107 }
108
109 bool KeyInfo::operator == (const KeyInfo& key_info) {
110   if (this == &key_info)
111     return true;
112
113   if (type_ != key_info.type_)
114     return false;
115
116   if (key_ != key_info.key_)
117     return false;
118
119   if (values_.size() != key_info.values_.size())
120     return false;
121
122   for (unsigned int i = 0; i < values_.size(); ++i) {
123     if (values_size_[i] == key_info.values_size_[i])
124       return false;
125
126     int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
127         values_size_[i]);
128     if (ret == 0)
129       return false;
130   }
131
132   return true;
133 }
134
135 int KeyInfo::GetType() const {
136   return type_;
137 }
138
139 bool KeyInfo::IsArray() const {
140   if (type_ & BUNDLE_TYPE_ARRAY)
141     return true;
142
143   return false;
144 }
145
146 const std::string& KeyInfo::GetKey() {
147   return key_;
148 }
149
150 const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
151   return values_;
152 }
153
154 const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
155   return values_size_;
156 }
157
158 const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
159   return uvalues_size_;
160 }
161
162 int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
163   auto* new_value = new (std::nothrow) unsigned char[value.size()];
164   if (new_value == nullptr)
165     return BUNDLE_ERROR_OUT_OF_MEMORY;
166
167   std::copy(value.begin(), value.end(), new_value);
168   values_.emplace_back(new_value);
169   values_size_.push_back(value.size());
170   uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
171   return BUNDLE_ERROR_NONE;
172 }
173
174 int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
175   for (unsigned int i = 0; i< values.size(); ++i) {
176     auto* new_value = new (std::nothrow) unsigned char[values[i].size()];
177     if (new_value == nullptr)
178       return BUNDLE_ERROR_OUT_OF_MEMORY;
179
180     std::copy(values[i].begin(), values[i].end(), new_value);
181     values_.emplace_back(new_value);
182     values_size_.push_back(values[i].size());
183     uvalues_size_.push_back(values[i].size());
184   }
185   return BUNDLE_ERROR_NONE;
186 }
187
188 std::vector<unsigned char> KeyInfo::Encode() {
189   std::size_t encoded_size = GetEncodedSize();
190   if (encoded_size == 0)
191     return {};
192
193   std::vector<unsigned char> bytes;
194
195   // total size
196   unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
197   bytes.insert(bytes.end(), p, p + sizeof(encoded_size));
198
199   // type
200   p = reinterpret_cast<unsigned char*>(&type_);
201   bytes.insert(bytes.end(), p, p + sizeof(type_));
202
203   // key size
204   std::size_t key_length = key_.length() + 1;
205   p = reinterpret_cast<unsigned char*>(&key_length);
206   bytes.insert(bytes.end(), p, p + sizeof(key_length));
207
208   // key
209   bytes.insert(bytes.end(), key_.begin(), key_.end() + 1);
210
211   if (type_ & BUNDLE_TYPE_ARRAY) {
212     // values size
213     std::size_t values_size = values_.size();
214     p = reinterpret_cast<unsigned char*>(&values_size);
215     bytes.insert(bytes.end(), p , p + sizeof(values_size));
216   }
217
218   // values
219   for (unsigned int i = 0; i < values_.size(); i++) {
220     std::size_t value_size = values_size_[i];
221     p = reinterpret_cast<unsigned char*>(&value_size);
222     bytes.insert(bytes.end(), p, p + sizeof(value_size));
223
224     bytes.insert(bytes.end(), values_[i].get(), values_[i].get() + value_size);
225   }
226
227   return bytes;
228 }
229
230 std::size_t KeyInfo::GetEncodedSize() {
231   // total size
232   std::size_t encoded_size = sizeof(std::size_t);
233
234   // type
235   encoded_size += sizeof(int);
236
237   // key size
238   encoded_size += sizeof(std::size_t);
239
240   // key
241   if ((encoded_size + key_.length() + 1) < encoded_size)
242     return 0;
243
244   encoded_size += key_.length() + 1;
245
246   if (type_ & BUNDLE_TYPE_ARRAY) {
247     // values size
248     if ((encoded_size + sizeof(std::size_t)) < encoded_size)
249       return 0;
250
251     encoded_size += sizeof(std::size_t);
252   }
253
254   // values
255   std::size_t values_size = 0;
256   for (unsigned int i = 0; i < values_.size(); ++i) {
257     // value size
258     if ((values_size + sizeof(std::size_t)) < values_size)
259       return 0;
260
261     values_size += sizeof(std::size_t);
262
263     // value
264     if ((values_size + values_size_[i]) < values_size)
265       return 0;
266
267     values_size += values_size_[i];
268   }
269
270   if ((encoded_size + values_size) < encoded_size)
271     return 0;
272
273   encoded_size += values_size;
274
275   return encoded_size;
276 }
277
278 int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
279   unsigned int reader = 0;
280
281   // total size
282   std::size_t total_size = 0;
283   if ((reader + sizeof(total_size)) > bytes.size())
284     return BUNDLE_ERROR_INVALID_PARAMETER;
285
286   unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
287   std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
288   reader += sizeof(total_size);
289
290   // type
291   if ((reader + sizeof(type_)) > bytes.size())
292     return BUNDLE_ERROR_INVALID_PARAMETER;
293
294   p = reinterpret_cast<unsigned char*>(&type_);
295   std::copy(&bytes[reader], &bytes[reader] + sizeof(type_),  p);
296   reader += sizeof(type_);
297
298   // key size
299   std::size_t key_size = 0;
300
301   if ((reader + sizeof(key_size)) > bytes.size())
302     return BUNDLE_ERROR_INVALID_PARAMETER;
303
304   p = reinterpret_cast<unsigned char*>(&key_size);
305   std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
306   reader += sizeof(key_size);
307
308   if ((reader + key_size) > bytes.size())
309     return BUNDLE_ERROR_INVALID_PARAMETER;
310
311   // key
312   std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
313   p = reinterpret_cast<unsigned char*>(&key[0]);
314   key_ = std::string(reinterpret_cast<char*>(p));
315   reader += key_size;
316
317   std::size_t values_size = 0;
318   if (type_ & BUNDLE_TYPE_ARRAY) {
319     // values size
320     if ((reader + sizeof(values_size)) > bytes.size())
321       return BUNDLE_ERROR_INVALID_PARAMETER;
322
323     p = reinterpret_cast<unsigned char*>(&values_size);
324     std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
325     reader += sizeof(values_size);
326   } else {
327     values_size = 1;
328   }
329
330   // values
331   for (std::size_t i = 0; i < values_size; ++i) {
332     // value_size
333     std::size_t value_size = 0;
334     if ((reader + sizeof(value_size)) > bytes.size())
335       return BUNDLE_ERROR_INVALID_PARAMETER;
336
337     p = reinterpret_cast<unsigned char*>(&value_size);
338     std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
339     reader += sizeof(value_size);
340
341     // value
342     if ((reader + value_size) > bytes.size())
343       return BUNDLE_ERROR_INVALID_PARAMETER;
344
345     auto* new_value = new (std::nothrow) unsigned char[value_size];
346     if (new_value == nullptr)
347       return BUNDLE_ERROR_OUT_OF_MEMORY;
348
349     std::copy(&bytes[reader], &bytes[reader] + value_size, new_value);
350     reader += value_size;
351
352     values_.emplace_back(new_value);
353     values_size_.push_back(value_size);
354     uvalues_size_.push_back(static_cast<unsigned int>(value_size));
355   }
356
357   return BUNDLE_ERROR_NONE;
358 }
359
360 int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
361   if (index > GetSize() || index < 0)
362     return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
363
364   if (!IsArray())
365     return BUNDLE_ERROR_INVALID_PARAMETER;
366
367   auto* new_value = new (std::nothrow) unsigned char[value.size()];
368   if (new_value == nullptr)
369     return BUNDLE_ERROR_OUT_OF_MEMORY;
370
371   if (value.size() != 0)
372     std::copy(value.begin(), value.end(), new_value);
373
374   values_[index].reset(new_value);
375   values_size_[index] = value.size();
376   uvalues_size_[index] = static_cast<unsigned int>(value.size());
377   return BUNDLE_ERROR_NONE;
378 }
379
380 int KeyInfo::GetSize() const {
381   return values_.size();
382 }
383
384 }  // namespace internal
385 }  // namespace tizen_base