|
@@ -19,10 +19,10 @@
|
|
|
#ifndef avro_GenericDatum_hh__
|
|
|
#define avro_GenericDatum_hh__
|
|
|
|
|
|
-#include <stdint.h>
|
|
|
-#include <vector>
|
|
|
+#include <cstdint>
|
|
|
#include <map>
|
|
|
#include <string>
|
|
|
+#include <vector>
|
|
|
|
|
|
#if __cplusplus >= 201703L
|
|
|
#include <any>
|
|
@@ -54,7 +54,7 @@ namespace avro {
|
|
|
* \li Avro <tt>array</tt> maps to C++ class <tt>GenericArray</tt>.
|
|
|
* \li Avro <tt>map</tt> maps to C++ class <tt>GenericMap</tt>.
|
|
|
* \li There is no C++ type corresponding to Avro <tt>union</tt>. The
|
|
|
- * object should have the C++ type corresponing to one of the constituent
|
|
|
+ * object should have the C++ type corresponding to one of the constituent
|
|
|
* types of the union.
|
|
|
*
|
|
|
*/
|
|
@@ -68,17 +68,18 @@ protected:
|
|
|
boost::any value_;
|
|
|
#endif
|
|
|
|
|
|
- GenericDatum(Type t)
|
|
|
- : type_(t), logicalType_(LogicalType::NONE) { }
|
|
|
+ explicit GenericDatum(Type t)
|
|
|
+ : type_(t), logicalType_(LogicalType::NONE) {}
|
|
|
|
|
|
GenericDatum(Type t, LogicalType logicalType)
|
|
|
- : type_(t), logicalType_(logicalType) { }
|
|
|
+ : type_(t), logicalType_(logicalType) {}
|
|
|
+
|
|
|
+ template<typename T>
|
|
|
+ GenericDatum(Type t, LogicalType logicalType, const T &v)
|
|
|
+ : type_(t), logicalType_(logicalType), value_(v) {}
|
|
|
|
|
|
- template <typename T>
|
|
|
- GenericDatum(Type t, LogicalType logicalType, const T& v)
|
|
|
- : type_(t), logicalType_(logicalType), value_(v) { }
|
|
|
+ void init(const NodePtr &schema);
|
|
|
|
|
|
- void init(const NodePtr& schema);
|
|
|
public:
|
|
|
/**
|
|
|
* The avro data type this datum holds.
|
|
@@ -95,7 +96,8 @@ public:
|
|
|
* T The type for the value. This must correspond to the
|
|
|
* avro type returned by type().
|
|
|
*/
|
|
|
- template<typename T> const T& value() const;
|
|
|
+ template<typename T>
|
|
|
+ const T &value() const;
|
|
|
|
|
|
/**
|
|
|
* Returns the reference to the value held by this datum, which
|
|
@@ -106,7 +108,8 @@ public:
|
|
|
* T The type for the value. This must correspond to the
|
|
|
* avro type returned by type().
|
|
|
*/
|
|
|
- template<typename T> T& value();
|
|
|
+ template<typename T>
|
|
|
+ T &value();
|
|
|
|
|
|
/**
|
|
|
* Returns true if and only if this datum is a union.
|
|
@@ -126,36 +129,49 @@ public:
|
|
|
void selectBranch(size_t branch);
|
|
|
|
|
|
/// Makes a new AVRO_NULL datum.
|
|
|
- GenericDatum() : type_(AVRO_NULL), logicalType_(LogicalType::NONE) { }
|
|
|
+ GenericDatum() : type_(AVRO_NULL), logicalType_(LogicalType::NONE) {}
|
|
|
|
|
|
/// Makes a new AVRO_BOOL datum whose value is of type bool.
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
GenericDatum(bool v)
|
|
|
- : type_(AVRO_BOOL), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ : type_(AVRO_BOOL), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_INT datum whose value is of type int32_t.
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
GenericDatum(int32_t v)
|
|
|
- : type_(AVRO_INT), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ : type_(AVRO_INT), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_LONG datum whose value is of type int64_t.
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
GenericDatum(int64_t v)
|
|
|
- : type_(AVRO_LONG), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ : type_(AVRO_LONG), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_FLOAT datum whose value is of type float.
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
GenericDatum(float v)
|
|
|
- : type_(AVRO_FLOAT), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ : type_(AVRO_FLOAT), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_DOUBLE datum whose value is of type double.
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
GenericDatum(double v)
|
|
|
- : type_(AVRO_DOUBLE), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ : type_(AVRO_DOUBLE), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_STRING datum whose value is of type std::string.
|
|
|
- GenericDatum(const std::string& v)
|
|
|
- : type_(AVRO_STRING), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
+ GenericDatum(const std::string &v)
|
|
|
+ : type_(AVRO_STRING), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/// Makes a new AVRO_BYTES datum whose value is of type
|
|
|
/// std::vector<uint8_t>.
|
|
|
- GenericDatum(const std::vector<uint8_t>& v) :
|
|
|
- type_(AVRO_BYTES), logicalType_(LogicalType::NONE), value_(v) { }
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
+ GenericDatum(const std::vector<uint8_t> &v) : type_(AVRO_BYTES), logicalType_(LogicalType::NONE), value_(v) {}
|
|
|
|
|
|
/**
|
|
|
* Constructs a datum corresponding to the given avro type.
|
|
@@ -163,7 +179,9 @@ public:
|
|
|
* data type.
|
|
|
* \param schema The schema that defines the avro type.
|
|
|
*/
|
|
|
- GenericDatum(const NodePtr& schema);
|
|
|
+ /// We don't make this explicit constructor because we want to allow automatic conversion
|
|
|
+ // NOLINTNEXTLINE(google-explicit-constructor)
|
|
|
+ GenericDatum(const NodePtr &schema);
|
|
|
|
|
|
/**
|
|
|
* Constructs a datum corresponding to the given avro type and set
|
|
@@ -172,8 +190,7 @@ public:
|
|
|
* \param v The value for this type.
|
|
|
*/
|
|
|
template<typename T>
|
|
|
- GenericDatum(const NodePtr& schema, const T& v) :
|
|
|
- type_(schema->type()), logicalType_(schema->logicalType()) {
|
|
|
+ GenericDatum(const NodePtr &schema, const T &v) : type_(schema->type()), logicalType_(schema->logicalType()) {
|
|
|
init(schema);
|
|
|
#if __cplusplus >= 201703L
|
|
|
*std::any_cast<T>(&value_) = v;
|
|
@@ -188,7 +205,7 @@ public:
|
|
|
* data type.
|
|
|
* \param schema The schema that defines the avro type.
|
|
|
*/
|
|
|
- GenericDatum(const ValidSchema& schema);
|
|
|
+ explicit GenericDatum(const ValidSchema &schema);
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -196,18 +213,19 @@ public:
|
|
|
*/
|
|
|
class AVRO_DECL GenericContainer {
|
|
|
NodePtr schema_;
|
|
|
- static void assertType(const NodePtr& schema, Type type);
|
|
|
+ static void assertType(const NodePtr &schema, Type type);
|
|
|
+
|
|
|
protected:
|
|
|
/**
|
|
|
* Constructs a container corresponding to the given schema.
|
|
|
*/
|
|
|
- GenericContainer(Type type, const NodePtr& s) : schema_(s) {
|
|
|
+ GenericContainer(Type type, const NodePtr &s) : schema_(s) {
|
|
|
assertType(s, type);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
/// Returns the schema for this object
|
|
|
- const NodePtr& schema() const {
|
|
|
+ const NodePtr &schema() const {
|
|
|
return schema_;
|
|
|
}
|
|
|
};
|
|
@@ -225,8 +243,7 @@ public:
|
|
|
* and the given value. The schema should be of Avro type union
|
|
|
* and the value should correspond to one of the branches of the union.
|
|
|
*/
|
|
|
- GenericUnion(const NodePtr& schema) :
|
|
|
- GenericContainer(AVRO_UNION, schema), curBranch_(schema->leaves()) {
|
|
|
+ explicit GenericUnion(const NodePtr &schema) : GenericContainer(AVRO_UNION, schema), curBranch_(schema->leaves()) {
|
|
|
selectBranch(0);
|
|
|
}
|
|
|
|
|
@@ -250,7 +267,7 @@ public:
|
|
|
* Returns the datum corresponding to the currently selected branch
|
|
|
* in this union.
|
|
|
*/
|
|
|
- GenericDatum& datum() {
|
|
|
+ GenericDatum &datum() {
|
|
|
return datum_;
|
|
|
}
|
|
|
|
|
@@ -258,7 +275,7 @@ public:
|
|
|
* Returns the datum corresponding to the currently selected branch
|
|
|
* in this union.
|
|
|
*/
|
|
|
- const GenericDatum& datum() const {
|
|
|
+ const GenericDatum &datum() const {
|
|
|
return datum_;
|
|
|
}
|
|
|
};
|
|
@@ -268,12 +285,13 @@ public:
|
|
|
*/
|
|
|
class AVRO_DECL GenericRecord : public GenericContainer {
|
|
|
std::vector<GenericDatum> fields_;
|
|
|
+
|
|
|
public:
|
|
|
/**
|
|
|
* Constructs a generic record corresponding to the given schema \p schema,
|
|
|
* which should be of Avro type record.
|
|
|
*/
|
|
|
- GenericRecord(const NodePtr& schema);
|
|
|
+ explicit GenericRecord(const NodePtr &schema);
|
|
|
|
|
|
/**
|
|
|
* Returns the number of fields in the current record.
|
|
@@ -285,7 +303,7 @@ public:
|
|
|
/**
|
|
|
* Returns index of the field with the given name \p name
|
|
|
*/
|
|
|
- size_t fieldIndex(const std::string& name) const {
|
|
|
+ size_t fieldIndex(const std::string &name) const {
|
|
|
size_t index = 0;
|
|
|
if (!schema()->nameIndex(name, index)) {
|
|
|
throw Exception("Invalid field name: " + name);
|
|
@@ -297,7 +315,7 @@ public:
|
|
|
* Returns true if a field with the given name \p name is located in this r
|
|
|
* false otherwise
|
|
|
*/
|
|
|
- bool hasField(const std::string& name) const {
|
|
|
+ bool hasField(const std::string &name) const {
|
|
|
size_t index = 0;
|
|
|
return schema()->nameIndex(name, index);
|
|
|
}
|
|
@@ -305,7 +323,7 @@ public:
|
|
|
/**
|
|
|
* Returns the field with the given name \p name.
|
|
|
*/
|
|
|
- const GenericDatum& field(const std::string& name) const {
|
|
|
+ const GenericDatum &field(const std::string &name) const {
|
|
|
return fieldAt(fieldIndex(name));
|
|
|
}
|
|
|
|
|
@@ -313,14 +331,14 @@ public:
|
|
|
* Returns the reference to the field with the given name \p name,
|
|
|
* which can be used to change the contents.
|
|
|
*/
|
|
|
- GenericDatum& field(const std::string& name) {
|
|
|
+ GenericDatum &field(const std::string &name) {
|
|
|
return fieldAt(fieldIndex(name));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the field at the given position \p pos.
|
|
|
*/
|
|
|
- const GenericDatum& fieldAt(size_t pos) const {
|
|
|
+ const GenericDatum &fieldAt(size_t pos) const {
|
|
|
return fields_[pos];
|
|
|
}
|
|
|
|
|
@@ -328,14 +346,14 @@ public:
|
|
|
* Returns the reference to the field at the given position \p pos,
|
|
|
* which can be used to change the contents.
|
|
|
*/
|
|
|
- GenericDatum& fieldAt(size_t pos) {
|
|
|
+ GenericDatum &fieldAt(size_t pos) {
|
|
|
return fields_[pos];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Replaces the field at the given position \p pos with \p v.
|
|
|
*/
|
|
|
- void setFieldAt(size_t pos, const GenericDatum& v) {
|
|
|
+ void setFieldAt(size_t pos, const GenericDatum &v) {
|
|
|
// assertSameType(v, schema()->leafAt(pos));
|
|
|
fields_[pos] = v;
|
|
|
}
|
|
@@ -355,22 +373,23 @@ public:
|
|
|
* Constructs a generic array corresponding to the given schema \p schema,
|
|
|
* which should be of Avro type array.
|
|
|
*/
|
|
|
- GenericArray(const NodePtr& schema) : GenericContainer(AVRO_ARRAY, schema) {
|
|
|
+ explicit GenericArray(const NodePtr &schema) : GenericContainer(AVRO_ARRAY, schema) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the contents of this array.
|
|
|
*/
|
|
|
- const Value& value() const {
|
|
|
+ const Value &value() const {
|
|
|
return value_;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the reference to the contents of this array.
|
|
|
*/
|
|
|
- Value& value() {
|
|
|
+ Value &value() {
|
|
|
return value_;
|
|
|
}
|
|
|
+
|
|
|
private:
|
|
|
Value value_;
|
|
|
};
|
|
@@ -383,28 +402,29 @@ public:
|
|
|
/**
|
|
|
* The contents type for the map.
|
|
|
*/
|
|
|
- typedef std::vector<std::pair<std::string, GenericDatum> > Value;
|
|
|
+ typedef std::vector<std::pair<std::string, GenericDatum>> Value;
|
|
|
|
|
|
/**
|
|
|
* Constructs a generic map corresponding to the given schema \p schema,
|
|
|
* which should be of Avro type map.
|
|
|
*/
|
|
|
- GenericMap(const NodePtr& schema) : GenericContainer(AVRO_MAP, schema) {
|
|
|
+ explicit GenericMap(const NodePtr &schema) : GenericContainer(AVRO_MAP, schema) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the contents of this map.
|
|
|
*/
|
|
|
- const Value& value() const {
|
|
|
+ const Value &value() const {
|
|
|
return value_;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the reference to the contents of this map.
|
|
|
*/
|
|
|
- Value& value() {
|
|
|
+ Value &value() {
|
|
|
return value_;
|
|
|
}
|
|
|
+
|
|
|
private:
|
|
|
Value value_;
|
|
|
};
|
|
@@ -415,7 +435,7 @@ private:
|
|
|
class AVRO_DECL GenericEnum : public GenericContainer {
|
|
|
size_t value_;
|
|
|
|
|
|
- static size_t index(const NodePtr& schema, const std::string& symbol) {
|
|
|
+ static size_t index(const NodePtr &schema, const std::string &symbol) {
|
|
|
size_t result;
|
|
|
if (schema->nameIndex(symbol, result)) {
|
|
|
return result;
|
|
@@ -428,19 +448,17 @@ public:
|
|
|
* Constructs a generic enum corresponding to the given schema \p schema,
|
|
|
* which should be of Avro type enum.
|
|
|
*/
|
|
|
- GenericEnum(const NodePtr& schema) :
|
|
|
- GenericContainer(AVRO_ENUM, schema), value_(0) {
|
|
|
+ explicit GenericEnum(const NodePtr &schema) : GenericContainer(AVRO_ENUM, schema), value_(0) {
|
|
|
}
|
|
|
|
|
|
- GenericEnum(const NodePtr& schema, const std::string& symbol) :
|
|
|
- GenericContainer(AVRO_ENUM, schema), value_(index(schema, symbol)) {
|
|
|
+ GenericEnum(const NodePtr &schema, const std::string &symbol) : GenericContainer(AVRO_ENUM, schema), value_(index(schema, symbol)) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the symbol corresponding to the cardinal \p n. If the
|
|
|
* value for \p n is not within the limits an exception is thrown.
|
|
|
*/
|
|
|
- const std::string& symbol(size_t n) {
|
|
|
+ const std::string &symbol(size_t n) {
|
|
|
if (n < schema()->names()) {
|
|
|
return schema()->nameAt(n);
|
|
|
}
|
|
@@ -451,14 +469,14 @@ public:
|
|
|
* Returns the cardinal for the given symbol \c symbol. If the symbol
|
|
|
* is not defined for this enum and exception is thrown.
|
|
|
*/
|
|
|
- size_t index(const std::string& symbol) const {
|
|
|
+ size_t index(const std::string &symbol) const {
|
|
|
return index(schema(), symbol);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Set the value for this enum corresponding to the given symbol \c symbol.
|
|
|
*/
|
|
|
- size_t set(const std::string& symbol) {
|
|
|
+ size_t set(const std::string &symbol) {
|
|
|
return value_ = index(symbol);
|
|
|
}
|
|
|
|
|
@@ -483,7 +501,7 @@ public:
|
|
|
/**
|
|
|
* Returns the symbol for the current value of this enum.
|
|
|
*/
|
|
|
- const std::string& symbol() const {
|
|
|
+ const std::string &symbol() const {
|
|
|
return schema()->nameAt(value_);
|
|
|
}
|
|
|
};
|
|
@@ -493,29 +511,29 @@ public:
|
|
|
*/
|
|
|
class AVRO_DECL GenericFixed : public GenericContainer {
|
|
|
std::vector<uint8_t> value_;
|
|
|
+
|
|
|
public:
|
|
|
/**
|
|
|
* Constructs a generic enum corresponding to the given schema \p schema,
|
|
|
* which should be of Avro type fixed.
|
|
|
*/
|
|
|
- GenericFixed(const NodePtr& schema) : GenericContainer(AVRO_FIXED, schema) {
|
|
|
+ explicit GenericFixed(const NodePtr &schema) : GenericContainer(AVRO_FIXED, schema) {
|
|
|
value_.resize(schema->fixedSize());
|
|
|
}
|
|
|
|
|
|
- GenericFixed(const NodePtr& schema, const std::vector<uint8_t>& v) :
|
|
|
- GenericContainer(AVRO_FIXED, schema), value_(v) { }
|
|
|
+ GenericFixed(const NodePtr &schema, const std::vector<uint8_t> &v);
|
|
|
|
|
|
/**
|
|
|
* Returns the contents of this fixed.
|
|
|
*/
|
|
|
- const std::vector<uint8_t>& value() const {
|
|
|
+ const std::vector<uint8_t> &value() const {
|
|
|
return value_;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the reference to the contents of this fixed.
|
|
|
*/
|
|
|
- std::vector<uint8_t>& value() {
|
|
|
+ std::vector<uint8_t> &value() {
|
|
|
return value_;
|
|
|
}
|
|
|
};
|
|
@@ -523,36 +541,46 @@ public:
|
|
|
inline Type GenericDatum::type() const {
|
|
|
return (type_ == AVRO_UNION) ?
|
|
|
#if __cplusplus >= 201703L
|
|
|
- std::any_cast<GenericUnion>(&value_)->datum().type() :
|
|
|
+ std::any_cast<GenericUnion>(&value_)->datum().type()
|
|
|
+ :
|
|
|
#else
|
|
|
- boost::any_cast<GenericUnion>(&value_)->datum().type() :
|
|
|
+ boost::any_cast<GenericUnion>(&value_)->datum().type()
|
|
|
+ :
|
|
|
#endif
|
|
|
- type_;
|
|
|
+ type_;
|
|
|
}
|
|
|
|
|
|
inline LogicalType GenericDatum::logicalType() const {
|
|
|
- return logicalType_;
|
|
|
+ return (type_ == AVRO_UNION) ?
|
|
|
+#if __cplusplus >= 201703L
|
|
|
+ std::any_cast<GenericUnion>(&value_)->datum().logicalType() :
|
|
|
+#else
|
|
|
+ boost::any_cast<GenericUnion>(&value_)->datum().logicalType() :
|
|
|
+#endif
|
|
|
+ logicalType_;
|
|
|
}
|
|
|
|
|
|
-template<typename T> T& GenericDatum::value() {
|
|
|
+template<typename T>
|
|
|
+T &GenericDatum::value() {
|
|
|
return (type_ == AVRO_UNION) ?
|
|
|
#if __cplusplus >= 201703L
|
|
|
- std::any_cast<GenericUnion>(&value_)->datum().value<T>() :
|
|
|
- *std::any_cast<T>(&value_);
|
|
|
+ std::any_cast<GenericUnion>(&value_)->datum().value<T>()
|
|
|
+ : *std::any_cast<T>(&value_);
|
|
|
#else
|
|
|
- boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
|
|
|
- *boost::any_cast<T>(&value_);
|
|
|
+ boost::any_cast<GenericUnion>(&value_)->datum().value<T>()
|
|
|
+ : *boost::any_cast<T>(&value_);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-template<typename T> const T& GenericDatum::value() const {
|
|
|
+template<typename T>
|
|
|
+const T &GenericDatum::value() const {
|
|
|
return (type_ == AVRO_UNION) ?
|
|
|
#if __cplusplus >= 201703L
|
|
|
- std::any_cast<GenericUnion>(&value_)->datum().value<T>() :
|
|
|
- *std::any_cast<T>(&value_);
|
|
|
+ std::any_cast<GenericUnion>(&value_)->datum().value<T>()
|
|
|
+ : *std::any_cast<T>(&value_);
|
|
|
#else
|
|
|
- boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
|
|
|
- *boost::any_cast<T>(&value_);
|
|
|
+ boost::any_cast<GenericUnion>(&value_)->datum().value<T>()
|
|
|
+ : *boost::any_cast<T>(&value_);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -572,5 +600,5 @@ inline void GenericDatum::selectBranch(size_t branch) {
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-} // namespace avro
|
|
|
+} // namespace avro
|
|
|
#endif // avro_GenericDatum_hh__
|