• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 OHOS_WIFI_CONFIG_FILE_IMPL_H
17 #define OHOS_WIFI_CONFIG_FILE_IMPL_H
18 #include <fstream>
19 #include <sstream>
20 #include <string>
21 #include <unistd.h>
22 #include <vector>
23 #include "wifi_config_file_spec.h"
24 #include "wifi_log.h"
25 
26 namespace OHOS {
27 namespace Wifi {
28 /**
29  * @Description Remove head and tail space
30  *
31  * @param str - String
32  */
TrimString(std::string & str)33 static inline void TrimString(std::string &str)
34 {
35     int i = 0;
36     int j = static_cast<int>(str.length()) - 1;
37     while (i < static_cast<int>(str.length()) && str[i] == ' ') {
38         ++i;
39     }
40     while (j >= 0 && str[j] == ' ') {
41         --j;
42     }
43     str = ((i > j) ? "" : str.substr(i, j - i + 1));
44 }
45 
46 /**
47  * @Description Delete comment message begin with ; and #
48  *
49  * @param str - String
50  */
DelComment(std::string & str)51 static inline void DelComment(std::string &str)
52 {
53     std::string::size_type i = 0;
54     for (; i < str.length(); ++i) {
55         if (str[i] == ';' || str[i] == '#') {
56             str = str.substr(0, i);
57             break;
58         }
59     }
60     return;
61 }
62 
63 template<typename T>
64 class WifiConfigFileImpl {
65 public:
66     /**
67      * @Description Set the config file path
68      *
69      * @param fileName - file name
70      * @return int - 0 success
71      */
72     int SetConfigFilePath(const std::string &fileName);
73 
74     /**
75      * @Description read and parses the ini config file, need call SetConfigFilePath first
76      *
77      * @return int - 0 Success; -1 file not exist
78      */
79     int LoadConfig();
80 
81     /**
82      * @Description Save config to file
83      *
84      * @return int - 0 Success; -1 Failed
85      */
86     int SaveConfig();
87 
88     /**
89      * @Description Get config values
90      *
91      * @param results - output config values
92      * @return int - 0 Success, -1 Failed
93      */
94     int GetValue(std::vector<T> &results);
95 
96     /**
97      * @Description Get config values
98      *
99      * @return config values
100      */
101     const std::vector<T>& GetValue() const;
102 
103     /**
104      * @Description Set the config value
105      *
106      * @param values - input config values
107      * @return int - 0 Success, -1 Failed
108      */
109     int SetValue(const std::vector<T> &values);
110 
111 private:
112     std::string mFileName;
113     std::vector<T> mValues;
114 };
115 
116 template<typename T>
SetConfigFilePath(const std::string & fileName)117 int WifiConfigFileImpl<T>::SetConfigFilePath(const std::string &fileName)
118 {
119     mFileName = fileName;
120     return 0;
121 }
122 
123 template<typename T>
LoadConfig()124 int WifiConfigFileImpl<T>::LoadConfig()
125 {
126     if (mFileName.empty()) {
127         LOGE("File name is empty.");
128         return -1;
129     }
130     std::ifstream fs(mFileName.c_str());
131     if (!fs.is_open()) {
132         LOGE("Loading config file: %{public}s, fs.is_open() failed!", mFileName.c_str());
133         return -1;
134     }
135     mValues.clear();
136     bool bSection = false;
137     T item;
138     std::string line;
139     while (std::getline(fs, line)) {
140         TrimString(line);
141         if (line.empty()) {
142             continue;
143         }
144         if (line[0] == '[' && line[line.length() - 1] == ']') {
145             if (bSection) {
146                 mValues.push_back(item);
147             }
148             bSection = true;
149             ClearTClass(item); /* template function, needing specialization */
150             continue;
151         }
152         std::string::size_type npos = line.find("=");
153         if (npos == std::string::npos) {
154             continue;
155         }
156         std::string key = line.substr(0, npos);
157         std::string value = line.substr(npos + 1);
158         TrimString(key);
159         TrimString(value);
160         /* template function, needing specialization */
161         SetTClassKeyValue(item, key, value);
162     }
163     if (bSection) {
164         mValues.push_back(item);
165     }
166     fs.close();
167     return 0;
168 }
169 
170 template<typename T>
SaveConfig()171 int WifiConfigFileImpl<T>::SaveConfig()
172 {
173     if (mFileName.empty()) {
174         LOGE("File name is empty.");
175         return -1;
176     }
177     FILE* fp = fopen(mFileName.c_str(), "w");
178     if (!fp) {
179         LOGE("Save config file: %{public}s, fopen() failed!", mFileName.c_str());
180         return -1;
181     }
182     std::ostringstream ss;
183     for (std::size_t i = 0; i < mValues.size(); ++i) {
184         T &item = mValues[i];
185         /*
186          * here use template function GetTClassName OutTClassString, needing
187          * specialization.
188          */
189         ss << "[" << GetTClassName<T>() << "_" << (i + 1) << "]" << std::endl;
190         ss << OutTClassString(item) << std::endl;
191     }
192     std::string content = ss.str();
193     int ret = fwrite(content.c_str(), 1, content.length(), fp);
194     if (ret != (int)content.length()) {
195         LOGE("Save config file: %{public}s, fwrite() failed!", mFileName.c_str());
196     }
197     (void)fflush(fp);
198     (void)fsync(fileno(fp));
199     (void)fclose(fp);
200     mValues.clear(); /* clear values */
201     return 0;
202 }
203 
204 template<typename T>
GetValue(std::vector<T> & results)205 int WifiConfigFileImpl<T>::GetValue(std::vector<T> &results)
206 {
207     /*
208      * swap, WifiConfigFileImpl not saved this config when next use, call LoadConfig first
209      */
210     std::swap(results, mValues);
211     return 0;
212 }
213 
214 template <typename T>
GetValue()215 const std::vector<T>& WifiConfigFileImpl<T>::GetValue() const
216 {
217     return mValues;
218 }
219 
220 template <typename T>
SetValue(const std::vector<T> & results)221 int WifiConfigFileImpl<T>::SetValue(const std::vector<T> &results)
222 {
223     mValues = results;
224     return 0;
225 }
226 }  // namespace Wifi
227 }  // namespace OHOS
228 #endif