1 /*
2  * Copyright (c) 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 NWEB_VALUE_H
17 #define NWEB_VALUE_H
18 
19 #include <iostream>
20 #include <map>
21 #include <set>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25 
26 #include "nweb_export.h"
27 
28 namespace OHOS::NWeb {
29 
30 union data_union {
31     int n;
32     double f;
33     bool b;
34 
data_union()35     data_union() {}
36 
data_union(int value)37     data_union(int value) : n(value) {}
38 
data_union(double value)39     data_union(double value) : f(value) {}
40 
data_union(bool value)41     data_union(bool value) : b(value) {}
42 };
43 
44 class OHOS_NWEB_EXPORT NWebValue {
45 public:
46     enum class Type : unsigned char {
47         NONE = 0,
48         BOOLEAN,
49         INTEGER,
50         DOUBLE,
51         STRING,
52         BINARY,
53         DICTIONARY,
54         LIST,
55         ERROR,
56         STRINGARRAY,
57         BOOLEANARRAY,
58         DOUBLEARRAY,
59         INT64ARRAY
60     };
61 
NWebValue()62     NWebValue() {}
63 
NWebValue(Type type)64     explicit NWebValue(Type type) : type_(type) {}
65 
NWebValue(const int & value)66     explicit NWebValue(const int& value) : type_(Type::INTEGER), data_(value) {}
67 
NWebValue(const double & value)68     explicit NWebValue(const double& value) : type_(Type::DOUBLE), data_(value) {}
69 
NWebValue(const bool & value)70     explicit NWebValue(const bool& value) : type_(Type::BOOLEAN), data_(value) {}
71 
NWebValue(const std::string & value)72     explicit NWebValue(const std::string& value) : type_(Type::STRING), str_(value) {}
73 
NWebValue(const char * data,size_t len)74     NWebValue(const char* data, size_t len) : type_(Type::BINARY), str_(data, len) {}
75 
NWebValue(const std::vector<NWebValue> & value)76     explicit NWebValue(const std::vector<NWebValue>& value) : type_(Type::LIST), list_value_(value.begin(), value.end())
77     {}
78 
NWebValue(const std::map<std::string,NWebValue> & value)79     explicit NWebValue(const std::map<std::string, NWebValue>& value)
80         : type_(Type::DICTIONARY), dictionary_value_(value)
81     {}
82 
NWebValue(const NWebValue & value)83     explicit NWebValue(const NWebValue& value) : type_(value.type_)
84     {
85         switch (type_) {
86             case Type::NONE:
87                 break;
88             case Type::BOOLEAN:
89                 data_.b = value.data_.b;
90                 break;
91             case Type::INTEGER:
92                 data_.n = value.data_.n;
93                 break;
94             case Type::DOUBLE:
95                 data_.f = value.data_.f;
96                 break;
97             case Type::STRING:
98                 str_ = value.str_;
99                 break;
100             case Type::BINARY:
101                 str_ = value.str_;
102                 break;
103             case Type::LIST:
104                 list_value_ = value.list_value_;
105                 break;
106             case Type::DICTIONARY:
107                 dictionary_value_ = value.dictionary_value_;
108                 break;
109             default:
110                 break;
111         }
112     }
113 
NWebValue(std::vector<NWebValue> && value)114     NWebValue(std::vector<NWebValue>&& value) : type_(Type::LIST)
115     {
116         std::swap(list_value_, value);
117     }
118 
NWebValue(std::map<std::string,NWebValue> && value)119     NWebValue(std::map<std::string, NWebValue>&& value) : type_(Type::DICTIONARY)
120     {
121         std::swap(dictionary_value_, value);
122     }
123 
NWebValue(NWebValue && value)124     NWebValue(NWebValue&& value)
125     {
126         *this = std::move(value);
127     }
128 
129     ~NWebValue() = default;
130 
131     NWebValue& operator=(const NWebValue& value)
132     {
133         SetType(value.type_);
134         switch (type_) {
135             case Type::NONE:
136                 break;
137             case Type::BOOLEAN:
138                 data_.b = value.data_.b;
139                 break;
140             case Type::INTEGER:
141                 data_.n = value.data_.n;
142                 break;
143             case Type::DOUBLE:
144                 data_.f = value.data_.f;
145                 break;
146             case Type::STRING:
147                 str_ = value.str_;
148                 break;
149             case Type::BINARY:
150                 str_ = value.str_;
151                 break;
152             case Type::LIST:
153                 list_value_ = value.list_value_;
154                 break;
155             case Type::DICTIONARY:
156                 dictionary_value_ = value.dictionary_value_;
157                 break;
158             default:
159                 std::cout << "error: Invalid type" << std::endl;
160                 break;
161         }
162         return *this;
163     }
164 
165     NWebValue& operator=(NWebValue&& value)
166     {
167         std::swap(type_, value.type_);
168         switch (type_) {
169             case Type::NONE:
170                 break;
171             case Type::BOOLEAN:
172                 std::swap(data_.b, value.data_.b);
173                 break;
174             case Type::INTEGER:
175                 std::swap(data_.n, value.data_.n);
176                 break;
177             case Type::DOUBLE:
178                 std::swap(data_.f, value.data_.f);
179                 break;
180             case Type::STRING:
181                 std::swap(str_, value.str_);
182                 break;
183             case Type::BINARY:
184                 std::swap(str_, value.str_);
185                 break;
186             case Type::LIST:
187                 std::swap(list_value_, value.list_value_);
188                 break;
189             case Type::DICTIONARY:
190                 std::swap(dictionary_value_, value.dictionary_value_);
191                 break;
192             default:
193                 std::cout << "error: Invalid type" << std::endl;
194                 break;
195         }
196         return *this;
197     }
198 
199     bool operator==(NWebValue& oVal)
200     {
201         if (type_ != oVal.type_)
202             return false;
203         switch (type_) {
204             case Type::NONE:
205                 return false;
206             case Type::BOOLEAN:
207                 return data_.b == oVal.data_.b;
208             case Type::INTEGER:
209                 return data_.n == oVal.data_.n;
210             case Type::DOUBLE:
211                 return data_.f == oVal.data_.f;
212             case Type::STRING:
213                 return str_ == oVal.str_;
214             case Type::LIST:
215                 if ((*this).list_value_.size() != oVal.list_value_.size())
216                     return false;
217                 for (size_t i = 0; i < list_value_.size(); ++i) {
218                     NWebValue& lVal = oVal.list_value_[i];
219                     NWebValue& rVal = (*this).list_value_[i];
220                     if (!(lVal == rVal)) {
221                         return false;
222                     }
223                 }
224                 return true;
225             case Type::DICTIONARY:
226                 if ((*this).dictionary_value_.size() != oVal.dictionary_value_.size())
227                     return false;
228                 for (auto item : dictionary_value_) {
229                     NWebValue& lVal = oVal.dictionary_value_[item.first];
230                     NWebValue& rVal = (*this).dictionary_value_[item.first];
231                     if (!(lVal == rVal)) {
232                         return false;
233                     }
234                 }
235                 return true;
236             case Type::BINARY:
237                 return str_ == oVal.str_;
238             default:
239                 std::cout << "error: Invalid type" << std::endl;
240                 return false;
241         }
242         return false;
243     }
244 
IsNone()245     bool IsNone()
246     {
247         return GetType() == Type::NONE;
248     }
249 
IsBoolean()250     bool IsBoolean()
251     {
252         return GetType() == Type::BOOLEAN;
253     }
254 
IsString()255     bool IsString()
256     {
257         return GetType() == Type::STRING;
258     }
259 
IsDouble()260     bool IsDouble()
261     {
262         return GetType() == Type::DOUBLE;
263     }
264 
IsINTEGER()265     bool IsINTEGER()
266     {
267         return GetType() == Type::INTEGER;
268     }
269 
IsList()270     bool IsList()
271     {
272         return GetType() == Type::LIST;
273     }
274 
IsDictionary()275     bool IsDictionary()
276     {
277         return GetType() == Type::DICTIONARY;
278     }
279 
IsBinary()280     bool IsBinary()
281     {
282         return GetType() == Type::BINARY;
283     }
284 
GetBoolean()285     bool GetBoolean()
286     {
287         validateType(Type::BOOLEAN);
288         return data_.b;
289     }
290 
SetBoolean(bool b)291     void SetBoolean(bool b)
292     {
293         validateType(Type::BOOLEAN);
294         data_.b = b;
295     }
296 
SetString(std::string str)297     void SetString(std::string str)
298     {
299         validateType(Type::STRING);
300         str_ = str;
301     }
302 
GetString()303     std::string GetString()
304     {
305         validateType(Type::STRING);
306         return str_;
307     }
308 
SetDouble(double dou)309     void SetDouble(double dou)
310     {
311         validateType(Type::DOUBLE);
312         data_.f = dou;
313     }
314 
GetDouble()315     double GetDouble()
316     {
317         validateType(Type::DOUBLE);
318         return data_.f;
319     }
320 
SetInt(int num)321     void SetInt(int num)
322     {
323         validateType(Type::INTEGER);
324         data_.n = num;
325     }
326 
GetInt()327     int GetInt()
328     {
329         validateType(Type::INTEGER);
330         return data_.n;
331     }
332 
GetListValueSize()333     size_t GetListValueSize()
334     {
335         validateType(Type::LIST);
336         return list_value_.size();
337     }
338 
GetListValue()339     std::vector<NWebValue> GetListValue()
340     {
341         validateType(Type::LIST);
342         return list_value_;
343     }
344 
GetListValue(unsigned int index)345     NWebValue& GetListValue(unsigned int index)
346     {
347         validateType(Type::LIST);
348         if (index >= list_value_.size()) {
349             std::cout << "error: index larger than size()" << std::endl;
350         }
351         return list_value_[index];
352     }
353 
AddListValue(const NWebValue & value)354     void AddListValue(const NWebValue& value)
355     {
356         validateType(Type::LIST);
357         SetType(Type::LIST);
358         list_value_.push_back(value);
359     }
360 
deleteListValue()361     void deleteListValue()
362     {
363         validateType(Type::LIST);
364         SetType(Type::LIST);
365         list_value_.pop_back();
366     }
367 
GetDictionaryValueSize()368     size_t GetDictionaryValueSize()
369     {
370         validateType(Type::DICTIONARY);
371         return dictionary_value_.size();
372     }
373 
GetDictionaryValueKeys()374     std::vector<std::string> GetDictionaryValueKeys()
375     {
376         validateType(Type::DICTIONARY);
377         std::vector<std::string> ret;
378         for (auto& item : dictionary_value_) {
379             ret.push_back(item.first);
380         }
381         return ret;
382     }
383 
HasDictionaryValueKey(std::string & key)384     bool HasDictionaryValueKey(std::string& key)
385     {
386         validateType(Type::DICTIONARY);
387         return dictionary_value_.count(key) == 1;
388     }
389 
GetDictionaryValue()390     std::map<std::string, NWebValue> GetDictionaryValue()
391     {
392         validateType(Type::DICTIONARY);
393         return dictionary_value_;
394     }
395 
GetDictionaryValue(std::string & key)396     NWebValue& GetDictionaryValue(std::string& key)
397     {
398         validateType(Type::DICTIONARY);
399         return dictionary_value_[key];
400     }
401 
AddDictionaryValue(std::string key,NWebValue & value)402     void AddDictionaryValue(std::string key, NWebValue& value)
403     {
404         validateType(Type::DICTIONARY);
405         dictionary_value_[key] = value;
406     }
407 
DeleteDictionaryValue(std::string & key)408     void DeleteDictionaryValue(std::string& key)
409     {
410         validateType(Type::DICTIONARY);
411         dictionary_value_.erase(key);
412     }
413 
GetBinaryValueSize()414     size_t GetBinaryValueSize()
415     {
416         validateType(Type::BINARY);
417         return str_.size();
418     }
419 
GetBinaryValue()420     const char* GetBinaryValue()
421     {
422         validateType(Type::BINARY);
423         return (const char*)str_.c_str();
424     }
425 
SetJsonString(std::string json_string)426     void SetJsonString(std::string json_string)
427     {
428         str_json_ = json_string;
429     }
430 
GetJsonString()431     std::string GetJsonString()
432     {
433         return str_json_;
434     }
435 
GetType()436     Type GetType()
437     {
438         return type_;
439     }
440 
SetType(Type type)441     void SetType(Type type)
442     {
443         type_ = type;
444     }
445 
validateType(Type type)446     void validateType(Type type) const
447     {
448         if (type_ != Type::NONE && type_ != type) {
449             std::cout << "error: Invalid type" << std::endl;
450         }
451     }
452 
453     int error_ = 0;
454 
455 private:
456     Type type_ = Type::NONE;
457     data_union data_;
458     std::string str_;
459     std::string str_json_;
460     std::map<std::string, NWebValue> dictionary_value_;
461     std::vector<NWebValue> list_value_;
462 };
463 
464 } // namespace OHOS::NWeb
465 
466 #endif // NWEB_VALUE_H
467