chromium/third_party/inspector_protocol/lib/ValueConversions_h.template

// This file is generated by ValueConversions_h.template.

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef {{"_".join(config.protocol.namespace)}}_ValueConversions_h
#define {{"_".join(config.protocol.namespace)}}_ValueConversions_h

//#include "ErrorSupport.h"
//#include "Forward.h"
//#include "Values.h"

{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
{% endfor %}

template<typename T>
struct ValueConversions {
    static std::unique_ptr<T> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        return T::fromValue(value, errors);
    }

    static std::unique_ptr<protocol::Value> toValue(T* value)
    {
        return value->toValue();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<T>& value)
    {
        return value->toValue();
    }
};

template<>
struct ValueConversions<bool> {
    static bool fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool result = false;
        bool success = value ? value->asBoolean(&result) : false;
        if (!success)
            errors->AddError("boolean value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(bool value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<int> {
    static int fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        int result = 0;
        bool success = value ? value->asInteger(&result) : false;
        if (!success)
            errors->AddError("integer value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(int value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<double> {
    static double fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        double result = 0;
        bool success = value ? value->asDouble(&result) : false;
        if (!success)
            errors->AddError("double value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(double value)
    {
        return FundamentalValue::create(value);
    }
};

template<>
struct ValueConversions<String> {
    static String fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        String result;
        bool success = value ? value->asString(&result) : false;
        if (!success)
            errors->AddError("string value expected");
        return result;
    }

    static std::unique_ptr<protocol::Value> toValue(const String& value)
    {
        return StringValue::create(value);
    }
};

template<>
struct ValueConversions<Binary> {
    static Binary fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        if (!value ||
            (value->type() != Value::TypeBinary && value->type() != Value::TypeString)) {
            errors->AddError("Either string base64 or binary value expected");
            return Binary();
        }
        Binary binary;
        if (value->asBinary(&binary))
            return binary;
        String result;
        value->asString(&result);
        bool success;
        Binary out = Binary::fromBase64(result, &success);
        if (!success)
          errors->AddError("base64 decoding error");
        return out;
    }

    static std::unique_ptr<protocol::Value> toValue(const Binary& value)
    {
        return BinaryValue::create(value);
    }
};

template<typename T>
struct ValueConversions<std::vector<std::unique_ptr<T>>> {
    static std::unique_ptr<std::vector<std::unique_ptr<T>>> fromValue(protocol::Value* value, ErrorSupport* errors) {
        protocol::ListValue* array = ListValue::cast(value);
        if (!array) {
            errors->AddError("array expected");
            return nullptr;
        }
        errors->Push();
        std::unique_ptr<std::vector<std::unique_ptr<T>>> result(
            new std::vector<std::unique_ptr<T>>());
        result->reserve(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            errors->SetIndex(i);
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
        errors->Pop();
        if (!errors->Errors().empty())
            return nullptr;
        return result;
    }

    static std::unique_ptr<protocol::ListValue> toValue(std::vector<std::unique_ptr<T>>* v)
    {
        std::unique_ptr<protocol::ListValue> result = ListValue::create();
        result->reserve(v->size());
        for (auto& item : *v)
            result->pushValue(ValueConversions<T>::toValue(item.get()));
        return result;
    }

};

template<typename T>
struct ValueConversions<std::vector<T>> {
    static std::unique_ptr<std::vector<T>> fromValue(protocol::Value* value, ErrorSupport* errors) {
        protocol::ListValue* array = ListValue::cast(value);
        if (!array) {
            errors->AddError("array expected");
            return nullptr;
        }
        errors->Push();
        std::unique_ptr<std::vector<T>> result(new std::vector<T>());
        result->reserve(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
            errors->SetIndex(i);
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
        errors->Pop();
        if (!errors->Errors().empty())
            return nullptr;
        return result;
    }

    static std::unique_ptr<protocol::ListValue> toValue(std::vector<T>* v)
    {
        std::unique_ptr<protocol::ListValue> result = ListValue::create();
        result->reserve(v->size());
        for (auto& item : *v)
            result->pushValue(ValueConversions<T>::toValue(item));
        return result;
    }
};

template<>
struct ValueConversions<Value> {
    static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = !!value;
        if (!success) {
            errors->AddError("value expected");
            return nullptr;
        }
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(Value* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<Value>& value)
    {
        return value->clone();
    }
};

template<>
struct ValueConversions<DictionaryValue> {
    static std::unique_ptr<DictionaryValue> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = value && value->type() == protocol::Value::TypeObject;
        if (!success)
            errors->AddError("object expected");
        return DictionaryValue::cast(value->clone());
    }

    static std::unique_ptr<protocol::Value> toValue(DictionaryValue* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<DictionaryValue>& value)
    {
        return value->clone();
    }
};

template<>
struct ValueConversions<ListValue> {
    static std::unique_ptr<ListValue> fromValue(protocol::Value* value, ErrorSupport* errors)
    {
        bool success = value && value->type() == protocol::Value::TypeArray;
        if (!success)
            errors->AddError("list expected");
        return ListValue::cast(value->clone());
    }

    static std::unique_ptr<protocol::Value> toValue(ListValue* value)
    {
        return value->clone();
    }

    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<ListValue>& value)
    {
        return value->clone();
    }
};

template<typename T> struct ValueTypeConverter {
  static std::unique_ptr<T> FromValue(const protocol::Value& value) {
    std::vector<uint8_t> bytes;
    value.AppendSerialized(&bytes);
    return T::FromBinary(bytes.data(), bytes.size());
  }

  static std::unique_ptr<protocol::DictionaryValue> ToValue(const T& obj) {
    std::vector<uint8_t> bytes;
    obj.AppendSerialized(&bytes);
    auto result = Value::parseBinary(bytes.data(), bytes.size());
    return DictionaryValue::cast(std::move(result));
  }
};

{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}

namespace {{config.crdtp.namespace}} {

template<typename T>
struct ProtocolTypeTraits<T,
     typename std::enable_if<std::is_base_of<{{"::".join(config.protocol.namespace)}}::Value, T>::value>::type> {
  static void Serialize(const {{"::".join(config.protocol.namespace)}}::Value& value, std::vector<uint8_t>* bytes) {
    value.AppendSerialized(bytes);
  }
};

template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Value>& value, std::vector<uint8_t>* bytes);
};

template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::DictionaryValue>& value, std::vector<uint8_t>* bytes);
};

// TODO(caseq): get rid of it, it's just a DictionaryValue really.
template <>
struct ProtocolTypeTraits<std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>> {
  static bool Deserialize(DeserializerState* state, std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>* value);
  static void Serialize(const std::unique_ptr<{{"::".join(config.protocol.namespace)}}::Object>& value, std::vector<uint8_t>* bytes);
};

template<>
struct ProtocolTypeTraits<{{"::".join(config.protocol.namespace)}}::Object> {
  static void Serialize(const {{"::".join(config.protocol.namespace)}}::Object& value, std::vector<uint8_t>* bytes) {
    value.AppendSerialized(bytes);
  }
};

}  // namespace {{config.crdtp.namespace}}

#endif // !defined({{"_".join(config.protocol.namespace)}}_ValueConversions_h)