[mediacontroller][common] Support for null values in Json-Bundle conversions. 78/210678/4
authorMichal Michalski <m.michalski2@partner.samsung.com>
Tue, 23 Jul 2019 15:00:26 +0000 (17:00 +0200)
committerMichal Michalski <m.michalski2@partner.samsung.com>
Tue, 30 Jul 2019 11:07:52 +0000 (13:07 +0200)
JsonToBundle and BundleToJson functions didn't support null values. Manually
handling them every time was cumbersome, hence this commit adds support for null values.

[Verification] + bundle c++ unittests 100% pass
+ bundle js tests 100% pass
+ tct-mediacontroller-tizen-tests 20190722 tct package 100% pass.

Signed-off-by: Michal Michalski <m.michalski2@partner.samsung.com>
Change-Id: I1315899d8ebb66935ea9b10791b5dba82341af45

src/common/json-utils.cc
src/common/json-utils.h
src/common/ut/bundle_ut.cc
src/mediacontroller/mediacontroller_client.cc
src/mediacontroller/mediacontroller_server.cc

index 7d12135..b58486a 100644 (file)
@@ -159,25 +159,57 @@ int BundleAdd(const std::string& key, const picojson::value& value, bundle* bund
 
 namespace common {
 
-PlatformResult JsonToBundle(const picojson::object& json, bundle* bundle_data) {
+PlatformResult JsonToBundle(const picojson::value& json, bundle** data) {
   ScopeLogger();
-  for (const auto& property : json) {
-    int ret = BundleAdd(property.first, property.second, bundle_data);
+
+  if (json.is<picojson::null>()) {
+    *data = nullptr;
+    LoggerD("bundle data is null");
+    return PlatformResult(ErrorCode::NO_ERROR);
+  }
+
+  if (!json.is<picojson::object>()) {
+    return PlatformResult(ErrorCode::UNKNOWN_ERR);
+  }
+
+  bundle* temp = bundle_create();
+  if (nullptr == temp) {
+    LoggerE("bundle_create() failed");
+    return PlatformResult(ErrorCode::UNKNOWN_ERR);
+  }
+
+  for (const auto& property : json.get<picojson::object>()) {
+    int ret = BundleAdd(property.first, property.second, *data);
     if (BUNDLE_ERROR_NONE != ret) {
       LoggerE("BundleAdd failed with error message: %s", get_error_message(ret));
+      bundle_free(temp);
       return PlatformResult(ErrorCode::UNKNOWN_ERR);
     }
   }
+
+  *data = temp;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
-PlatformResult BundleToJson(bundle* bundle_data, picojson::object* json) {
+PlatformResult BundleToJson(bundle* bundle_data, picojson::value* json) {
   ScopeLogger();
+
+  if (nullptr == json) {
+    return PlatformResult(ErrorCode::UNKNOWN_ERR);
+  }
+
+  if (nullptr == bundle_data) {
+    *json = picojson::value();
+    LoggerD("bundle data is null");
+    return PlatformResult(ErrorCode::NO_ERROR);
+  }
+
   picojson::array array_data;
   bundle_foreach(bundle_data, BundleJsonIterator, &array_data);
 
+  *json = picojson::value(picojson::object());
   for (auto& elem : array_data) {
-    (*json)[elem.get("key").get<std::string>()] = elem.get("value");
+    (json->get<picojson::object>())[elem.get("key").get<std::string>()] = elem.get("value");
   }
 
   return PlatformResult(ErrorCode::NO_ERROR);
index 4579a8c..fdd5011 100644 (file)
@@ -25,8 +25,8 @@ namespace common {
 
 void BundleJsonIterator(const char* key, const int type, const bundle_keyval_t* kv, void* d);
 
-PlatformResult JsonToBundle(const picojson::object& json, bundle* bundle_data);
-PlatformResult BundleToJson(bundle* bundle_data, picojson::object* json);
+PlatformResult JsonToBundle(const picojson::value& json, bundle** bundle_data);
+PlatformResult BundleToJson(bundle* bundle_data, picojson::value* json);
 
 }  // namespace common;
 
index 5b9c406..0155d4d 100644 (file)
@@ -156,13 +156,13 @@ MATCHER_P(KeyValBytesArrEq, expected, "match keyval_t bytes array value") {
 class JsonToBundleTest : public testing::Test {
  public:
   virtual void SetUp() {
-    bundleData = bundle_create();
-    ASSERT_NE(bundleData, nullptr);
+    bundleData = nullptr;
   }
 
   virtual void TearDown() {
-    int ret = bundle_free(bundleData);
-    ASSERT_EQ(ret, BUNDLE_ERROR_NONE);
+    if (bundleData) {
+      bundle_free(bundleData);
+    }
   }
 
   // Replacing bundle_keyval_t with void and cast it in matcher is required because
@@ -187,14 +187,17 @@ class JsonToBundleTest : public testing::Test {
 TEST_F(JsonToBundleTest, BytesArrayConversion) {
   vector<vector<unsigned char>> value = {{0, 1, 2}, {100, 101, 102}, {200, 201, 202}};
 
-  picojson::object json;
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
+
   picojson::array array;
   array.push_back(vec2json<double>(value[0]));
   array.push_back(vec2json<double>(value[1]));
   array.push_back(vec2json<double>(value[2]));
+
   json["key"] = picojson::value(array);
 
-  auto result = common::JsonToBundle(jsonbundleData);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_TRUE(result);
 
   EXPECT_CALL(bundleIteratorMock,
@@ -206,10 +209,12 @@ TEST_F(JsonToBundleTest, BytesArrayConversion) {
 TEST_F(JsonToBundleTest, BytesConversion) {
   vector<unsigned char> value = {0, 126, 255};
 
-  picojson::object json;
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
+
   json["key"] = vec2json<double>(value);
 
-  auto result = common::JsonToBundle(jsonbundleData);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_TRUE(result);
 
   EXPECT_CALL(bundleIteratorMock,
@@ -219,23 +224,27 @@ TEST_F(JsonToBundleTest, BytesConversion) {
 }
 
 TEST_F(JsonToBundleTest, BytesConversionInvalidByteValue) {
-  picojson::object json;
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
   json["key"] = vec2json<double>(vector<double>({1.0, 256.0, 2.0}));
 
-  auto result = common::JsonToBundle(jsonbundleData);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_FALSE(result);
 
   json["key"] = vec2json<double>(vector<double>({1.0, -1.0, 2.0}));
-  result = common::JsonToBundle(jsonbundleData);
+  result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_FALSE(result);
 }
 
 TEST_F(JsonToBundleTest, StringConversion) {
   string value = "tizen";
-  picojson::object json;
+
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
+
   json["key"] = picojson::value(value);
 
-  auto result = common::JsonToBundle(jsonbundleData);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_TRUE(result);
 
   EXPECT_CALL(bundleIteratorMock, Call(StrEq("key"), BUNDLE_TYPE_STR, KeyValStrEq(value), nullptr));
@@ -246,11 +255,13 @@ TEST_F(JsonToBundleTest, StringConversion) {
 TEST_F(JsonToBundleTest, StringArrayConversion) {
   vector<string> value = {"str1", "str2", "str3"};
 
-  picojson::object json;
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
+
   json["key"] = picojson::value(picojson::array(
       {picojson::value(value[0]), picojson::value(value[1]), picojson::value(value[2])}));
 
-  auto result = common::JsonToBundle(jsonbundleData);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_TRUE(result);
 
   EXPECT_CALL(bundleIteratorMock,
@@ -260,42 +271,58 @@ TEST_F(JsonToBundleTest, StringArrayConversion) {
 }
 
 TEST_F(JsonToBundleTest, UnsupportedType) {
-  picojson::object json;
-  json["key"] = picojson::value(true);
+  auto json_val = picojson::value(picojson::object());
+  auto& json = json_val.get<picojson::object>();
 
-  auto result = common::JsonToBundle(json, bundleData);
+  json["key"] = picojson::value(true);
+  auto result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_FALSE(result);
 
-  picojson::object json2;
   json["key"] = picojson::value(picojson::object());
-
-  result = common::JsonToBundle(json, bundleData);
+  result = common::JsonToBundle(json_val, &bundleData);
   ASSERT_FALSE(result);
 }
 
+TEST_F(JsonToBundleTest, NullConversion) {
+  picojson::value json_val;
+  auto result = common::JsonToBundle(json_val, &bundleData);
+  ASSERT_TRUE(result);
+  ASSERT_EQ(nullptr, bundleData);
+}
+
 class BundleToJsonTest : public testing::Test {
  public:
   virtual void SetUp() {
     bundleData = bundle_create();
-    ASSERT_NE(bundleData, nullptr);
   }
 
   virtual void TearDown() {
-    ASSERT_EQ(bundle_free(bundleData), BUNDLE_ERROR_NONE);
+    if (bundleData) {
+      bundle_free(bundleData);
+    }
   }
 
   bundle* bundleData;
 };
 
+TEST_F(BundleToJsonTest, NullConversion) {
+  bundle* data = nullptr;
+  picojson::value json;
+  auto result = common::BundleToJson(data, &json);
+  ASSERT_TRUE(result);
+  ASSERT_TRUE(json.is<picojson::null>());
+}
+
 TEST_F(BundleToJsonTest, StringConversion) {
   string key = "key", value = "tizen";
   ASSERT_EQ(bundle_add_str(bundleData, key.c_str(), value.c_str()), BUNDLE_ERROR_NONE);
 
-  picojson::object json;
+  picojson::value json;
   auto result = common::BundleToJson(bundleData, &json);
 
   ASSERT_TRUE(result);
-  ASSERT_EQ(json[key].get<string>(), value);
+  ASSERT_TRUE(json.is<picojson::object>());
+  ASSERT_EQ(json.get<picojson::object>()[key].get<string>(), value);
 }
 
 TEST_F(BundleToJsonTest, StringArrayConversion) {
@@ -305,11 +332,12 @@ TEST_F(BundleToJsonTest, StringArrayConversion) {
   ASSERT_EQ(bundle_add_str_array(bundleData, key.c_str(), value.data(), value.size()),
             BUNDLE_ERROR_NONE);
 
-  picojson::object json;
+  picojson::value json;
   auto result = common::BundleToJson(bundleData, &json);
   ASSERT_TRUE(result);
+  ASSERT_TRUE(json.is<picojson::object>());
 
-  const auto& array = json[key].get<picojson::array>();
+  const auto& array = json.get<picojson::object>()[key].get<picojson::array>();
   ASSERT_EQ(array.size(), value.size());
   EXPECT_EQ(array[0].get<std::string>(), std::string(value[0]));
   EXPECT_EQ(array[1].get<std::string>(), std::string(value[1]));
@@ -322,11 +350,12 @@ TEST_F(BundleToJsonTest, BytesConversion) {
   ASSERT_EQ(bundle_add_byte(bundleData, key.c_str(), bytes.data(), bytes.size()),
             BUNDLE_ERROR_NONE);
 
-  picojson::object json;
+  picojson::value json;
   auto result = common::BundleToJson(bundleData, &json);
   ASSERT_TRUE(result);
+  ASSERT_TRUE(json.is<picojson::object>());
 
-  const auto& array = json[key].get<picojson::array>();
+  const auto& array = json.get<picojson::object>()[key].get<picojson::array>();
   ASSERT_EQ(array.size(), bytes.size());
   EXPECT_EQ(array[0].get<double>(), bytes[0]);
   EXPECT_EQ(array[1].get<double>(), bytes[1]);
@@ -346,11 +375,12 @@ TEST_F(BundleToJsonTest, BytesArrayConversion) {
       bundle_set_byte_array_element(bundleData, key.c_str(), 1, value[1].data(), value[1].size()),
       BUNDLE_ERROR_NONE);
 
-  picojson::object json;
+  picojson::value json;
   auto result = common::BundleToJson(bundleData, &json);
   ASSERT_TRUE(result);
+  ASSERT_TRUE(json.is<picojson::object>());
 
-  auto& array = json[key].get<picojson::array>();
+  auto& array = json.get<picojson::object>()[key].get<picojson::array>();
   ASSERT_EQ(array.size(), value.size());
 
   auto& bytes = array[0].get<picojson::array>();
index 089202a..749ff21 100644 (file)
@@ -552,10 +552,7 @@ PlatformResult MediaControllerClient::SendCommand(const std::string& server_name
   };
 
   if (!data.is<picojson::null>()) {
-    bundle = bundle_create();
-
-    const picojson::object& json = data.get<picojson::object>();
-    PlatformResult result = common::JsonToBundle(json, bundle);
+    PlatformResult result = common::JsonToBundle(data, &bundle);
     if (!result) {
       LoggerE("JsonToBundle() failed.");
       return result;
@@ -585,9 +582,8 @@ void MediaControllerClient::OnCommandReply(const char* server_name, const char*
   picojson::value reply = picojson::value(picojson::object());
   picojson::object& reply_o = reply.get<picojson::object>();
 
-  picojson::value data = picojson::value(picojson::object());
-  picojson::object& data_obj = data.get<picojson::object>();
-  PlatformResult result = common::BundleToJson(bundle, &data_obj);
+  picojson::value data;
+  PlatformResult result = common::BundleToJson(bundle, &data);
   if (!result) {
     LoggerE("BundleToJson() failed.");
     ReportError(out_o);
index 93e6d88..0a2858e 100644 (file)
@@ -303,9 +303,8 @@ void MediaControllerServer::OnCommandReceived(const char* client_name, const cha
   ScopeLogger();
   MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
 
-  picojson::value data = picojson::value(picojson::object());
-  picojson::object& data_obj = data.get<picojson::object>();
-  PlatformResult result = common::BundleToJson(bundle, &data_obj);
+  picojson::value data;
+  PlatformResult result = common::BundleToJson(bundle, &data);
   if (!result) {
     LoggerE("BundleToJson() failed.");
     return;
@@ -334,10 +333,7 @@ PlatformResult MediaControllerServer::CommandReply(const std::string& client_nam
   };
 
   if (!data.is<picojson::null>()) {
-    bundle = bundle_create();
-    const picojson::object& json = data.get<picojson::object>();
-    PlatformResult result = common::JsonToBundle(json, bundle);
-
+    PlatformResult result = common::JsonToBundle(data, &bundle);
     if (!result) {
       LoggerE("JsonToBundle() failed.");
       return result;