Refactor bundle implementation
[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 <algorithm>
18 #include <cstring>
19 #include <utility>
20
21 #include "include/bundle.h"
22
23 #include "exception-internal.h"
24 #include "key-info-internal.h"
25
26 namespace tizen_base {
27 namespace internal {
28
29 KeyInfo::KeyInfo(int type, std::string key, std::vector<unsigned char> value)
30     : type_(type), 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), key_(std::move(key)) {
39   int ret = SetValues(values);
40   if (ret != BUNDLE_ERROR_NONE)
41     THROW(ret);
42 }
43
44 KeyInfo::KeyInfo(std::vector<unsigned char> encoded_bytes) {
45   int ret = Decode(encoded_bytes);
46   if (ret != BUNDLE_ERROR_NONE)
47     THROW(ret);
48 }
49
50 KeyInfo::KeyInfo(const KeyInfo& key_info) {
51   values_.reserve(key_info.values_.size());
52   try {
53     for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
54       auto new_value =
55           std::make_unique<unsigned char[]>(key_info.values_size_[i]);
56       std::copy(key_info.values_[i].get(),
57           key_info.values_[i].get() + key_info.values_size_[i],
58           new_value.get());
59       values_.push_back(std::move(new_value));
60     }
61   } catch (const std::bad_alloc& e) {
62     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
63   }
64
65   type_ = key_info.type_;
66   key_ = key_info.key_;
67   values_size_ = key_info.values_size_;
68   uvalues_size_ = key_info.uvalues_size_;
69 }
70
71 KeyInfo& KeyInfo::operator=(const KeyInfo& key_info) {
72   if (this != &key_info) {
73     decltype(values_) new_values;
74     try {
75       for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
76         auto new_value =
77             std::make_unique<unsigned char[]>(key_info.values_size_[i]);
78         std::copy(key_info.values_[i].get(),
79             key_info.values_[i].get() + key_info.values_size_[i],
80             new_value.get());
81         new_values.push_back(std::move(new_value));
82       }
83     } catch (const std::bad_alloc& e) {
84       THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
85     }
86
87     type_ = key_info.type_;
88     key_ = key_info.key_;
89     values_size_ = key_info.values_size_;
90     uvalues_size_ = key_info.uvalues_size_;
91     values_ = std::move(new_values);
92   }
93
94   return *this;
95 }
96
97 KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
98   type_ = key_info.type_;
99   key_info.type_ = 0;
100   key_ = std::move(key_info.key_);
101   values_ = std::move(key_info.values_);
102   values_size_ = std::move(key_info.values_size_);
103   uvalues_size_ = std::move(key_info.uvalues_size_);
104 }
105
106 KeyInfo& KeyInfo::operator=(KeyInfo&& key_info) noexcept {
107   if (this != &key_info) {
108     type_ = key_info.type_;
109     key_info.type_ = 0;
110     key_ = std::move(key_info.key_);
111     values_ = std::move(key_info.values_);
112     values_size_ = std::move(key_info.values_size_);
113     uvalues_size_ = std::move(key_info.uvalues_size_);
114   }
115   return *this;
116 }
117
118 bool KeyInfo::operator==(const KeyInfo& key_info) {
119   if (this == &key_info)
120     return true;
121
122   if (type_ != key_info.type_)
123     return false;
124
125   if (key_ != key_info.key_)
126     return false;
127
128   if (values_.size() != key_info.values_.size())
129     return false;
130
131   for (unsigned int i = 0; i < values_.size(); ++i) {
132     if (values_size_[i] != key_info.values_size_[i])
133       return false;
134
135     int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
136         values_size_[i]);
137     if (ret != 0)
138       return false;
139   }
140
141   return true;
142 }
143
144 int KeyInfo::GetType() const {
145   return type_;
146 }
147
148 bool KeyInfo::IsArray() const {
149   if (type_ & BUNDLE_TYPE_ARRAY)
150     return true;
151
152   return false;
153 }
154
155 const std::string& KeyInfo::GetKey() {
156   return key_;
157 }
158
159 const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
160   return values_;
161 }
162
163 const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
164   return values_size_;
165 }
166
167 const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
168   return uvalues_size_;
169 }
170
171 int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
172   try {
173     auto new_value = std::make_unique<unsigned char[]>(value.size());
174     std::copy(value.begin(), value.end(), new_value.get());
175     values_.emplace_back(std::move(new_value));
176   } catch (const std::bad_alloc& e) {
177     return BUNDLE_ERROR_OUT_OF_MEMORY;
178   }
179
180   values_size_.push_back(value.size());
181   uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
182   return BUNDLE_ERROR_NONE;
183 }
184
185 int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
186   try {
187     for (unsigned int i = 0; i < values.size(); ++i) {
188       auto new_value = std::make_unique<unsigned char[]>(values[i].size());
189       std::copy(values[i].begin(), values[i].end(), new_value.get());
190       values_.push_back(std::move(new_value));
191       values_size_.push_back(values[i].size());
192       uvalues_size_.push_back(values[i].size());
193     }
194   } catch (const std::bad_alloc& e) {
195     return BUNDLE_ERROR_OUT_OF_MEMORY;
196   }
197
198   return BUNDLE_ERROR_NONE;
199 }
200
201 std::vector<unsigned char> KeyInfo::Encode() {
202   std::size_t encoded_size = GetEncodedSize();
203   if (encoded_size == 0)
204     return {};
205
206   std::vector<unsigned char> bytes;
207
208   // total size
209   unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
210   bytes.insert(bytes.end(), p, p + sizeof(encoded_size));
211
212   // type
213   p = reinterpret_cast<unsigned char*>(&type_);
214   bytes.insert(bytes.end(), p, p + sizeof(type_));
215
216   // key size
217   std::size_t key_length = key_.length() + 1;
218   p = reinterpret_cast<unsigned char*>(&key_length);
219   bytes.insert(bytes.end(), p, p + sizeof(key_length));
220
221   // key
222   bytes.insert(bytes.end(), key_.begin(), key_.end() + 1);
223
224   if (type_ & BUNDLE_TYPE_ARRAY) {
225     // values size
226     std::size_t values_size = values_.size();
227     p = reinterpret_cast<unsigned char*>(&values_size);
228     bytes.insert(bytes.end(), p, p + sizeof(values_size));
229   }
230
231   // values
232   for (unsigned int i = 0; i < values_.size(); i++) {
233     std::size_t value_size = values_size_[i];
234     p = reinterpret_cast<unsigned char*>(&value_size);
235     bytes.insert(bytes.end(), p, p + sizeof(value_size));
236
237     bytes.insert(bytes.end(), values_[i].get(), values_[i].get() + value_size);
238   }
239
240   return bytes;
241 }
242
243 std::size_t KeyInfo::GetEncodedSize() {
244   // total size
245   std::size_t encoded_size = sizeof(std::size_t);
246
247   // type
248   encoded_size += sizeof(int);
249
250   // key size
251   encoded_size += sizeof(std::size_t);
252
253   // key
254   if ((encoded_size + key_.length() + 1) < encoded_size)
255     return 0;
256
257   encoded_size += key_.length() + 1;
258
259   if (type_ & BUNDLE_TYPE_ARRAY) {
260     // values size
261     if ((encoded_size + sizeof(std::size_t)) < encoded_size)
262       return 0;
263
264     encoded_size += sizeof(std::size_t);
265   }
266
267   // values
268   std::size_t values_size = 0;
269   for (unsigned int i = 0; i < values_.size(); ++i) {
270     // value size
271     if ((values_size + sizeof(std::size_t)) < values_size)
272       return 0;
273
274     values_size += sizeof(std::size_t);
275
276     // value
277     if ((values_size + values_size_[i]) < values_size)
278       return 0;
279
280     values_size += values_size_[i];
281   }
282
283   if ((encoded_size + values_size) < encoded_size)
284     return 0;
285
286   encoded_size += values_size;
287
288   return encoded_size;
289 }
290
291 int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
292   unsigned int reader = 0;
293
294   // total size
295   std::size_t total_size = 0;
296   if ((reader + sizeof(total_size)) > bytes.size())
297     return BUNDLE_ERROR_INVALID_PARAMETER;
298
299   unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
300   std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
301   reader += sizeof(total_size);
302
303   // type
304   if ((reader + sizeof(type_)) > bytes.size())
305     return BUNDLE_ERROR_INVALID_PARAMETER;
306
307   p = reinterpret_cast<unsigned char*>(&type_);
308   std::copy(&bytes[reader], &bytes[reader] + sizeof(type_), p);
309   reader += sizeof(type_);
310
311   // key size
312   std::size_t key_size = 0;
313
314   if ((reader + sizeof(key_size)) > bytes.size())
315     return BUNDLE_ERROR_INVALID_PARAMETER;
316
317   p = reinterpret_cast<unsigned char*>(&key_size);
318   std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
319   reader += sizeof(key_size);
320
321   if ((reader + key_size) > bytes.size())
322     return BUNDLE_ERROR_INVALID_PARAMETER;
323
324   // key
325   std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
326   p = reinterpret_cast<unsigned char*>(&key[0]);
327   key_ = std::string(reinterpret_cast<char*>(p));
328   reader += key_size;
329
330   std::size_t values_size = 0;
331   if (type_ & BUNDLE_TYPE_ARRAY) {
332     // values size
333     if ((reader + sizeof(values_size)) > bytes.size())
334       return BUNDLE_ERROR_INVALID_PARAMETER;
335
336     p = reinterpret_cast<unsigned char*>(&values_size);
337     std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
338     reader += sizeof(values_size);
339   } else {
340     values_size = 1;
341   }
342
343   // values
344   for (std::size_t i = 0; i < values_size; ++i) {
345     // value_size
346     std::size_t value_size = 0;
347     if ((reader + sizeof(value_size)) > bytes.size())
348       return BUNDLE_ERROR_INVALID_PARAMETER;
349
350     p = reinterpret_cast<unsigned char*>(&value_size);
351     std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
352     reader += sizeof(value_size);
353
354     // value
355     if ((reader + value_size) > bytes.size())
356       return BUNDLE_ERROR_INVALID_PARAMETER;
357
358     try {
359       auto new_value = std::make_unique<unsigned char[]>(value_size);
360       std::copy(&bytes[reader], &bytes[reader] + value_size, new_value.get());
361       reader += value_size;
362       values_.push_back(std::move(new_value));
363     } catch (const std::bad_alloc& e) {
364       return BUNDLE_ERROR_OUT_OF_MEMORY;
365     }
366     values_size_.push_back(value_size);
367     uvalues_size_.push_back(static_cast<unsigned int>(value_size));
368   }
369
370   return BUNDLE_ERROR_NONE;
371 }
372
373 int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
374   if (index > GetSize() || index < 0)
375     return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
376
377   if (!IsArray())
378     return BUNDLE_ERROR_INVALID_PARAMETER;
379
380   try {
381     auto new_value = std::make_unique<unsigned char[]>(value.size());
382     if (value.size() != 0)
383       std::copy(value.begin(), value.end(), new_value.get());
384
385     values_[index] = std::move(new_value);
386   } catch (const std::bad_alloc& e) {
387     return BUNDLE_ERROR_OUT_OF_MEMORY;
388   }
389
390   values_size_[index] = value.size();
391   uvalues_size_[index] = static_cast<unsigned int>(value.size());
392   return BUNDLE_ERROR_NONE;
393 }
394
395 int KeyInfo::GetSize() const {
396   return values_.size();
397 }
398
399 }  // namespace internal
400 }  // namespace tizen_base