* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_CODEC_DATA_H
#define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_CODEC_DATA_H
#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <variant>
#include <vector>
namespace OHOS::Ace::Framework {
enum class BufferDataType : uint8_t {
TYPE_NULL = 0x10,
TYPE_TRUE,
TYPE_FALSE,
TYPE_INT,
TYPE_LONG,
TYPE_DOUBLE,
TYPE_STRING,
TYPE_MAP,
TYPE_SET,
TYPE_INT8_ARRAY,
TYPE_INT16_ARRAY,
TYPE_INT32_ARRAY,
TYPE_FUNCTION,
TYPE_OBJECT,
};
class CodecData final {
public:
CodecData() = default;
~CodecData() = default;
CodecData(const CodecData& other) = default;
CodecData(CodecData&& other) = default;
CodecData& operator=(const CodecData& other) = default;
CodecData& operator=(CodecData&& other) = default;
explicit CodecData(bool val) : type_(val ? BufferDataType::TYPE_TRUE : BufferDataType::TYPE_FALSE) {}
explicit CodecData(int32_t val) : type_(BufferDataType::TYPE_INT), data_(val) {}
explicit CodecData(int32_t val, BufferDataType type) : type_(type), data_(val) {}
explicit CodecData(int64_t val) : type_(BufferDataType::TYPE_LONG), data_(val) {}
explicit CodecData(double val) : type_(BufferDataType::TYPE_DOUBLE), data_(val) {}
explicit CodecData(const std::string& val) : type_(BufferDataType::TYPE_STRING), data_(val) {}
explicit CodecData(const std::string& val, BufferDataType type) : type_(type), data_(val) {}
explicit CodecData(const std::map<std::string, std::string>& val) : type_(BufferDataType::TYPE_MAP), data_(val) {}
explicit CodecData(const std::set<std::string>& val) : type_(BufferDataType::TYPE_SET), data_(val) {}
explicit CodecData(const std::vector<int8_t>& val) : type_(BufferDataType::TYPE_INT8_ARRAY), data_(val) {}
explicit CodecData(const std::vector<int16_t>& val) : type_(BufferDataType::TYPE_INT16_ARRAY), data_(val) {}
explicit CodecData(const std::vector<int32_t>& val) : type_(BufferDataType::TYPE_INT32_ARRAY), data_(val) {}
explicit CodecData(std::string&& val) : type_(BufferDataType::TYPE_STRING), data_(std::move(val)) {}
explicit CodecData(std::map<std::string, std::string>&& val)
: type_(BufferDataType::TYPE_MAP), data_(std::move(val)) {}
explicit CodecData(std::set<std::string>&& val) : type_(BufferDataType::TYPE_SET), data_(std::move(val)) {}
explicit CodecData(std::vector<int8_t>&& val) : type_(BufferDataType::TYPE_INT8_ARRAY), data_(std::move(val)) {}
explicit CodecData(std::vector<int16_t>&& val) : type_(BufferDataType::TYPE_INT16_ARRAY), data_(std::move(val)) {}
explicit CodecData(std::vector<int32_t>&& val) : type_(BufferDataType::TYPE_INT32_ARRAY), data_(std::move(val)) {}
BufferDataType GetType() const
{
return type_;
}
bool IsNull() const
{
return type_ == BufferDataType::TYPE_NULL;
}
bool IsBool() const
{
return type_ == BufferDataType::TYPE_TRUE || type_ == BufferDataType::TYPE_FALSE;
}
bool IsInt() const
{
return type_ == BufferDataType::TYPE_INT;
}
bool IsLong() const
{
return type_ == BufferDataType::TYPE_LONG;
}
bool IsDouble() const
{
return type_ == BufferDataType::TYPE_DOUBLE;
}
bool IsString() const
{
return type_ == BufferDataType::TYPE_STRING;
}
bool IsMap() const
{
return type_ == BufferDataType::TYPE_MAP;
}
bool IsSet() const
{
return type_ == BufferDataType::TYPE_SET;
}
bool IsInt8Array() const
{
return type_ == BufferDataType::TYPE_INT8_ARRAY;
}
bool IsInt16Array() const
{
return type_ == BufferDataType::TYPE_INT16_ARRAY;
}
bool IsInt32Array() const
{
return type_ == BufferDataType::TYPE_INT32_ARRAY;
}
bool IsFunction() const
{
return type_ == BufferDataType::TYPE_FUNCTION;
}
bool IsObject() const
{
return type_ == BufferDataType::TYPE_OBJECT;
}
bool GetBoolValue(bool defValue = false) const
{
return (type_ == BufferDataType::TYPE_TRUE) ? true : (type_ == BufferDataType::TYPE_FALSE) ? false : defValue;
}
int32_t GetIntValue(int32_t defValue = 0) const
{
return IsInt() ? std::get<int32_t>(data_) : defValue;
}
int64_t GetLongValue(int64_t defValue = 0) const
{
return IsLong() ? std::get<int64_t>(data_) : IsInt() ? std::get<int32_t>(data_) : defValue;
}
double GetDoubleValue(double defValue = 0.0) const
{
return IsDouble() ? std::get<double>(data_)
: IsLong() ? std::get<int64_t>(data_) : IsInt() ? std::get<int32_t>(data_) : defValue;
}
const std::string& GetStringValue() const
{
return GetValue<std::string>();
}
const std::map<std::string, std::string>& GetMapValue() const
{
return GetValue<std::map<std::string, std::string>>();
}
const std::set<std::string>& GetSetValue() const
{
return GetValue<std::set<std::string>>();
}
const std::vector<int8_t>& GetInt8ArrayValue() const
{
return GetValue<std::vector<int8_t>>();
}
const std::vector<int16_t>& GetInt16ArrayValue() const
{
return GetValue<std::vector<int16_t>>();
}
const std::vector<int32_t>& GetInt32ArrayValue() const
{
return GetValue<std::vector<int32_t>>();
}
int32_t GetFunctionValue(int32_t defValue = 0) const
{
return IsFunction() ? std::get<int32_t>(data_) : defValue;
}
const std::string& GetObjectValue() const
{
return GetValue<std::string>();
}
private:
template<class T>
struct CopyableUniquePtr final {
CopyableUniquePtr() = default;
~CopyableUniquePtr() = default;
CopyableUniquePtr(const CopyableUniquePtr& other) : ptr(std::make_unique<T>(*other.ptr)) {}
CopyableUniquePtr(CopyableUniquePtr&& other) = default;
CopyableUniquePtr& operator=(const CopyableUniquePtr& other)
{
ptr = std::make_unique<T>(*other.ptr);
return *this;
}
CopyableUniquePtr& operator=(CopyableUniquePtr&& other) = default;
CopyableUniquePtr(const T& data) : ptr(std::make_unique<T>(data)) {}
CopyableUniquePtr(T&& data) : ptr(std::make_unique<T>(std::move(data))) {}
std::unique_ptr<T> ptr;
};
using EncodedData = std::variant<int32_t, int64_t, double, CopyableUniquePtr<std::string>,
CopyableUniquePtr<std::map<std::string, std::string>>, CopyableUniquePtr<std::set<std::string>>,
CopyableUniquePtr<std::vector<int8_t>>, CopyableUniquePtr<std::vector<int16_t>>,
CopyableUniquePtr<std::vector<int32_t>>>;
template<class T>
const T& GetValue() const
{
auto val = std::get_if<CopyableUniquePtr<T>>(&data_);
if (val != nullptr) {
return *(val->ptr);
} else {
static T defData;
return defData;
}
}
BufferDataType type_ = BufferDataType::TYPE_NULL;
EncodedData data_;
};
}
#endif