ValueConversions_h.template 10.1 KB
Newer Older
1 2
// This file is generated by ValueConversions_h.template.

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Copyright 2016 The Chromium Authors. All rights reserved.
// 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 {
20
    static std::unique_ptr<T> fromValue(protocol::Value* value, ErrorSupport* errors)
21
    {
22
        return T::fromValue(value, errors);
23 24
    }

25
    static std::unique_ptr<protocol::Value> toValue(T* value)
26
    {
27
        return value->toValue();
28 29
    }

30
    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<T>& value)
31
    {
32
        return value->toValue();
33 34 35 36 37
    }
};

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

47
    static std::unique_ptr<protocol::Value> toValue(bool value)
48 49 50 51 52 53 54
    {
        return FundamentalValue::create(value);
    }
};

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

64
    static std::unique_ptr<protocol::Value> toValue(int value)
65 66 67 68 69 70 71
    {
        return FundamentalValue::create(value);
    }
};

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

81
    static std::unique_ptr<protocol::Value> toValue(double value)
82 83 84 85 86 87 88
    {
        return FundamentalValue::create(value);
    }
};

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

98
    static std::unique_ptr<protocol::Value> toValue(const String& value)
99 100 101 102 103
    {
        return StringValue::create(value);
    }
};

104 105 106 107
template<>
struct ValueConversions<Binary> {
    static Binary fromValue(protocol::Value* value, ErrorSupport* errors)
    {
108 109
        if (!value ||
            (value->type() != Value::TypeBinary && value->type() != Value::TypeString)) {
110
            errors->AddError("Either string base64 or binary value expected");
111 112
            return Binary();
        }
113 114 115 116 117 118
        Binary binary;
        if (value->asBinary(&binary))
            return binary;
        String result;
        value->asString(&result);
        bool success;
119 120
        Binary out = Binary::fromBase64(result, &success);
        if (!success)
121
          errors->AddError("base64 decoding error");
122 123 124 125 126
        return out;
    }

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

131 132 133 134 135
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) {
136
            errors->AddError("array expected");
137 138
            return nullptr;
        }
139
        errors->Push();
140 141 142 143
        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) {
144
            errors->SetIndex(i);
145 146 147
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
148 149
        errors->Pop();
        if (!errors->Errors().empty())
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
            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) {
170
            errors->AddError("array expected");
171 172
            return nullptr;
        }
173
        errors->Push();
174 175 176
        std::unique_ptr<std::vector<T>> result(new std::vector<T>());
        result->reserve(array->size());
        for (size_t i = 0; i < array->size(); ++i) {
177
            errors->SetIndex(i);
178 179 180
            auto item = ValueConversions<T>::fromValue(array->at(i), errors);
            result->emplace_back(std::move(item));
        }
181 182
        errors->Pop();
        if (!errors->Errors().empty())
183 184 185 186 187 188 189 190 191 192 193 194 195 196
            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;
    }
};

197 198
template<>
struct ValueConversions<Value> {
199
    static std::unique_ptr<Value> fromValue(protocol::Value* value, ErrorSupport* errors)
200 201 202
    {
        bool success = !!value;
        if (!success) {
203
            errors->AddError("value expected");
204 205 206 207 208
            return nullptr;
        }
        return value->clone();
    }

209
    static std::unique_ptr<protocol::Value> toValue(Value* value)
210 211 212 213
    {
        return value->clone();
    }

214
    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<Value>& value)
215 216 217 218 219 220 221
    {
        return value->clone();
    }
};

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

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

235
    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<DictionaryValue>& value)
236 237 238 239 240 241 242
    {
        return value->clone();
    }
};

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

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

256
    static std::unique_ptr<protocol::Value> toValue(const std::unique_ptr<ListValue>& value)
257 258 259 260 261
    {
        return value->clone();
    }
};

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
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));
  }
};

277 278 279 280
{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
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}}

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