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 #ifndef SERVICES_INCLUDE_IME_CONFIG_PARSE_H
17 #define SERVICES_INCLUDE_IME_CONFIG_PARSE_H
18
19 #include <sys/types.h>
20
21 #include <memory>
22 #include <mutex>
23 #include <string>
24 #include <vector>
25
26 #include "global.h"
27 #include "config_policy_utils.h"
28
29 #include "nlohmann/json.hpp"
30
31 namespace OHOS {
32 namespace MiscServices {
33 class ImeConfigParse {
34 public:
35 static std::string ReadFile(const std::string &path);
36 static CfgFiles* ParseFromCustom();
37 static bool ParseJson(const std::string &cfgPath, const std::string &parseKey, nlohmann::json &jsonCfg);
38 template<typename T>
39 static bool ParseFromCustomSystem(const std::string &parseKey, T &data);
40 template<typename T>
41 static bool ParseFromCustomSystem(const std::string &parseKey, std::vector<T> &data);
42 template<typename T>
43 static bool GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, T &data);
44 template<typename T>
45 static bool GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, std::vector<T> &data);
46 };
47
48 template<typename T>
ParseFromCustomSystem(const std::string & parseKey,T & data)49 bool ImeConfigParse::ParseFromCustomSystem(const std::string &parseKey, T &data)
50 {
51 CfgFiles* cfgFiles = ParseFromCustom();
52 if (cfgFiles == nullptr) {
53 IMSA_HILOGE("cfgFiles is nullptr");
54 return false;
55 }
56 bool isSuccess = true;
57 // parse config files, ordered by priority from high to low
58 for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
59 auto path = cfgFiles->paths[i];
60 if (path == nullptr || *path == '\0') {
61 continue;
62 }
63 isSuccess = false;
64 char realPath[PATH_MAX + 1] = { 0x00 };
65 if (strlen(path) == 0 || strlen(path) > PATH_MAX || realpath(path, realPath) == nullptr) {
66 IMSA_HILOGE("failed to get realpath");
67 break;
68 }
69 std::string cfgPath(realPath);
70 if (GetCfgsFromFile(cfgPath, parseKey, data)) {
71 isSuccess = true;
72 break;
73 }
74 }
75 FreeCfgFiles(cfgFiles);
76 IMSA_HILOGI("parse result: %{public}d", isSuccess);
77 return isSuccess;
78 }
79
80 template<typename T>
ParseFromCustomSystem(const std::string & parseKey,std::vector<T> & data)81 bool ImeConfigParse::ParseFromCustomSystem(const std::string &parseKey, std::vector<T> &data)
82 {
83 CfgFiles* cfgFiles = ParseFromCustom();
84 if (cfgFiles == nullptr) {
85 IMSA_HILOGE("cfgFiles is nullptr");
86 return false;
87 }
88 bool isSuccess = true;
89 // parse config files, ordered by priority from high to low
90 for (int32_t i = MAX_CFG_POLICY_DIRS_CNT - 1; i >= 0; i--) {
91 auto path = cfgFiles->paths[i];
92 if (path == nullptr || *path == '\0') {
93 continue;
94 }
95 isSuccess = false;
96 char realPath[PATH_MAX + 1] = { 0x00 };
97 if (strlen(path) == 0 || strlen(path) > PATH_MAX || realpath(path, realPath) == nullptr) {
98 IMSA_HILOGE("failed to get realpath");
99 break;
100 }
101 std::string cfgPath(realPath);
102 if (!GetCfgsFromFile(cfgPath, parseKey, data)) {
103 break;
104 }
105 isSuccess = true;
106 }
107 FreeCfgFiles(cfgFiles);
108 IMSA_HILOGI("parse result: %{public}d", isSuccess);
109 return isSuccess;
110 }
111
112 template<typename T>
GetCfgsFromFile(const std::string & cfgPath,const std::string & parseKey,T & data)113 bool ImeConfigParse::GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, T &data)
114 {
115 nlohmann::json jsonCfg;
116 if (ParseJson(cfgPath, parseKey, jsonCfg)) {
117 data = jsonCfg.at(parseKey).get<T>();
118 return true;
119 }
120 return false;
121 }
122
123 template<typename T>
GetCfgsFromFile(const std::string & cfgPath,const std::string & parseKey,std::vector<T> & data)124 bool ImeConfigParse::GetCfgsFromFile(const std::string &cfgPath, const std::string &parseKey, std::vector<T> &data)
125 {
126 nlohmann::json jsonCfg;
127 if (ParseJson(cfgPath, parseKey, jsonCfg)) {
128 if (!jsonCfg.at(parseKey).is_array()) {
129 IMSA_HILOGE("%{public}s is not array", parseKey.c_str());
130 return false;
131 }
132 data = jsonCfg.at(parseKey).get<std::vector<T>>();
133 return true;
134 }
135 return false;
136 }
137 } // namespace MiscServices
138 } // namespace OHOS
139 #endif // SERVICES_INCLUDE_IME_CONFIG_PARSE_H
140