blob: 9648272a1f04121aa44490605438eacb5c02efad [file] [log] [blame]
// 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 BLIMP_HELIUM_SERIALIZABLE_STRUCT_H_
#define BLIMP_HELIUM_SERIALIZABLE_STRUCT_H_
#include <memory>
#include <vector>
#include "blimp/helium/blimp_helium_export.h"
#include "blimp/helium/serializable.h"
#include "blimp/helium/stream_helpers.h"
#include "blimp/helium/syncable.h"
#include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
namespace blimp {
namespace helium {
// SerializableStruct is a base class which manages registration, serialization,
// and deserialization of its contents. Optional values are not permitted;
// SerializableStructs are therefore emitted/parsed in their entirety.
//
// Example usage:
//
// struct MyStruct : public SerializableStruct {
// MyStruct() : some_str(this, "initial value!"), some_int(this) {}
// Field<std::string> some_str;
// Field<int> some_int;
// };
//
// MyStruct s;
// s.some_str.Set("foo");
// s.some_int.Set(123);
class BLIMP_HELIUM_EXPORT SerializableStruct : public Serializable {
public:
// Provides template type-agnostic methods to SerializableStruct.
class FieldBase : public Serializable {
public:
FieldBase();
~FieldBase();
void SetLocalUpdateCallback(const base::Closure& local_update_callback);
void RegisterWith(SerializableStruct* container);
private:
base::Closure local_update_callback_;
};
// Holds arbitrarily-typed Serializable values and registers itself with the
// SerializableStruct.
template <typename FieldType>
class Field : public FieldBase {
public:
Field() = delete;
explicit Field(SerializableStruct* changeset, const FieldType& value = {})
: value_(value) {
DCHECK(changeset);
RegisterWith(changeset);
}
~Field() {}
void Set(const FieldType& value);
const FieldType& operator()() const;
// Serializable implementation.
void Serialize(
google::protobuf::io::CodedOutputStream* output_stream) const override;
bool Parse(google::protobuf::io::CodedInputStream* input_stream) override;
private:
FieldType value_;
DISALLOW_COPY_AND_ASSIGN(Field);
};
SerializableStruct();
virtual ~SerializableStruct();
void SetLocalUpdateCallback(const base::Closure& local_update_callback);
// Serializable implementation.
void Serialize(
google::protobuf::io::CodedOutputStream* output_stream) const override;
bool Parse(google::protobuf::io::CodedInputStream* input_stream) override;
private:
friend class FieldBase;
std::vector<FieldBase*> fields_;
DISALLOW_COPY_AND_ASSIGN(SerializableStruct);
};
template <typename FieldType>
void SerializableStruct::Field<FieldType>::Set(const FieldType& value) {
value_ = value;
}
template <typename FieldType>
const FieldType& SerializableStruct::Field<FieldType>::operator()() const {
return value_;
}
template <typename FieldType>
void SerializableStruct::Field<FieldType>::Serialize(
google::protobuf::io::CodedOutputStream* output_stream) const {
DCHECK(output_stream);
WriteToStream(value_, output_stream);
}
template <typename FieldType>
bool SerializableStruct::Field<FieldType>::Parse(
google::protobuf::io::CodedInputStream* input_stream) {
DCHECK(input_stream);
return ReadFromStream(input_stream, &value_);
}
} // namespace helium
} // namespace blimp
#endif // BLIMP_HELIUM_SERIALIZABLE_STRUCT_H_