1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "json_utils.h"
17
18 #include <climits>
19 #include <fcntl.h>
20 #include <fstream>
21 #include <sstream>
22 #include <unistd.h>
23 #include <vector>
24
25 #include "standby_service_log.h"
26
27 namespace OHOS {
28 namespace DevStandbyMgr {
29 namespace {
30 constexpr uint32_t JSON_FORMAT = 4;
31 }
32
LoadJsonValueFromContent(nlohmann::json & jsonValue,const std::string & content)33 bool JsonUtils::LoadJsonValueFromContent(nlohmann::json& jsonValue, const std::string& content)
34 {
35 if (content.empty()) {
36 STANDBYSERVICE_LOGE("content is empty");
37 return false;
38 }
39 jsonValue = nlohmann::json::parse(content, nullptr, false);
40 if (jsonValue.is_discarded()) {
41 STANDBYSERVICE_LOGE("failed to parse content");
42 return false;
43 }
44 if (!jsonValue.is_object()) {
45 STANDBYSERVICE_LOGE("the content is not an object");
46 return false;
47 }
48 return true;
49 }
50
LoadJsonValueFromFile(nlohmann::json & jsonValue,const std::string & filePath)51 bool JsonUtils::LoadJsonValueFromFile(nlohmann::json& jsonValue, const std::string& filePath)
52 {
53 std::string content;
54 if (!GetFileContent(filePath, content)) {
55 STANDBYSERVICE_LOGE("failed to load content from %{public}s", filePath.c_str());
56 return false;
57 }
58 if (content.empty()) {
59 STANDBYSERVICE_LOGE("content of %{public}s is empty", filePath.c_str());
60 return false;
61 }
62 jsonValue = nlohmann::json::parse(content, nullptr, false);
63 if (jsonValue.is_discarded()) {
64 STANDBYSERVICE_LOGE("failed to parse content from %{public}s", filePath.c_str());
65 return false;
66 }
67 if (!jsonValue.is_object()) {
68 STANDBYSERVICE_LOGE("the content of %{public}s is not an object ", filePath.c_str());
69 return false;
70 }
71 return true;
72 }
73
DumpJsonValueToFile(const nlohmann::json & jsonValue,const std::string & filePath)74 bool JsonUtils::DumpJsonValueToFile(const nlohmann::json& jsonValue, const std::string& filePath)
75 {
76 if (!CreateNodeFile(filePath)) {
77 STANDBYSERVICE_LOGE("create file failed.");
78 return false;
79 }
80 std::ofstream fout;
81 std::string realPath;
82 if (!GetRealPath(filePath, realPath)) {
83 STANDBYSERVICE_LOGE("get real file path: %{public}s failed", filePath.c_str());
84 return false;
85 }
86 fout.open(realPath, std::ios::out);
87 if (!fout.is_open()) {
88 STANDBYSERVICE_LOGE("open file: %{public}s failed.", filePath.c_str());
89 return false;
90 }
91 fout << jsonValue.dump(JSON_FORMAT).c_str() << std::endl;
92 fout.close();
93 return true;
94 }
95
CreateNodeFile(const std::string & filePath)96 bool JsonUtils::CreateNodeFile(const std::string &filePath)
97 {
98 if (access(filePath.c_str(), F_OK) == ERR_OK) {
99 STANDBYSERVICE_LOGD("the standby service config file: %{public}s already exists.", filePath.c_str());
100 return true;
101 }
102 std::string fullpath {""};
103 if (!GetRealPath(filePath, fullpath)) {
104 STANDBYSERVICE_LOGD("the standby service config file: %{public}s not exists.", filePath.c_str());
105 fullpath = filePath;
106 }
107 int32_t fd = open(fullpath.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
108 if (fd < ERR_OK) {
109 STANDBYSERVICE_LOGE("Fail to open file: %{public}s", fullpath.c_str());
110 return false;
111 }
112 close(fd);
113 return true;
114 }
115
GetInt32FromJsonValue(const nlohmann::json & jsonValue,const std::string & key,int32_t & value)116 bool JsonUtils::GetInt32FromJsonValue(const nlohmann::json& jsonValue, const std::string& key, int32_t& value)
117 {
118 if (jsonValue.empty() || key.empty()) {
119 return false;
120 }
121 if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_number_integer()) {
122 return false;
123 }
124 value = jsonValue.at(key).get<int32_t>();
125 return true;
126 }
127
GetBoolFromJsonValue(const nlohmann::json & jsonValue,const std::string & key,bool & value)128 bool JsonUtils::GetBoolFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, bool& value)
129 {
130 if (jsonValue.empty() || key.empty()) {
131 return false;
132 }
133 if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_boolean()) {
134 return false;
135 }
136 value = jsonValue.at(key).get<bool>();
137 return true;
138 }
139
GetStringFromJsonValue(const nlohmann::json & jsonValue,const std::string & key,std::string & value)140 bool JsonUtils::GetStringFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, std::string& value)
141 {
142 if (jsonValue.empty() || key.empty()) {
143 return false;
144 }
145 if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_string()) {
146 return false;
147 }
148 value = jsonValue.at(key).get<std::string>();
149 return true;
150 }
151
GetObjFromJsonValue(const nlohmann::json & jsonValue,const std::string & key,nlohmann::json & value)152 bool JsonUtils::GetObjFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, nlohmann::json& value)
153 {
154 if (jsonValue.empty() || key.empty()) {
155 return false;
156 }
157 if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_object()) {
158 return false;
159 }
160 value = jsonValue.at(key);
161 return true;
162 }
163
GetArrayFromJsonValue(const nlohmann::json & jsonValue,const std::string & key,nlohmann::json & value)164 bool JsonUtils::GetArrayFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, nlohmann::json& value)
165 {
166 if (jsonValue.empty() || key.empty()) {
167 return false;
168 }
169 if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_array()) {
170 return false;
171 }
172 value = jsonValue.at(key);
173 return true;
174 }
175
GetStrArrFromJsonValue(const nlohmann::json & jsonValue,const std::string & key,std::vector<std::string> & strArray)176 bool JsonUtils::GetStrArrFromJsonValue(const nlohmann::json& jsonValue, const std::string& key,
177 std::vector<std::string>& strArray)
178 {
179 nlohmann::json strArrayValue;
180 if (!JsonUtils::GetArrayFromJsonValue(jsonValue, key, strArrayValue)) {
181 return false;
182 }
183 strArray.clear();
184 for (const auto &strItem : strArrayValue) {
185 if (!strItem.is_string()) {
186 return false;
187 }
188 strArray.emplace_back(strItem.get<std::string>());
189 }
190 return true;
191 }
192
GetFileContent(const std::string & filePath,std::string & content)193 bool JsonUtils::GetFileContent(const std::string& filePath, std::string& content)
194 {
195 std::string fullPath;
196 if (!GetRealPath(filePath, fullPath)) {
197 return false;
198 }
199 STANDBYSERVICE_LOGD("full path of standby service config file is: %{public}s ", fullPath.c_str());
200 std::ifstream fin(fullPath);
201 if (!fin.is_open()) {
202 return false;
203 }
204 std::ostringstream ss;
205 ss << fin.rdbuf();
206 content = ss.str();
207 return true;
208 }
209
GetRealPath(const std::string & partialPath,std::string & fullPath)210 bool JsonUtils::GetRealPath(const std::string& partialPath, std::string& fullPath)
211 {
212 char tmpPath[PATH_MAX] = {0};
213 if (partialPath.size() > PATH_MAX || !realpath(partialPath.c_str(), tmpPath)) {
214 return false;
215 }
216 fullPath = tmpPath;
217 return true;
218 }
219
SplitVersion(const std::string & versionStr,char versionDelim)220 std::vector<std::string> JsonUtils::SplitVersion(const std::string& versionStr, char versionDelim)
221 {
222 std::vector<std::string> tokens;
223 std::stringstream ss(versionStr);
224 std::string token;
225 while (std::getline(ss, token, versionDelim)) {
226 if (!token.empty()) {
227 tokens.push_back(token);
228 }
229 }
230 return tokens;
231 }
232 } // namespace DevStandbyMgr
233 } // namespace OHOS