1/*
2 * Copyright (c) 2021 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 FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_CODEC_DATA_H
17#define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_CODEC_DATA_H
18
19#include <cstdint>
20#include <map>
21#include <memory>
22#include <set>
23#include <string>
24#include <variant>
25#include <vector>
26
27namespace OHOS::Ace::Framework {
28
29enum class BufferDataType : uint8_t {
30    TYPE_NULL = 0x10,
31    TYPE_TRUE,
32    TYPE_FALSE,
33    TYPE_INT,
34    TYPE_LONG,
35    TYPE_DOUBLE,
36    TYPE_STRING,
37    TYPE_MAP,
38    TYPE_SET,
39    TYPE_INT8_ARRAY,
40    TYPE_INT16_ARRAY,
41    TYPE_INT32_ARRAY,
42    TYPE_FUNCTION,
43    TYPE_OBJECT,
44};
45
46class CodecData final {
47public:
48    CodecData() = default;
49    ~CodecData() = default;
50    CodecData(const CodecData& other) = default;
51    CodecData(CodecData&& other) = default;
52    CodecData& operator=(const CodecData& other) = default;
53    CodecData& operator=(CodecData&& other) = default;
54
55    explicit CodecData(bool val) : type_(val ? BufferDataType::TYPE_TRUE : BufferDataType::TYPE_FALSE) {}
56    explicit CodecData(int32_t val) : type_(BufferDataType::TYPE_INT), data_(val) {}
57    explicit CodecData(int32_t val, BufferDataType type) : type_(type), data_(val) {}
58    explicit CodecData(int64_t val) : type_(BufferDataType::TYPE_LONG), data_(val) {}
59    explicit CodecData(double val) : type_(BufferDataType::TYPE_DOUBLE), data_(val) {}
60
61    explicit CodecData(const std::string& val) : type_(BufferDataType::TYPE_STRING), data_(val) {}
62    explicit CodecData(const std::string& val, BufferDataType type) : type_(type), data_(val) {}
63    explicit CodecData(const std::map<std::string, std::string>& val) : type_(BufferDataType::TYPE_MAP), data_(val) {}
64    explicit CodecData(const std::set<std::string>& val) : type_(BufferDataType::TYPE_SET), data_(val) {}
65    explicit CodecData(const std::vector<int8_t>& val) : type_(BufferDataType::TYPE_INT8_ARRAY), data_(val) {}
66    explicit CodecData(const std::vector<int16_t>& val) : type_(BufferDataType::TYPE_INT16_ARRAY), data_(val) {}
67    explicit CodecData(const std::vector<int32_t>& val) : type_(BufferDataType::TYPE_INT32_ARRAY), data_(val) {}
68
69    explicit CodecData(std::string&& val) : type_(BufferDataType::TYPE_STRING), data_(std::move(val)) {}
70    explicit CodecData(std::map<std::string, std::string>&& val)
71        : type_(BufferDataType::TYPE_MAP), data_(std::move(val)) {}
72    explicit CodecData(std::set<std::string>&& val) : type_(BufferDataType::TYPE_SET), data_(std::move(val)) {}
73    explicit CodecData(std::vector<int8_t>&& val) : type_(BufferDataType::TYPE_INT8_ARRAY), data_(std::move(val)) {}
74    explicit CodecData(std::vector<int16_t>&& val) : type_(BufferDataType::TYPE_INT16_ARRAY), data_(std::move(val)) {}
75    explicit CodecData(std::vector<int32_t>&& val) : type_(BufferDataType::TYPE_INT32_ARRAY), data_(std::move(val)) {}
76
77    BufferDataType GetType() const
78    {
79        return type_;
80    }
81    bool IsNull() const
82    {
83        return type_ == BufferDataType::TYPE_NULL;
84    }
85    bool IsBool() const
86    {
87        return type_ == BufferDataType::TYPE_TRUE || type_ == BufferDataType::TYPE_FALSE;
88    }
89    bool IsInt() const
90    {
91        return type_ == BufferDataType::TYPE_INT;
92    }
93    bool IsLong() const
94    {
95        return type_ == BufferDataType::TYPE_LONG;
96    }
97    bool IsDouble() const
98    {
99        return type_ == BufferDataType::TYPE_DOUBLE;
100    }
101    bool IsString() const
102    {
103        return type_ == BufferDataType::TYPE_STRING;
104    }
105    bool IsMap() const
106    {
107        return type_ == BufferDataType::TYPE_MAP;
108    }
109    bool IsSet() const
110    {
111        return type_ == BufferDataType::TYPE_SET;
112    }
113    bool IsInt8Array() const
114    {
115        return type_ == BufferDataType::TYPE_INT8_ARRAY;
116    }
117    bool IsInt16Array() const
118    {
119        return type_ == BufferDataType::TYPE_INT16_ARRAY;
120    }
121    bool IsInt32Array() const
122    {
123        return type_ == BufferDataType::TYPE_INT32_ARRAY;
124    }
125
126    bool IsFunction() const
127    {
128        return type_ == BufferDataType::TYPE_FUNCTION;
129    }
130
131    bool IsObject() const
132    {
133        return type_ == BufferDataType::TYPE_OBJECT;
134    }
135
136    bool GetBoolValue(bool defValue = false) const
137    {
138        return (type_ == BufferDataType::TYPE_TRUE) ? true : (type_ == BufferDataType::TYPE_FALSE) ? false : defValue;
139    }
140    int32_t GetIntValue(int32_t defValue = 0) const
141    {
142        return IsInt() ? std::get<int32_t>(data_) : defValue;
143    }
144    int64_t GetLongValue(int64_t defValue = 0) const
145    {
146        return IsLong() ? std::get<int64_t>(data_) : IsInt() ? std::get<int32_t>(data_) : defValue;
147    }
148    double GetDoubleValue(double defValue = 0.0) const
149    {
150        return IsDouble() ? std::get<double>(data_)
151                          : IsLong() ? std::get<int64_t>(data_) : IsInt() ? std::get<int32_t>(data_) : defValue;
152    }
153
154    const std::string& GetStringValue() const
155    {
156        return GetValue<std::string>();
157    }
158    const std::map<std::string, std::string>& GetMapValue() const
159    {
160        return GetValue<std::map<std::string, std::string>>();
161    }
162    const std::set<std::string>& GetSetValue() const
163    {
164        return GetValue<std::set<std::string>>();
165    }
166    const std::vector<int8_t>& GetInt8ArrayValue() const
167    {
168        return GetValue<std::vector<int8_t>>();
169    }
170    const std::vector<int16_t>& GetInt16ArrayValue() const
171    {
172        return GetValue<std::vector<int16_t>>();
173    }
174    const std::vector<int32_t>& GetInt32ArrayValue() const
175    {
176        return GetValue<std::vector<int32_t>>();
177    }
178
179    int32_t GetFunctionValue(int32_t defValue = 0) const
180    {
181        return IsFunction() ? std::get<int32_t>(data_) : defValue;
182    }
183
184    const std::string& GetObjectValue() const
185    {
186        return GetValue<std::string>();
187    }
188
189private:
190    template<class T>
191    struct CopyableUniquePtr final {
192        CopyableUniquePtr() = default;
193        ~CopyableUniquePtr() = default;
194
195        CopyableUniquePtr(const CopyableUniquePtr& other) : ptr(std::make_unique<T>(*other.ptr)) {}
196        CopyableUniquePtr(CopyableUniquePtr&& other) = default;
197
198        CopyableUniquePtr& operator=(const CopyableUniquePtr& other)
199        {
200            ptr = std::make_unique<T>(*other.ptr);
201            return *this;
202        }
203        CopyableUniquePtr& operator=(CopyableUniquePtr&& other) = default;
204
205        CopyableUniquePtr(const T& data) : ptr(std::make_unique<T>(data)) {}
206        CopyableUniquePtr(T&& data) : ptr(std::make_unique<T>(std::move(data))) {}
207
208        std::unique_ptr<T> ptr;
209    };
210
211    using EncodedData = std::variant<int32_t, int64_t, double, CopyableUniquePtr<std::string>,
212        CopyableUniquePtr<std::map<std::string, std::string>>, CopyableUniquePtr<std::set<std::string>>,
213        CopyableUniquePtr<std::vector<int8_t>>, CopyableUniquePtr<std::vector<int16_t>>,
214        CopyableUniquePtr<std::vector<int32_t>>>;
215
216    template<class T>
217    const T& GetValue() const
218    {
219        auto val = std::get_if<CopyableUniquePtr<T>>(&data_);
220        if (val != nullptr) {
221            return *(val->ptr);
222        } else {
223            static T defData;
224            return defData;
225        }
226    }
227
228    BufferDataType type_ = BufferDataType::TYPE_NULL;
229    EncodedData data_;
230};
231
232} // namespace OHOS::Ace::Framework
233
234#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_CODEC_DATA_H
235