1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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_parser.h"
17 #include <errors.h>
18 #include <fstream>
19 #include <memory>
20 #include <unistd.h>
21 #include "common/common_macro.h"
22 #include "media_log.h"
23 
24 namespace OHOS {
25 namespace Sharing {
GetConfig(std::string &fileName, SharingData::Ptr &value)26 int32_t JsonParser::GetConfig(std::string &fileName, SharingData::Ptr &value)
27 {
28     SHARING_LOGD("trace.");
29     Json::Value root;
30     std::ifstream ifs;
31     ifs.open(fileName.c_str());
32 
33     if (!ifs.is_open()) {
34         SHARING_LOGE("cannot open %{public}s.", fileName.c_str());
35         return -1;
36     }
37 
38     Json::CharReaderBuilder builder;
39     builder["collectComments"] = false;
40     JSONCPP_STRING errs;
41 
42     if (!parseFromStream(builder, ifs, &root, &errs)) {
43         SHARING_LOGE("parse file error: %{public}s.", errs.c_str());
44         return -1;
45     }
46 
47     SHARING_LOGD("parse json:\n%{public}s.", root.toStyledString().c_str());
48     for (auto &modules : root) {
49         ReadModuleConfig(modules, value);
50     }
51 
52     ifs.close();
53     return 0;
54 }
55 
SaveConfig(std::string &fileName, SharingData::Ptr &value)56 int32_t JsonParser::SaveConfig(std::string &fileName, SharingData::Ptr &value)
57 {
58     SHARING_LOGD("trace.");
59     RETURN_INVALID_IF_NULL(value);
60     std::ofstream ofs;
61     ofs.open(fileName.c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
62 
63     if (!ofs.is_open()) {
64         SHARING_LOGE("open file %{public}s err.", fileName.c_str());
65         return -1;
66     }
67 
68     Json::Value root(Json::ValueType::objectValue);
69     Json::StreamWriterBuilder builder;
70     builder["commentStyle"] = "All";
71     Json::StreamWriter *writer(builder.newStreamWriter());
72 
73     value->ForEach([&](const std::string &moduleName, const SharingDataGroupByModule::Ptr &moduleValue) {
74         Json::Value moduleArray(Json::ValueType::arrayValue);
75         SaveModuleConfig(moduleArray, moduleValue);
76         root[moduleName] = moduleArray;
77     });
78 
79     MEDIA_LOGD("save json:\n%{public}s.", root.toStyledString().c_str());
80     writer->write(root, &ofs);
81     ofs.close();
82     return 0;
83 }
84 
ReadModuleConfig(Json::Value &modules, SharingData::Ptr &value)85 int32_t JsonParser::ReadModuleConfig(Json::Value &modules, SharingData::Ptr &value)
86 {
87     SHARING_LOGD("trace.");
88     if (modules.empty()) {
89         SHARING_LOGE("this module is empty.");
90         return -1;
91     }
92 
93     auto moduleNames = modules.getMemberNames();
94     for (auto &moduleName : moduleNames) {
95         MEDIA_LOGD("take down %{public}s: %{public}s.", moduleName.c_str(),
96                    modules[moduleName].toStyledString().c_str());
97         auto moduleValue = std::make_shared<SharingDataGroupByModule>(moduleName);
98         auto module = modules[moduleName];
99         for (auto &item : module) {
100             auto tag = item["tag"].asString();
101             auto tagValue = std::make_shared<SharingDataGroupByTag>(tag);
102             moduleValue->PutSharingValues(tag, tagValue);
103             auto keyNames = item.getMemberNames();
104             for (auto &key : keyNames) {
105                 if (key == "tag") {
106                     continue;
107                 }
108                 if (key == "isEnable" && tag == "mediaLog") {
109                     g_logOn = item[key].asBool();
110                 }
111                 SharingValue::Ptr sharingData = nullptr;
112                 if (item[key].isString()) {
113                     std::string value = item[key].asString();
114                     sharingData = std::make_shared<SharingValue>(value);
115                 } else if (item[key].isInt()) {
116                     int32_t value = item[key].asInt();
117                     sharingData = std::make_shared<SharingValue>(value);
118                 } else if (item[key].isBool()) {
119                     bool value = item[key].asBool();
120                     sharingData = std::make_shared<SharingValue>(value);
121                 } else if (item[key].isArray()) {
122                     std::vector<int32_t> value;
123                     for (auto &it : item[key]) {
124                         value.emplace_back(it.asInt());
125                     }
126                     sharingData = std::make_shared<SharingValue>(value);
127                 }
128                 tagValue->PutSharingValue(key, sharingData);
129             }
130         }
131         value->PutSharingValues(moduleValue, moduleName);
132     }
133 
134     return 0;
135 }
136 
SaveModuleConfig(Json::Value &module, const SharingDataGroupByModule::Ptr &moduleValue)137 int32_t JsonParser::SaveModuleConfig(Json::Value &module, const SharingDataGroupByModule::Ptr &moduleValue)
138 {
139     SHARING_LOGD("trace.");
140     RETURN_INVALID_IF_NULL(moduleValue);
141     moduleValue->ForEach([&](const std::string &tagName, const SharingDataGroupByTag::Ptr &tagValue) {
142         Json::Value tagObject(Json::ValueType::objectValue);
143         tagObject["tag"] = tagName;
144         tagValue->ForEach([&](const std::string &key, const SharingValue::Ptr &value) {
145             if (value->IsBool()) {
146                 bool data;
147                 if (value->GetValue(data)) {
148                     tagObject[key] = data;
149                 }
150             } else if (value->IsInt32()) {
151                 int32_t data;
152                 if (value->GetValue(data)) {
153                     tagObject[key] = data;
154                 }
155             } else if (value->IsString()) {
156                 std::string data;
157                 if (value->GetValue(data)) {
158                     tagObject[key] = data;
159                 }
160             } else if (value->IsVector()) {
161                 std::vector<int32_t> data;
162                 if (value->GetValue(data)) {
163                     Json::Value vec(Json::ValueType::arrayValue);
164                     for (auto &item : data) {
165                         vec.append(item);
166                     }
167                     tagObject[key] = vec;
168                 }
169             }
170         });
171         module.append(tagObject);
172     });
173 
174     return 0;
175 }
176 } // namespace Sharing
177 } // namespace OHOS