Fix static analysis issues
[platform/core/base/bundle.git] / src / json-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 "exception-internal.h"
18 #include "json-internal.h"
19
20 namespace tizen_base {
21 namespace internal {
22
23 Json::Json(std::string json) : json_(std::move(json)) {
24 }
25
26 Json::Json(Bundle* b) : b_(b) {
27 }
28
29 Bundle* Json::ToBundle() {
30   if (json_.empty())
31     return nullptr;
32
33   JsonParser* parser = json_parser_new();
34   if (parser == nullptr)
35     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
36
37   std::unique_ptr<JsonParser, decltype(g_object_unref)*> parser_ptr(parser,
38       g_object_unref);
39
40   GError* error = nullptr;
41   json_parser_load_from_data(parser, json_.c_str(), json_.length(), &error);
42   if (error) {
43     g_error_free(error);
44     THROW(BUNDLE_ERROR_INVALID_PARAMETER);
45   }
46
47   JsonNode* root = json_parser_get_root(parser);
48   if (root == nullptr)
49     THROW(BUNDLE_ERROR_INVALID_PARAMETER);
50
51   JsonObject* root_obj = json_node_get_object(root);
52   if (root_obj == nullptr)
53     THROW(BUNDLE_ERROR_INVALID_PARAMETER);
54
55   Bundle* b = new (std::nothrow) Bundle();
56   if (b == nullptr)
57     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
58
59   json_object_foreach_member(root_obj, OnJsonObjectMember, b);
60
61   return b;
62 }
63
64 std::string Json::ToString() {
65   if (b_ == nullptr)
66     THROW(BUNDLE_ERROR_INVALID_PARAMETER);
67
68   JsonObject* object = json_object_new();
69   if (object == nullptr)
70     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
71
72   std::unique_ptr<JsonObject, decltype(json_object_unref)*> object_ptr(object,
73       json_object_unref);
74
75   for (const auto& kv : b_->GetMap()) {
76     auto& key_info = kv.second;
77     if (key_info->GetType() == Bundle::Type::StringArray) {
78       JsonArray* json_arr = json_array_new();
79       if (json_arr == nullptr)
80         THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
81
82       for (const auto& v : key_info->GetValues()) {
83         json_array_add_string_element(json_arr,
84             const_cast<const char*>(reinterpret_cast<char*>(v.get())));
85       }
86
87       json_object_set_array_member(object, key_info->GetKey().c_str(),
88           json_arr);
89     } else {
90       json_object_set_string_member(object, key_info->GetKey().c_str(),
91           const_cast<const char*>(
92             reinterpret_cast<char*>(
93               key_info->GetValues()[0].get())));
94     }
95   }
96
97   JsonNode* node = json_node_new(JSON_NODE_OBJECT);
98   if (node == nullptr)
99     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
100
101   std::unique_ptr<JsonNode, decltype(json_node_free)*> node_ptr(node,
102       json_node_free);
103
104   json_node_set_object(node, object);
105
106   JsonGenerator* generator = json_generator_new();
107   if (generator == nullptr)
108     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
109
110   std::unique_ptr<JsonGenerator, decltype(g_object_unref)*> generator_ptr(
111       generator, g_object_unref);
112
113   json_generator_set_root(generator, node);
114   gsize length = 0;
115   gchar* json = json_generator_to_data(generator, &length);
116   if (json == nullptr)
117     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
118
119   std::unique_ptr<gchar, decltype(g_free)*> json_auto(json, g_free);
120   json_ = json;
121   return json_;
122 }
123
124 void Json::OnJsonObjectMember(JsonObject* object, const char* key,
125   JsonNode* node, gpointer user_data) {
126   auto* b = static_cast<Bundle*>(user_data);
127   KeyInfo* key_info;
128   JsonNodeType node_type = JSON_NODE_TYPE(node);
129   if (node_type == JSON_NODE_ARRAY) {
130     JsonArray* json_arr = json_node_get_array(node);
131     if (json_arr == nullptr)
132       return;
133
134     std::vector<std::vector<unsigned char>> values;
135     guint len = json_array_get_length(json_arr);
136     for (guint i = 0; i < len; ++i) {
137       auto* val = json_array_get_string_element(json_arr, i);
138       if (val == nullptr)
139         val = "";
140
141       auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
142       std::vector<unsigned char> value(p, p + (strlen(val) + 1));
143       values.push_back(std::move(value));
144     }
145
146     try {
147       key_info = new KeyInfo(Bundle::Type::StringArray, key, std::move(values));
148     } catch (const Exception& e) {
149       _E("Error(%d)", e.GetErrorCode());
150       return;
151     } catch (const std::bad_alloc& ba) {
152       _E("bad alloc exception");
153       return;
154     }
155   } else {
156     auto* val = json_node_get_string(node);
157     if (val == nullptr)
158       val = "";
159
160     auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
161     std::vector<unsigned char> value(p, p + (strlen(val) + 1));
162
163     try {
164       key_info = new KeyInfo(Bundle::Type::String, key, std::move(value));
165     } catch (const Exception& e) {
166       _E("Error(%d)", e.GetErrorCode());
167       return;
168     } catch (const std::bad_alloc& ba) {
169       _E("bad alloc exception");
170       return;
171     }
172   }
173
174   try {
175     b->Add(std::shared_ptr<KeyInfo>(key_info));
176   } catch (const Exception& e) {
177     _W("Add() is failed. error(%d)", e.GetErrorCode());
178     return;
179   }
180 }
181
182 }  // namespace internal
183 }  // namespace tizen_base