From f665c6a17dd3a2aa2d7f6a50f3bf6d7dfd4fdaf6 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 30 Jun 2020 19:24:29 +0900 Subject: [PATCH] Fix function implementation for backward compatibility Change-Id: I9c1bd9f28336337f716cce41faaa9e2313c96f06 Signed-off-by: Hwankyu Jhun --- src/bundle-internal.cc | 60 ++++++++++---- src/bundle-internal.h | 2 + src/json-internal.cc | 31 ++++--- src/key-info-internal.cc | 112 ++++++++++++++++++-------- src/key-info-internal.h | 10 +-- src/stub.cc | 204 ++++++++++++++++++++++++++++++++--------------- 6 files changed, 288 insertions(+), 131 deletions(-) diff --git a/src/bundle-internal.cc b/src/bundle-internal.cc index 12fea42..9c7b2ee 100644 --- a/src/bundle-internal.cc +++ b/src/bundle-internal.cc @@ -47,21 +47,27 @@ Bundle::~Bundle() = default; Bundle::Bundle(const Bundle& b) { map_ = b.map_; + list_ = b.list_; } Bundle& Bundle::operator = (const Bundle& b) { - if (this != &b) + if (this != &b) { map_ = b.map_; + list_ = b.list_; + } return *this; } Bundle::Bundle(Bundle&& b) noexcept { map_ = std::move(b.map_); + list_ = std::move(b.list_); } Bundle& Bundle::operator = (Bundle&& b) noexcept { - if (this != &b) + if (this != &b) { map_ = std::move(b.map_); + list_ = std::move(b.list_); + } return *this; } @@ -91,6 +97,7 @@ void Bundle::Remove(const std::string& key) { if (iter == map_.end()) THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE); + list_.remove(iter->second); map_.erase(iter); } @@ -100,6 +107,7 @@ void Bundle::Add(std::shared_ptr key_info) { THROW(BUNDLE_ERROR_KEY_EXISTS); map_[key_info->GetKey()] = key_info; + list_.push_back(key_info); } void Bundle::Set(const std::string& key, int index, @@ -108,7 +116,9 @@ void Bundle::Set(const std::string& key, int index, if (iter == map_.end()) THROW(BUNDLE_ERROR_KEY_NOT_AVAILABLE); - iter->second->SetValue(index, value); + int ret = iter->second->SetValue(index, value); + if (ret != BUNDLE_ERROR_NONE) + THROW(ret); } std::shared_ptr& Bundle::Get(const std::string& key) { @@ -133,8 +143,7 @@ int Bundle::GetType(const std::string& key) { unsigned char* Bundle::Encode() { std::vector bytes; - for (const auto& i : map_) { - auto& key_info = i.second; + for (const auto& key_info : list_) { auto encoded_bytes = key_info->Encode(); bytes.insert(bytes.end(), encoded_bytes.begin(), encoded_bytes.end()); } @@ -208,16 +217,22 @@ int Bundle::Decode(unsigned char* raw, int size) { std::back_inserter(encoded_bytes)); reader += total_size; - auto key_info = std::shared_ptr( - new (std::nothrow) KeyInfo(encoded_bytes)); - if (key_info.get() == nullptr) + KeyInfo* new_key_info; + try { + new_key_info = new KeyInfo(encoded_bytes); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } + auto key_info = std::shared_ptr(new_key_info); auto iter = map_.find(key_info->GetKey()); if (iter != map_.end()) continue; map_[key_info->GetKey()] = key_info; + list_.push_back(key_info); } return BUNDLE_ERROR_NONE; @@ -229,8 +244,7 @@ const std::map>& Bundle::GetMap() { std::vector Bundle::Export() { std::vector argv(2); - for (const auto& kv : map_) { - auto& key_info = kv.second; + for (const auto& key_info : list_) { argv.push_back(key_info->GetKey()); auto encoded_bytes = key_info->Encode(); @@ -257,16 +271,23 @@ int Bundle::Import(int argc, char** argv) { auto len = strlen(argv[idx + 1]) + 1; std::vector value; std::copy(p, p + len, std::back_inserter(value)); - auto key_info = std::shared_ptr( - new (std::nothrow) KeyInfo(Type::String, argv[idx], value)); - if (key_info.get() == nullptr) + + KeyInfo* new_key_info; + try { + new_key_info = new KeyInfo(Type::String, argv[idx], value); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } + auto key_info = std::shared_ptr(new_key_info); auto iter = map_.find(key_info->GetKey()); if (iter != map_.end()) continue; map_[key_info->GetKey()] = key_info; + list_.push_back(key_info); } return BUNDLE_ERROR_NONE; } @@ -284,16 +305,23 @@ int Bundle::Import(int argc, char** argv) { auto* p = reinterpret_cast(bytes); std::vector decoded_bytes(p, p + (out_len + 1)); - auto key_info = std::shared_ptr( - new (std::nothrow) KeyInfo(decoded_bytes)); - if (key_info.get() == nullptr) + + KeyInfo* new_key_info; + try { + new_key_info = new KeyInfo(decoded_bytes); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } + auto key_info = std::shared_ptr(new_key_info); auto iter = map_.find(key_info->GetKey()); if (iter != map_.end()) continue; map_[key_info->GetKey()] = key_info; + list_.push_back(key_info); } return BUNDLE_ERROR_NONE; diff --git a/src/bundle-internal.h b/src/bundle-internal.h index c73e5e2..c79fed4 100644 --- a/src/bundle-internal.h +++ b/src/bundle-internal.h @@ -17,6 +17,7 @@ #ifndef BUNDLE_INTERNAL_H_ #define BUNDLE_INTERNAL_H_ +#include #include #include #include @@ -78,6 +79,7 @@ class Bundle { private: std::map> map_; + std::list> list_; }; } // namespace internal diff --git a/src/json-internal.cc b/src/json-internal.cc index bb63639..770a214 100644 --- a/src/json-internal.cc +++ b/src/json-internal.cc @@ -125,7 +125,7 @@ std::string Json::ToString() { void Json::OnJsonObjectMember(JsonObject* object, const char* key, JsonNode* node, gpointer user_data) { auto* b = static_cast(user_data); - std::shared_ptr key_info; + KeyInfo* key_info; JsonNodeType node_type = JSON_NODE_TYPE(node); if (node_type == JSON_NODE_ARRAY) { JsonArray* json_arr = json_node_get_array(node); @@ -141,8 +141,16 @@ void Json::OnJsonObjectMember(JsonObject* object, const char* key, std::copy(p, p + (strlen(val) + 1), std::back_inserter(value)); values.push_back(value); } - key_info.reset( - new (std::nothrow) KeyInfo(Bundle::Type::StringArray, key, values)); + + try { + key_info = new KeyInfo(Bundle::Type::StringArray, key, values); + } catch (Exception& e) { + _E("Error(%d)", e.GetErrorCode()); + return; + } catch (const std::bad_alloc& ba) { + _E("bad alloc exception"); + return; + } } else { auto* val = json_node_get_string(node); if (val == nullptr) @@ -150,17 +158,20 @@ void Json::OnJsonObjectMember(JsonObject* object, const char* key, auto* p = reinterpret_cast(const_cast(val)); std::vector value; std::copy(p, p + (strlen(val) + 1), std::back_inserter(value)); - key_info.reset( - new (std::nothrow) KeyInfo(Bundle::Type::String, key, value)); - } - if (key_info.get() == nullptr) { - _E("Out of memory"); - return; + try { + key_info = new KeyInfo(Bundle::Type::String, key, value); + } catch (Exception& e) { + _E("Error(%d)", e.GetErrorCode()); + return; + } catch (const std::bad_alloc& ba) { + _E("bad alloc exception"); + return; + } } try { - b->Add(key_info); + b->Add(std::shared_ptr(key_info)); } catch (Exception& e) { _W("Add() is failed. error(%d)", e.GetErrorCode()); return; diff --git a/src/key-info-internal.cc b/src/key-info-internal.cc index b415584..eb0b559 100644 --- a/src/key-info-internal.cc +++ b/src/key-info-internal.cc @@ -16,8 +16,10 @@ #include +#include "include/bundle.h" + +#include "exception-internal.h" #include "key-info-internal.h" -#include "log-private.h" namespace tizen_base { namespace internal { @@ -26,18 +28,24 @@ KeyInfo::KeyInfo(int type, std::string key, std::vector value) : type_(type), key_(std::move(key)) { - SetValue(value); + int ret = SetValue(value); + if (ret != BUNDLE_ERROR_NONE) + THROW(ret); } KeyInfo::KeyInfo(int type, std::string key, std::vector> values) : type_(type), key_(std::move(key)) { - SetValues(values); + int ret = SetValues(values); + if (ret != BUNDLE_ERROR_NONE) + THROW(ret); } KeyInfo::KeyInfo(std::vector encoded_bytes) { - Decode(encoded_bytes); + int ret = Decode(encoded_bytes); + if (ret != BUNDLE_ERROR_NONE) + THROW(ret); } KeyInfo::~KeyInfo() = default; @@ -49,6 +57,9 @@ KeyInfo::KeyInfo(const KeyInfo& key_info) { uvalues_size_ = key_info.uvalues_size_; for (unsigned int i = 0; i < key_info.values_.size(); ++i) { auto* new_value = new (std::nothrow) unsigned char[values_size_[i]]; + if (new_value == nullptr) + THROW(BUNDLE_ERROR_OUT_OF_MEMORY); + std::copy(key_info.values_[i].get(), key_info.values_[i].get() + values_size_[i], new_value); values_.emplace_back(new_value); @@ -63,6 +74,9 @@ KeyInfo& KeyInfo::operator = (const KeyInfo& key_info) { uvalues_size_ = key_info.uvalues_size_; for (unsigned int i = 0; i < key_info.values_.size(); ++i) { auto* new_value = new (std::nothrow) unsigned char[values_size_[i]]; + if (new_value == nullptr) + THROW(BUNDLE_ERROR_OUT_OF_MEMORY); + std::copy(key_info.values_[i].get(), key_info.values_[i].get() + values_size_[i], new_value); values_.emplace_back(new_value); @@ -123,7 +137,7 @@ int KeyInfo::GetType() const { } bool KeyInfo::IsArray() const { - if (values_.size() == 1) + if (type_ & BUNDLE_TYPE_ARRAY) return true; return false; @@ -145,22 +159,30 @@ const std::vector& KeyInfo::GetUValuesSize() { return uvalues_size_; } -void KeyInfo::SetValue(const std::vector& value) { +int KeyInfo::SetValue(const std::vector& value) { auto* new_value = new (std::nothrow) unsigned char[value.size()]; + if (new_value == nullptr) + return BUNDLE_ERROR_OUT_OF_MEMORY; + std::copy(value.begin(), value.end(), new_value); values_.emplace_back(new_value); values_size_.push_back(value.size()); uvalues_size_.push_back(static_cast(value.size())); + return BUNDLE_ERROR_NONE; } -void KeyInfo::SetValues(const std::vector>& values) { +int KeyInfo::SetValues(const std::vector>& values) { for (unsigned int i = 0; i< values.size(); ++i) { auto* new_value = new (std::nothrow) unsigned char[values[i].size()]; + if (new_value == nullptr) + return BUNDLE_ERROR_OUT_OF_MEMORY; + std::copy(values[i].begin(), values[i].end(), new_value); values_.emplace_back(new_value); values_size_.push_back(values[i].size()); uvalues_size_.push_back(values[i].size()); } + return BUNDLE_ERROR_NONE; } std::vector KeyInfo::Encode() { @@ -186,10 +208,12 @@ std::vector KeyInfo::Encode() { // key std::copy(key_.begin(), key_.end() + 1, std::back_inserter(bytes)); - // values size - std::size_t values_size = values_.size(); - p = reinterpret_cast(&values_size); - std::copy(p , p + sizeof(values_size), std::back_inserter(bytes)); + if (type_ & BUNDLE_TYPE_ARRAY) { + // values size + std::size_t values_size = values_.size(); + p = reinterpret_cast(&values_size); + std::copy(p , p + sizeof(values_size), std::back_inserter(bytes)); + } // values for (unsigned int i = 0; i < values_.size(); i++) { @@ -220,11 +244,13 @@ std::size_t KeyInfo::GetEncodedSize() { encoded_size += key_.length() + 1; - // values size - if ((encoded_size + sizeof(std::size_t)) < encoded_size) - return 0; + if (type_ & BUNDLE_TYPE_ARRAY) { + // values size + if ((encoded_size + sizeof(std::size_t)) < encoded_size) + return 0; - encoded_size += sizeof(std::size_t); + encoded_size += sizeof(std::size_t); + } // values std::size_t values_size = 0; @@ -250,13 +276,13 @@ std::size_t KeyInfo::GetEncodedSize() { return encoded_size; } -void KeyInfo::Decode(const std::vector& bytes) { +int KeyInfo::Decode(const std::vector& bytes) { unsigned int reader = 0; // total size std::size_t total_size = 0; if ((reader + sizeof(total_size)) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; unsigned char* p = reinterpret_cast(&total_size); std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p); @@ -264,7 +290,7 @@ void KeyInfo::Decode(const std::vector& bytes) { // type if ((reader + sizeof(type_)) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; p = reinterpret_cast(&type_); std::copy(&bytes[reader], &bytes[reader] + sizeof(type_), p); @@ -274,14 +300,14 @@ void KeyInfo::Decode(const std::vector& bytes) { std::size_t key_size = 0; if ((reader + sizeof(key_size)) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; p = reinterpret_cast(&key_size); std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p); reader += sizeof(key_size); if ((reader + key_size) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; // key std::vector key(&bytes[reader], &bytes[reader] + key_size); @@ -289,21 +315,25 @@ void KeyInfo::Decode(const std::vector& bytes) { key_ = std::string(reinterpret_cast(p)); reader += key_size; - // values size std::size_t values_size = 0; - if ((reader + sizeof(values_size)) > bytes.size()) - return; - - p = reinterpret_cast(&values_size); - std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p); - reader += sizeof(values_size); + if (type_ & BUNDLE_TYPE_ARRAY) { + // values size + if ((reader + sizeof(values_size)) > bytes.size()) + return BUNDLE_ERROR_INVALID_PARAMETER; + + p = reinterpret_cast(&values_size); + std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p); + reader += sizeof(values_size); + } else { + values_size = 1; + } // values for (std::size_t i = 0; i < values_size; ++i) { // value_size std::size_t value_size = 0; if ((reader + sizeof(value_size)) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; p = reinterpret_cast(&value_size); std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p); @@ -311,9 +341,12 @@ void KeyInfo::Decode(const std::vector& bytes) { // value if ((reader + value_size) > bytes.size()) - return; + return BUNDLE_ERROR_INVALID_PARAMETER; + + auto* new_value = new (std::nothrow) unsigned char[value_size]; + if (new_value == nullptr) + return BUNDLE_ERROR_OUT_OF_MEMORY; - auto* new_value = new unsigned char[value_size]; std::copy(&bytes[reader], &bytes[reader] + value_size, new_value); reader += value_size; @@ -321,17 +354,28 @@ void KeyInfo::Decode(const std::vector& bytes) { values_size_.push_back(value_size); uvalues_size_.push_back(static_cast(value_size)); } + + return BUNDLE_ERROR_NONE; } -void KeyInfo::SetValue(int index, const std::vector& value) { +int KeyInfo::SetValue(int index, const std::vector& value) { if (index > GetSize() && index < 0) - return; + return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS; + + if (!IsArray()) + return BUNDLE_ERROR_INVALID_PARAMETER; + + auto* new_value = new (std::nothrow) unsigned char[value.size()]; + if (new_value == nullptr) + return BUNDLE_ERROR_OUT_OF_MEMORY; + + if (value.size() != 0) + std::copy(value.begin(), value.end(), new_value); - auto* new_value = new unsigned char[value.size()]; - std::copy(value.begin(), value.end(), new_value); values_[index].reset(new_value); values_size_[index] = value.size(); uvalues_size_[index] = static_cast(value.size()); + return BUNDLE_ERROR_NONE; } int KeyInfo::GetSize() const { diff --git a/src/key-info-internal.h b/src/key-info-internal.h index 3404773..9fa1e24 100644 --- a/src/key-info-internal.h +++ b/src/key-info-internal.h @@ -48,15 +48,15 @@ class KeyInfo { const std::vector& GetUValuesSize(); std::vector Encode(); - void SetValue(int index, const std::vector& value); + int SetValue(int index, const std::vector& value); int GetSize() const; private: std::size_t GetEncodedSize(); - void SetValuesSize(); - void SetValue(const std::vector& value); - void SetValues(const std::vector>& values); - void Decode(const std::vector& bytes); + int SetValuesSize(); + int SetValue(const std::vector& value); + int SetValues(const std::vector>& values); + int Decode(const std::vector& bytes); private: int type_; diff --git a/src/stub.cc b/src/stub.cc index a0f88d3..3efcf95 100644 --- a/src/stub.cc +++ b/src/stub.cc @@ -49,18 +49,23 @@ extern "C" EXPORT_API int bundle_free(bundle* b) { extern "C" EXPORT_API int bundle_add_str(bundle* b, const char* key, const char* str) { - if (b == nullptr || key == nullptr || str == nullptr) + if (b == nullptr || key == nullptr || strlen(key) == 0 || str == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); std::vector value(str, str + (strlen(str) + 1)); - std::shared_ptr key_info( - new (std::nothrow) KeyInfo(BUNDLE_TYPE_STR, key, value)); - if (key_info.get() == nullptr) + + KeyInfo* key_info; + try { + key_info = new KeyInfo(BUNDLE_TYPE_STR, key, value); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } try { - h->Add(key_info); + h->Add(std::shared_ptr(key_info)); } catch (Exception& e) { return e.GetErrorCode(); } @@ -70,7 +75,7 @@ extern "C" EXPORT_API int bundle_add_str(bundle* b, extern "C" EXPORT_API int bundle_get_str(bundle* b, const char* key, char** str) { - if (b == nullptr || key == nullptr || str == nullptr) + if (b == nullptr || key == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); @@ -84,9 +89,11 @@ extern "C" EXPORT_API int bundle_get_str(bundle* b, if (key_info->GetType() != BUNDLE_TYPE_STR) return BUNDLE_ERROR_INVALID_PARAMETER; - auto& values = key_info->GetValues(); - auto& value = const_cast&>(values[0]); - *str = reinterpret_cast(&value[0]); + if (str) { + auto& values = key_info->GetValues(); + auto& value = const_cast&>(values[0]); + *str = reinterpret_cast(&value[0]); + } return BUNDLE_ERROR_NONE; } @@ -97,7 +104,7 @@ extern "C" EXPORT_API int bundle_add(bundle* b, const char* key, } extern "C" EXPORT_API int bundle_del(bundle* b, const char* key) { - if (b == nullptr || key == nullptr) + if (b == nullptr || key == nullptr || strlen(key) == 0) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); @@ -200,32 +207,51 @@ extern "C" EXPORT_API int bundle_keyval_type_is_measurable( extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv, void** val, size_t* size) { - if (kv == nullptr || val == nullptr || size == nullptr) + if (kv == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* key_info = reinterpret_cast(kv); - auto& values = key_info->GetValues(); - auto& value = const_cast&>(values[0]); - *val = reinterpret_cast(&value[0]); - auto& values_size = key_info->GetValuesSize(); - *size = reinterpret_cast(values_size[0]); + if (key_info->IsArray()) + return BUNDLE_ERROR_INVALID_PARAMETER; + + if (val) { + auto& values = key_info->GetValues(); + auto& value = const_cast&>(values[0]); + *val = reinterpret_cast(&value[0]); + } + + if (size) { + auto& values_size = key_info->GetValuesSize(); + *size = reinterpret_cast(values_size[0]); + } + return BUNDLE_ERROR_NONE; } extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv, void*** array_val, unsigned int* array_len, size_t** array_item_size) { - if (kv == nullptr || array_val == nullptr || array_len == nullptr || - array_item_size == nullptr) + if (kv == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* key_info = reinterpret_cast(kv); + if (!key_info->IsArray()) + return BUNDLE_ERROR_INVALID_PARAMETER; + auto& values = const_cast>&>( key_info->GetValues()); - auto& values_size = const_cast&>( + + if (array_val) + *array_val = reinterpret_cast(&values[0]); + + if (array_len) + *array_len = static_cast(values.size()); + + if (array_item_size) { + auto& values_size = const_cast&>( key_info->GetValuesSize()); - *array_val = reinterpret_cast(&values[0]); - *array_len = static_cast(values.size()); - *array_item_size = reinterpret_cast(&values_size[0]); + *array_item_size = reinterpret_cast(&values_size[0]); + } + return BUNDLE_ERROR_NONE; } @@ -238,8 +264,14 @@ extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup( auto* keyval = const_cast(kv); auto* key_info = reinterpret_cast(keyval); - auto* k = new (std::nothrow) KeyInfo(*key_info); - if (k == nullptr) { + + KeyInfo* k; + try { + k = new KeyInfo(*key_info); + } catch (Exception& e) { + set_last_result(e.GetErrorCode()); + return nullptr; + } catch (const std::bad_alloc& ba) { set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY); return nullptr; } @@ -303,10 +335,13 @@ extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r, Bundle* b = nullptr; try { auto* raw = const_cast(r); - b = new (std::nothrow) Bundle(static_cast(raw), data_size); + b = new Bundle(static_cast(raw), data_size); } catch (Exception& e) { set_last_result(e.GetErrorCode()); return nullptr; + } catch (const std::bad_alloc& ba) { + set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY); + return nullptr; } set_last_result(BUNDLE_ERROR_NONE); @@ -344,7 +379,7 @@ extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) { extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key, const char** str_array, const int len) { - if (b == nullptr || key == nullptr || len <= 0) + if (b == nullptr || key == nullptr || strlen(key) == 0) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); @@ -357,14 +392,16 @@ extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key, } } - std::shared_ptr key_info( - new (std::nothrow) KeyInfo( - (BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY), key, values)); - if (key_info.get() == nullptr) - return BUNDLE_ERROR_OUT_OF_MEMORY; + KeyInfo* key_info; + try { + key_info = new KeyInfo((BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY), + key, values); + } catch (Exception& e) { + return e.GetErrorCode(); + } try { - h->Add(std::move(key_info)); + h->Add(std::shared_ptr(key_info)); } catch (Exception& e) { return e.GetErrorCode(); } @@ -374,7 +411,7 @@ extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key, extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b, const char* key, int* len) { - if (b == nullptr || key == nullptr || len == nullptr) { + if (b == nullptr || key == nullptr) { set_last_result(BUNDLE_ERROR_INVALID_PARAMETER); return nullptr; } @@ -393,31 +430,43 @@ extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b, return nullptr; } + set_last_result(BUNDLE_ERROR_NONE); + auto& raw_values = const_cast>&>( key_info->GetValues()); - auto** values = reinterpret_cast(&raw_values[0]); - *len = static_cast(raw_values.size()); - set_last_result(BUNDLE_ERROR_NONE); + if (len) + *len = static_cast(raw_values.size()); + + if (raw_values.size() == 0) + return nullptr; + + auto** values = reinterpret_cast(&raw_values[0]); return const_cast(reinterpret_cast(values)); } extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key, const void* bytes, const size_t size) { - if (b == nullptr || key == nullptr || bytes == nullptr || size == 0) + if (b == nullptr || key == nullptr || strlen(key) == 0) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); auto* p = reinterpret_cast(bytes); - std::vector value(p, p + size); + std::vector value; + if (bytes) + std::copy(p, p + size, std::back_inserter(value)); - std::shared_ptr key_info( - new (std::nothrow) KeyInfo(BUNDLE_TYPE_BYTE, key, value)); - if (key_info.get() == nullptr) + KeyInfo* key_info; + try { + key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, value); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } try { - h->Add(std::move(key_info)); + h->Add(std::shared_ptr(key_info)); } catch (Exception& e) { return e.GetErrorCode(); } @@ -427,7 +476,7 @@ extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key, extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key, void** bytes, size_t* size) { - if (b == nullptr || key == nullptr || bytes == nullptr || size == 0) + if (b == nullptr || key == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); @@ -441,12 +490,21 @@ extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key, if (key_info->GetType() != BUNDLE_TYPE_BYTE) return BUNDLE_ERROR_INVALID_PARAMETER; - auto& values = const_cast>&>( - key_info->GetValues()); - auto& value = values[0]; - *bytes = reinterpret_cast(&value[0]); - auto& values_size = key_info->GetValuesSize(); - *size = reinterpret_cast(values_size[0]); + if (bytes) { + auto& values = const_cast>&>( + key_info->GetValues()); + if (values.size() == 0) { + *bytes = nullptr; + } else { + auto& value = values[0]; + *bytes = reinterpret_cast(&value[0]); + } + } + + if (size) { + auto& values_size = key_info->GetValuesSize(); + *size = reinterpret_cast(values_size[0]); + } return BUNDLE_ERROR_NONE; } @@ -565,18 +623,23 @@ extern "C" EXPORT_API int bundle_add_byte_array(bundle* b, extern "C" EXPORT_API int bundle_init_byte_array(bundle* b, const char* key, const unsigned int len) { - if (b == nullptr || key == nullptr || len <= 0) + if (b == nullptr || key == nullptr || strlen(key) == 0) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); - std::vector> values(len); - auto key_info = std::shared_ptr( - new (std::nothrow) KeyInfo(Bundle::Type::ByteArray, key, values)); - if (key_info.get() == nullptr) + + KeyInfo* key_info; + try { + std::vector> values(len); + key_info = new KeyInfo(Bundle::Type::ByteArray, key, values); + } catch (Exception& e) { + return e.GetErrorCode(); + } catch (const std::bad_alloc& ba) { return BUNDLE_ERROR_OUT_OF_MEMORY; + } try { - h->Add(key_info); + h->Add(std::shared_ptr(key_info)); } catch (Exception& e) { return e.GetErrorCode(); } @@ -587,8 +650,7 @@ extern "C" EXPORT_API int bundle_init_byte_array(bundle* b, extern "C" EXPORT_API int bundle_get_byte_array(bundle* b, const char* key, void*** bytes_array, unsigned int* len, unsigned int** array_element_size) { - if (b == nullptr || key == nullptr || bytes_array == nullptr || - len == nullptr || array_element_size == nullptr) + if (b == nullptr || key == nullptr) return BUNDLE_ERROR_INVALID_PARAMETER; auto* h = reinterpret_cast(b); @@ -604,13 +666,20 @@ extern "C" EXPORT_API int bundle_get_byte_array(bundle* b, auto& raw_values = const_cast>&>( key_info->GetValues()); - auto** values = reinterpret_cast(&raw_values[0]); - *bytes_array = reinterpret_cast(values); - *len = static_cast(raw_values.size()); - auto& raw_values_size = const_cast&>( - key_info->GetUValuesSize()); - *array_element_size = reinterpret_cast(&raw_values_size[0]); + if (bytes_array) { + auto** values = reinterpret_cast(&raw_values[0]); + *bytes_array = reinterpret_cast(values); + } + + if (len) + *len = static_cast(raw_values.size()); + + if (array_element_size) { + auto& raw_values_size = const_cast&>( + key_info->GetUValuesSize()); + *array_element_size = reinterpret_cast(&raw_values_size[0]); + } return BUNDLE_ERROR_NONE; } @@ -618,11 +687,14 @@ extern "C" EXPORT_API int bundle_get_byte_array(bundle* b, extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b, const char* key, const unsigned int idx, const void* bytes, const size_t size) { - if (b == nullptr || key == nullptr || bytes == nullptr || size <= 0) + if (b == nullptr || key == nullptr || size <= 0) return BUNDLE_ERROR_INVALID_PARAMETER; - auto* p = reinterpret_cast(const_cast(bytes)); - std::vector value(p, p + size); + std::vector value; + if (bytes) { + auto* p = reinterpret_cast(const_cast(bytes)); + std::copy(p, p + size, std::back_inserter(value)); + } auto* h = reinterpret_cast(b); try { -- 2.7.4