Fix function implementation for backward compatibility 25/237425/6
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 30 Jun 2020 10:24:29 +0000 (19:24 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 1 Jul 2020 04:10:24 +0000 (13:10 +0900)
Change-Id: I9c1bd9f28336337f716cce41faaa9e2313c96f06
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/bundle-internal.cc
src/bundle-internal.h
src/json-internal.cc
src/key-info-internal.cc
src/key-info-internal.h
src/stub.cc

index 12fea42..9c7b2ee 100644 (file)
@@ -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<KeyInfo> 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<KeyInfo>& Bundle::Get(const std::string& key) {
@@ -133,8 +143,7 @@ int Bundle::GetType(const std::string& key) {
 
 unsigned char* Bundle::Encode() {
   std::vector<unsigned char> 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<KeyInfo>(
-        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<KeyInfo>(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<std::string, std::shared_ptr<KeyInfo>>& Bundle::GetMap() {
 
 std::vector<std::string> Bundle::Export() {
   std::vector<std::string> 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<unsigned char> value;
       std::copy(p, p + len, std::back_inserter(value));
-      auto key_info = std::shared_ptr<KeyInfo>(
-          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<KeyInfo>(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<unsigned char*>(bytes);
     std::vector<unsigned char> decoded_bytes(p, p + (out_len + 1));
-    auto key_info = std::shared_ptr<KeyInfo>(
-        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<KeyInfo>(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;
index c73e5e2..c79fed4 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef BUNDLE_INTERNAL_H_
 #define BUNDLE_INTERNAL_H_
 
+#include <list>
 #include <map>
 #include <memory>
 #include <string>
@@ -78,6 +79,7 @@ class Bundle {
 
  private:
   std::map<std::string, std::shared_ptr<KeyInfo>> map_;
+  std::list<std::shared_ptr<KeyInfo>> list_;
 };
 
 }  // namespace internal
index bb63639..770a214 100644 (file)
@@ -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<Bundle*>(user_data);
-  std::shared_ptr<KeyInfo> 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<unsigned char*>(const_cast<char*>(val));
     std::vector<unsigned char> 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<KeyInfo>(key_info));
   } catch (Exception& e) {
     _W("Add() is failed. error(%d)", e.GetErrorCode());
     return;
index b415584..eb0b559 100644 (file)
 
 #include <cstring>
 
+#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<unsigned char> 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<std::vector<unsigned char>> values)
   : type_(type),
     key_(std::move(key)) {
-  SetValues(values);
+  int ret = SetValues(values);
+  if (ret != BUNDLE_ERROR_NONE)
+    THROW(ret);
 }
 
 KeyInfo::KeyInfo(std::vector<unsigned char> 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<unsigned int>& KeyInfo::GetUValuesSize() {
   return uvalues_size_;
 }
 
-void KeyInfo::SetValue(const std::vector<unsigned char>& value) {
+int KeyInfo::SetValue(const std::vector<unsigned char>& 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<unsigned int>(value.size()));
+  return BUNDLE_ERROR_NONE;
 }
 
-void KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
+int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& 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<unsigned char> KeyInfo::Encode() {
@@ -186,10 +208,12 @@ std::vector<unsigned char> 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<unsigned char*>(&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<unsigned char*>(&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<unsigned char>& bytes) {
+int KeyInfo::Decode(const std::vector<unsigned char>& 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<unsigned char*>(&total_size);
   std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
@@ -264,7 +290,7 @@ void KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
 
   // type
   if ((reader + sizeof(type_)) > bytes.size())
-      return;
+    return BUNDLE_ERROR_INVALID_PARAMETER;
 
   p = reinterpret_cast<unsigned char*>(&type_);
   std::copy(&bytes[reader], &bytes[reader] + sizeof(type_),  p);
@@ -274,14 +300,14 @@ void KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
   std::size_t key_size = 0;
 
   if ((reader + sizeof(key_size)) > bytes.size())
-    return;
+    return BUNDLE_ERROR_INVALID_PARAMETER;
 
   p = reinterpret_cast<unsigned char*>(&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<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
@@ -289,21 +315,25 @@ void KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
   key_ = std::string(reinterpret_cast<char*>(p));
   reader += key_size;
 
-  // values size
   std::size_t values_size = 0;
-  if ((reader + sizeof(values_size)) > bytes.size())
-    return;
-
-  p = reinterpret_cast<unsigned char*>(&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<unsigned char*>(&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<unsigned char*>(&value_size);
     std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
@@ -311,9 +341,12 @@ void KeyInfo::Decode(const std::vector<unsigned char>& 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<unsigned char>& bytes) {
     values_size_.push_back(value_size);
     uvalues_size_.push_back(static_cast<unsigned int>(value_size));
   }
+
+  return BUNDLE_ERROR_NONE;
 }
 
-void KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
+int KeyInfo::SetValue(int index, const std::vector<unsigned char>& 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<unsigned int>(value.size());
+  return BUNDLE_ERROR_NONE;
 }
 
 int KeyInfo::GetSize() const {
index 3404773..9fa1e24 100644 (file)
@@ -48,15 +48,15 @@ class KeyInfo {
   const std::vector<unsigned int>& GetUValuesSize();
   std::vector<unsigned char> Encode();
 
-  void SetValue(int index, const std::vector<unsigned char>& value);
+  int SetValue(int index, const std::vector<unsigned char>& value);
   int GetSize() const;
 
  private:
   std::size_t GetEncodedSize();
-  void SetValuesSize();
-  void SetValue(const std::vector<unsigned char>& value);
-  void SetValues(const std::vector<std::vector<unsigned char>>& values);
-  void Decode(const std::vector<unsigned char>& bytes);
+  int SetValuesSize();
+  int SetValue(const std::vector<unsigned char>& value);
+  int SetValues(const std::vector<std::vector<unsigned char>>& values);
+  int Decode(const std::vector<unsigned char>& bytes);
 
  private:
   int type_;
index a0f88d3..3efcf95 100644 (file)
@@ -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<Bundle*>(b);
   std::vector<unsigned char> value(str, str + (strlen(str) + 1));
-  std::shared_ptr<KeyInfo> 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<KeyInfo>(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<Bundle*>(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<std::unique_ptr<unsigned char[]>&>(values[0]);
-  *str = reinterpret_cast<char*>(&value[0]);
+  if (str) {
+    auto& values = key_info->GetValues();
+    auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
+    *str = reinterpret_cast<char*>(&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<Bundle*>(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<KeyInfo*>(kv);
-  auto& values = key_info->GetValues();
-  auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
-  *val = reinterpret_cast<void*>(&value[0]);
-  auto& values_size = key_info->GetValuesSize();
-  *size = reinterpret_cast<size_t>(values_size[0]);
+  if (key_info->IsArray())
+    return BUNDLE_ERROR_INVALID_PARAMETER;
+
+  if (val) {
+    auto& values = key_info->GetValues();
+    auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
+    *val = reinterpret_cast<void*>(&value[0]);
+  }
+
+  if (size) {
+    auto& values_size = key_info->GetValuesSize();
+    *size = reinterpret_cast<size_t>(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<KeyInfo*>(kv);
+  if (!key_info->IsArray())
+    return BUNDLE_ERROR_INVALID_PARAMETER;
+
   auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
       key_info->GetValues());
-  auto& values_size = const_cast<std::vector<std::size_t>&>(
+
+  if (array_val)
+    *array_val = reinterpret_cast<void**>(&values[0]);
+
+  if (array_len)
+    *array_len = static_cast<unsigned int>(values.size());
+
+  if (array_item_size) {
+    auto& values_size = const_cast<std::vector<std::size_t>&>(
       key_info->GetValuesSize());
-  *array_val = reinterpret_cast<void**>(&values[0]);
-  *array_len = static_cast<unsigned int>(values.size());
-  *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
+    *array_item_size = reinterpret_cast<size_t*>(&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<bundle_keyval_t*>(kv);
   auto* key_info = reinterpret_cast<KeyInfo*>(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<bundle_raw*>(r);
-    b = new (std::nothrow) Bundle(static_cast<unsigned char*>(raw), data_size);
+    b = new Bundle(static_cast<unsigned char*>(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<Bundle*>(b);
@@ -357,14 +392,16 @@ extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
     }
   }
 
-  std::shared_ptr<KeyInfo> 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<KeyInfo>(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<std::vector<std::unique_ptr<unsigned char[]>>&>(
       key_info->GetValues());
-  auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
-  *len = static_cast<int>(raw_values.size());
 
-  set_last_result(BUNDLE_ERROR_NONE);
+  if (len)
+    *len = static_cast<int>(raw_values.size());
+
+  if (raw_values.size() == 0)
+    return nullptr;
+
+  auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
   return const_cast<const char**>(reinterpret_cast<char**>(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<Bundle*>(b);
   auto* p = reinterpret_cast<const unsigned char*>(bytes);
-  std::vector<unsigned char> value(p, p + size);
+  std::vector<unsigned char> value;
+  if (bytes)
+    std::copy(p, p + size, std::back_inserter(value));
 
-  std::shared_ptr<KeyInfo> 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<KeyInfo>(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<Bundle*>(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<std::vector<std::unique_ptr<unsigned char[]>>&>(
-      key_info->GetValues());
-  auto& value = values[0];
-  *bytes = reinterpret_cast<void*>(&value[0]);
-  auto& values_size = key_info->GetValuesSize();
-  *size = reinterpret_cast<size_t>(values_size[0]);
+  if (bytes) {
+    auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
+        key_info->GetValues());
+    if (values.size() == 0) {
+      *bytes = nullptr;
+    } else {
+      auto& value = values[0];
+      *bytes = reinterpret_cast<void*>(&value[0]);
+    }
+  }
+
+  if (size) {
+    auto& values_size = key_info->GetValuesSize();
+    *size = reinterpret_cast<size_t>(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<Bundle*>(b);
-  std::vector<std::vector<unsigned char>> values(len);
-  auto key_info = std::shared_ptr<KeyInfo>(
-      new (std::nothrow) KeyInfo(Bundle::Type::ByteArray, key, values));
-  if (key_info.get() == nullptr)
+
+  KeyInfo* key_info;
+  try {
+    std::vector<std::vector<unsigned char>> 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<KeyInfo>(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<Bundle*>(b);
@@ -604,13 +666,20 @@ extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
 
   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
       key_info->GetValues());
-  auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
-  *bytes_array = reinterpret_cast<void**>(values);
-  *len = static_cast<unsigned int>(raw_values.size());
 
-  auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
-      key_info->GetUValuesSize());
-  *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
+  if (bytes_array) {
+    auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
+    *bytes_array = reinterpret_cast<void**>(values);
+  }
+
+  if (len)
+    *len = static_cast<unsigned int>(raw_values.size());
+
+  if (array_element_size) {
+    auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
+        key_info->GetUValuesSize());
+    *array_element_size = reinterpret_cast<unsigned int*>(&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<unsigned char*>(const_cast<void*>(bytes));
-  std::vector<unsigned char> value(p, p + size);
+  std::vector<unsigned char> value;
+  if (bytes) {
+    auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
+    std::copy(p, p + size, std::back_inserter(value));
+  }
 
   auto* h = reinterpret_cast<Bundle*>(b);
   try {