aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/apache/avro/api/GenericDatum.hh
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.ru>2022-02-10 16:45:08 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:08 +0300
commit4e839db24a3bbc9f1c610c43d6faaaa99824dcca (patch)
tree506dac10f5df94fab310584ee51b24fc5a081c22 /contrib/libs/apache/avro/api/GenericDatum.hh
parent2d37894b1b037cf24231090eda8589bbb44fb6fc (diff)
downloadydb-4e839db24a3bbc9f1c610c43d6faaaa99824dcca.tar.gz
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/apache/avro/api/GenericDatum.hh')
-rw-r--r--contrib/libs/apache/avro/api/GenericDatum.hh1152
1 files changed, 576 insertions, 576 deletions
diff --git a/contrib/libs/apache/avro/api/GenericDatum.hh b/contrib/libs/apache/avro/api/GenericDatum.hh
index ac0e5e5e20..15cd53becb 100644
--- a/contrib/libs/apache/avro/api/GenericDatum.hh
+++ b/contrib/libs/apache/avro/api/GenericDatum.hh
@@ -1,576 +1,576 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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
- *
- * https://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 avro_GenericDatum_hh__
-#define avro_GenericDatum_hh__
-
-#include <stdint.h>
-#include <vector>
-#include <map>
-#include <string>
-
-#if __cplusplus >= 201703L
-#include <any>
-#else
-#include "boost/any.hpp"
-#endif
-
-#include "LogicalType.hh"
-#include "Node.hh"
-#include "ValidSchema.hh"
-
-namespace avro {
-
-/**
- * Generic datum which can hold any Avro type. The datum has a type
- * and a value. The type is one of the Avro data types. The C++ type for
- * value corresponds to the Avro type.
- * \li An Avro <tt>null</tt> corresponds to no C++ type. It is illegal to
- * to try to access values for <tt>null</tt>.
- * \li Avro <tt>boolean</tt> maps to C++ <tt>bool</tt>
- * \li Avro <tt>int</tt> maps to C++ <tt>int32_t</tt>.
- * \li Avro <tt>long</tt> maps to C++ <tt>int64_t</tt>.
- * \li Avro <tt>float</tt> maps to C++ <tt>float</tt>.
- * \li Avro <tt>double</tt> maps to C++ <tt>double</tt>.
- * \li Avro <tt>string</tt> maps to C++ <tt>std::string</tt>.
- * \li Avro <tt>bytes</tt> maps to C++ <tt>std::vector&lt;uint_t&gt;</tt>.
- * \li Avro <tt>fixed</tt> maps to C++ class <tt>GenericFixed</tt>.
- * \li Avro <tt>enum</tt> maps to C++ class <tt>GenericEnum</tt>.
- * \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
- * types of the union.
- *
- */
-class AVRO_DECL GenericDatum {
-protected:
- Type type_;
- LogicalType logicalType_;
-#if __cplusplus >= 201703L
- std::any value_;
-#else
- boost::any value_;
-#endif
-
- GenericDatum(Type t)
- : type_(t), logicalType_(LogicalType::NONE) { }
-
- GenericDatum(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) { }
-
- void init(const NodePtr& schema);
-public:
- /**
- * The avro data type this datum holds.
- */
- Type type() const;
-
- /**
- * The avro logical type that augments the main data type this datum holds.
- */
- LogicalType logicalType() const;
-
- /**
- * Returns the value held by this datum.
- * T The type for the value. This must correspond to the
- * avro type returned by type().
- */
- template<typename T> const T& value() const;
-
- /**
- * Returns the reference to the value held by this datum, which
- * can be used to change the contents. Please note that only
- * value can be changed, the data type of the value held cannot
- * be changed.
- *
- * T The type for the value. This must correspond to the
- * avro type returned by type().
- */
- template<typename T> T& value();
-
- /**
- * Returns true if and only if this datum is a union.
- */
- bool isUnion() const { return type_ == AVRO_UNION; }
-
- /**
- * Returns the index of the current branch, if this is a union.
- * \sa isUnion().
- */
- size_t unionBranch() const;
-
- /**
- * Selects a new branch in the union if this is a union.
- * \sa isUnion().
- */
- void selectBranch(size_t branch);
-
- /// Makes a new AVRO_NULL datum.
- GenericDatum() : type_(AVRO_NULL), logicalType_(LogicalType::NONE) { }
-
- /// Makes a new AVRO_BOOL datum whose value is of type bool.
- GenericDatum(bool v)
- : type_(AVRO_BOOL), logicalType_(LogicalType::NONE), value_(v) { }
-
- /// Makes a new AVRO_INT datum whose value is of type int32_t.
- GenericDatum(int32_t v)
- : type_(AVRO_INT), logicalType_(LogicalType::NONE), value_(v) { }
-
- /// Makes a new AVRO_LONG datum whose value is of type int64_t.
- GenericDatum(int64_t v)
- : type_(AVRO_LONG), logicalType_(LogicalType::NONE), value_(v) { }
-
- /// Makes a new AVRO_FLOAT datum whose value is of type float.
- GenericDatum(float v)
- : type_(AVRO_FLOAT), logicalType_(LogicalType::NONE), value_(v) { }
-
- /// Makes a new AVRO_DOUBLE datum whose value is of type double.
- GenericDatum(double 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) { }
-
- /// 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) { }
-
- /**
- * Constructs a datum corresponding to the given avro type.
- * The value will the appropriate default corresponding to the
- * data type.
- * \param schema The schema that defines the avro type.
- */
- GenericDatum(const NodePtr& schema);
-
- /**
- * Constructs a datum corresponding to the given avro type and set
- * the value.
- * \param schema The schema that defines the avro type.
- * \param v The value for this type.
- */
- template<typename T>
- GenericDatum(const NodePtr& schema, const T& v) :
- type_(schema->type()), logicalType_(schema->logicalType()) {
- init(schema);
-#if __cplusplus >= 201703L
- *std::any_cast<T>(&value_) = v;
-#else
- *boost::any_cast<T>(&value_) = v;
-#endif
- }
-
- /**
- * Constructs a datum corresponding to the given avro type.
- * The value will the appropriate default corresponding to the
- * data type.
- * \param schema The schema that defines the avro type.
- */
- GenericDatum(const ValidSchema& schema);
-};
-
-/**
- * The base class for all generic type for containers.
- */
-class AVRO_DECL GenericContainer {
- NodePtr schema_;
- 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) {
- assertType(s, type);
- }
-
-public:
- /// Returns the schema for this object
- const NodePtr& schema() const {
- return schema_;
- }
-};
-
-/**
- * Generic container for unions.
- */
-class AVRO_DECL GenericUnion : public GenericContainer {
- size_t curBranch_;
- GenericDatum datum_;
-
-public:
- /**
- * Constructs a generic union corresponding to the given schema \p schema,
- * 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()) {
- selectBranch(0);
- }
-
- /**
- * Returns the index of the current branch.
- */
- size_t currentBranch() const { return curBranch_; }
-
- /**
- * Selects a new branch. The type for the value is changed accordingly.
- * \param branch The index for the selected branch.
- */
- void selectBranch(size_t branch) {
- if (curBranch_ != branch) {
- datum_ = GenericDatum(schema()->leafAt(branch));
- curBranch_ = branch;
- }
- }
-
- /**
- * Returns the datum corresponding to the currently selected branch
- * in this union.
- */
- GenericDatum& datum() {
- return datum_;
- }
-
- /**
- * Returns the datum corresponding to the currently selected branch
- * in this union.
- */
- const GenericDatum& datum() const {
- return datum_;
- }
-};
-
-/**
- * The generic container for Avro records.
- */
-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);
-
- /**
- * Returns the number of fields in the current record.
- */
- size_t fieldCount() const {
- return fields_.size();
- }
-
- /**
- * Returns index of the field with the given name \p name
- */
- size_t fieldIndex(const std::string& name) const {
- size_t index = 0;
- if (!schema()->nameIndex(name, index)) {
- throw Exception("Invalid field name: " + name);
- }
- return index;
- }
-
- /**
- * 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 {
- size_t index = 0;
- return schema()->nameIndex(name, index);
- }
-
- /**
- * Returns the field with the given name \p name.
- */
- const GenericDatum& field(const std::string& name) const {
- return fieldAt(fieldIndex(name));
- }
-
- /**
- * 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) {
- return fieldAt(fieldIndex(name));
- }
-
- /**
- * Returns the field at the given position \p pos.
- */
- const GenericDatum& fieldAt(size_t pos) const {
- return fields_[pos];
- }
-
- /**
- * 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) {
- return fields_[pos];
- }
-
- /**
- * Replaces the field at the given position \p pos with \p v.
- */
- void setFieldAt(size_t pos, const GenericDatum& v) {
- // assertSameType(v, schema()->leafAt(pos));
- fields_[pos] = v;
- }
-};
-
-/**
- * The generic container for Avro arrays.
- */
-class AVRO_DECL GenericArray : public GenericContainer {
-public:
- /**
- * The contents type for the array.
- */
- typedef std::vector<GenericDatum> Value;
-
- /**
- * 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) {
- }
-
- /**
- * Returns the contents of this array.
- */
- const Value& value() const {
- return value_;
- }
-
- /**
- * Returns the reference to the contents of this array.
- */
- Value& value() {
- return value_;
- }
-private:
- Value value_;
-};
-
-/**
- * The generic container for Avro maps.
- */
-class AVRO_DECL GenericMap : public GenericContainer {
-public:
- /**
- * The contents type for the map.
- */
- 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) {
- }
-
- /**
- * Returns the contents of this map.
- */
- const Value& value() const {
- return value_;
- }
-
- /**
- * Returns the reference to the contents of this map.
- */
- Value& value() {
- return value_;
- }
-private:
- Value value_;
-};
-
-/**
- * Generic container for Avro enum.
- */
-class AVRO_DECL GenericEnum : public GenericContainer {
- size_t value_;
-
- static size_t index(const NodePtr& schema, const std::string& symbol) {
- size_t result;
- if (schema->nameIndex(symbol, result)) {
- return result;
- }
- throw Exception("No such symbol");
- }
-
-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) {
- }
-
- 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) {
- if (n < schema()->names()) {
- return schema()->nameAt(n);
- }
- throw Exception("Not as many symbols");
- }
-
- /**
- * 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 {
- return index(schema(), symbol);
- }
-
- /**
- * Set the value for this enum corresponding to the given symbol \c symbol.
- */
- size_t set(const std::string& symbol) {
- return value_ = index(symbol);
- }
-
- /**
- * Set the value for this enum corresponding to the given cardinal \c n.
- */
- void set(size_t n) {
- if (n < schema()->names()) {
- value_ = n;
- return;
- }
- throw Exception("Not as many symbols");
- }
-
- /**
- * Returns the cardinal for the current value of this enum.
- */
- size_t value() const {
- return value_;
- }
-
- /**
- * Returns the symbol for the current value of this enum.
- */
- const std::string& symbol() const {
- return schema()->nameAt(value_);
- }
-};
-
-/**
- * Generic container for Avro fixed.
- */
-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) {
- value_.resize(schema->fixedSize());
- }
-
- GenericFixed(const NodePtr& schema, const std::vector<uint8_t>& v) :
- GenericContainer(AVRO_FIXED, schema), value_(v) { }
-
- /**
- * Returns the contents of this fixed.
- */
- const std::vector<uint8_t>& value() const {
- return value_;
- }
-
- /**
- * Returns the reference to the contents of this fixed.
- */
- std::vector<uint8_t>& value() {
- return value_;
- }
-};
-
-inline Type GenericDatum::type() const {
- return (type_ == AVRO_UNION) ?
-#if __cplusplus >= 201703L
- std::any_cast<GenericUnion>(&value_)->datum().type() :
-#else
- boost::any_cast<GenericUnion>(&value_)->datum().type() :
-#endif
- type_;
-}
-
-inline LogicalType GenericDatum::logicalType() const {
- return logicalType_;
-}
-
-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_);
-#else
- boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
- *boost::any_cast<T>(&value_);
-#endif
-}
-
-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_);
-#else
- boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
- *boost::any_cast<T>(&value_);
-#endif
-}
-
-inline size_t GenericDatum::unionBranch() const {
-#if __cplusplus >= 201703L
- return std::any_cast<GenericUnion>(&value_)->currentBranch();
-#else
- return boost::any_cast<GenericUnion>(&value_)->currentBranch();
-#endif
-}
-
-inline void GenericDatum::selectBranch(size_t branch) {
-#if __cplusplus >= 201703L
- std::any_cast<GenericUnion>(&value_)->selectBranch(branch);
-#else
- boost::any_cast<GenericUnion>(&value_)->selectBranch(branch);
-#endif
-}
-
-} // namespace avro
-#endif // avro_GenericDatum_hh__
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 avro_GenericDatum_hh__
+#define avro_GenericDatum_hh__
+
+#include <stdint.h>
+#include <vector>
+#include <map>
+#include <string>
+
+#if __cplusplus >= 201703L
+#include <any>
+#else
+#include "boost/any.hpp"
+#endif
+
+#include "LogicalType.hh"
+#include "Node.hh"
+#include "ValidSchema.hh"
+
+namespace avro {
+
+/**
+ * Generic datum which can hold any Avro type. The datum has a type
+ * and a value. The type is one of the Avro data types. The C++ type for
+ * value corresponds to the Avro type.
+ * \li An Avro <tt>null</tt> corresponds to no C++ type. It is illegal to
+ * to try to access values for <tt>null</tt>.
+ * \li Avro <tt>boolean</tt> maps to C++ <tt>bool</tt>
+ * \li Avro <tt>int</tt> maps to C++ <tt>int32_t</tt>.
+ * \li Avro <tt>long</tt> maps to C++ <tt>int64_t</tt>.
+ * \li Avro <tt>float</tt> maps to C++ <tt>float</tt>.
+ * \li Avro <tt>double</tt> maps to C++ <tt>double</tt>.
+ * \li Avro <tt>string</tt> maps to C++ <tt>std::string</tt>.
+ * \li Avro <tt>bytes</tt> maps to C++ <tt>std::vector&lt;uint_t&gt;</tt>.
+ * \li Avro <tt>fixed</tt> maps to C++ class <tt>GenericFixed</tt>.
+ * \li Avro <tt>enum</tt> maps to C++ class <tt>GenericEnum</tt>.
+ * \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
+ * types of the union.
+ *
+ */
+class AVRO_DECL GenericDatum {
+protected:
+ Type type_;
+ LogicalType logicalType_;
+#if __cplusplus >= 201703L
+ std::any value_;
+#else
+ boost::any value_;
+#endif
+
+ GenericDatum(Type t)
+ : type_(t), logicalType_(LogicalType::NONE) { }
+
+ GenericDatum(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) { }
+
+ void init(const NodePtr& schema);
+public:
+ /**
+ * The avro data type this datum holds.
+ */
+ Type type() const;
+
+ /**
+ * The avro logical type that augments the main data type this datum holds.
+ */
+ LogicalType logicalType() const;
+
+ /**
+ * Returns the value held by this datum.
+ * T The type for the value. This must correspond to the
+ * avro type returned by type().
+ */
+ template<typename T> const T& value() const;
+
+ /**
+ * Returns the reference to the value held by this datum, which
+ * can be used to change the contents. Please note that only
+ * value can be changed, the data type of the value held cannot
+ * be changed.
+ *
+ * T The type for the value. This must correspond to the
+ * avro type returned by type().
+ */
+ template<typename T> T& value();
+
+ /**
+ * Returns true if and only if this datum is a union.
+ */
+ bool isUnion() const { return type_ == AVRO_UNION; }
+
+ /**
+ * Returns the index of the current branch, if this is a union.
+ * \sa isUnion().
+ */
+ size_t unionBranch() const;
+
+ /**
+ * Selects a new branch in the union if this is a union.
+ * \sa isUnion().
+ */
+ void selectBranch(size_t branch);
+
+ /// Makes a new AVRO_NULL datum.
+ GenericDatum() : type_(AVRO_NULL), logicalType_(LogicalType::NONE) { }
+
+ /// Makes a new AVRO_BOOL datum whose value is of type bool.
+ GenericDatum(bool v)
+ : type_(AVRO_BOOL), logicalType_(LogicalType::NONE), value_(v) { }
+
+ /// Makes a new AVRO_INT datum whose value is of type int32_t.
+ GenericDatum(int32_t v)
+ : type_(AVRO_INT), logicalType_(LogicalType::NONE), value_(v) { }
+
+ /// Makes a new AVRO_LONG datum whose value is of type int64_t.
+ GenericDatum(int64_t v)
+ : type_(AVRO_LONG), logicalType_(LogicalType::NONE), value_(v) { }
+
+ /// Makes a new AVRO_FLOAT datum whose value is of type float.
+ GenericDatum(float v)
+ : type_(AVRO_FLOAT), logicalType_(LogicalType::NONE), value_(v) { }
+
+ /// Makes a new AVRO_DOUBLE datum whose value is of type double.
+ GenericDatum(double 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) { }
+
+ /// 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) { }
+
+ /**
+ * Constructs a datum corresponding to the given avro type.
+ * The value will the appropriate default corresponding to the
+ * data type.
+ * \param schema The schema that defines the avro type.
+ */
+ GenericDatum(const NodePtr& schema);
+
+ /**
+ * Constructs a datum corresponding to the given avro type and set
+ * the value.
+ * \param schema The schema that defines the avro type.
+ * \param v The value for this type.
+ */
+ template<typename T>
+ GenericDatum(const NodePtr& schema, const T& v) :
+ type_(schema->type()), logicalType_(schema->logicalType()) {
+ init(schema);
+#if __cplusplus >= 201703L
+ *std::any_cast<T>(&value_) = v;
+#else
+ *boost::any_cast<T>(&value_) = v;
+#endif
+ }
+
+ /**
+ * Constructs a datum corresponding to the given avro type.
+ * The value will the appropriate default corresponding to the
+ * data type.
+ * \param schema The schema that defines the avro type.
+ */
+ GenericDatum(const ValidSchema& schema);
+};
+
+/**
+ * The base class for all generic type for containers.
+ */
+class AVRO_DECL GenericContainer {
+ NodePtr schema_;
+ 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) {
+ assertType(s, type);
+ }
+
+public:
+ /// Returns the schema for this object
+ const NodePtr& schema() const {
+ return schema_;
+ }
+};
+
+/**
+ * Generic container for unions.
+ */
+class AVRO_DECL GenericUnion : public GenericContainer {
+ size_t curBranch_;
+ GenericDatum datum_;
+
+public:
+ /**
+ * Constructs a generic union corresponding to the given schema \p schema,
+ * 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()) {
+ selectBranch(0);
+ }
+
+ /**
+ * Returns the index of the current branch.
+ */
+ size_t currentBranch() const { return curBranch_; }
+
+ /**
+ * Selects a new branch. The type for the value is changed accordingly.
+ * \param branch The index for the selected branch.
+ */
+ void selectBranch(size_t branch) {
+ if (curBranch_ != branch) {
+ datum_ = GenericDatum(schema()->leafAt(branch));
+ curBranch_ = branch;
+ }
+ }
+
+ /**
+ * Returns the datum corresponding to the currently selected branch
+ * in this union.
+ */
+ GenericDatum& datum() {
+ return datum_;
+ }
+
+ /**
+ * Returns the datum corresponding to the currently selected branch
+ * in this union.
+ */
+ const GenericDatum& datum() const {
+ return datum_;
+ }
+};
+
+/**
+ * The generic container for Avro records.
+ */
+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);
+
+ /**
+ * Returns the number of fields in the current record.
+ */
+ size_t fieldCount() const {
+ return fields_.size();
+ }
+
+ /**
+ * Returns index of the field with the given name \p name
+ */
+ size_t fieldIndex(const std::string& name) const {
+ size_t index = 0;
+ if (!schema()->nameIndex(name, index)) {
+ throw Exception("Invalid field name: " + name);
+ }
+ return index;
+ }
+
+ /**
+ * 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 {
+ size_t index = 0;
+ return schema()->nameIndex(name, index);
+ }
+
+ /**
+ * Returns the field with the given name \p name.
+ */
+ const GenericDatum& field(const std::string& name) const {
+ return fieldAt(fieldIndex(name));
+ }
+
+ /**
+ * 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) {
+ return fieldAt(fieldIndex(name));
+ }
+
+ /**
+ * Returns the field at the given position \p pos.
+ */
+ const GenericDatum& fieldAt(size_t pos) const {
+ return fields_[pos];
+ }
+
+ /**
+ * 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) {
+ return fields_[pos];
+ }
+
+ /**
+ * Replaces the field at the given position \p pos with \p v.
+ */
+ void setFieldAt(size_t pos, const GenericDatum& v) {
+ // assertSameType(v, schema()->leafAt(pos));
+ fields_[pos] = v;
+ }
+};
+
+/**
+ * The generic container for Avro arrays.
+ */
+class AVRO_DECL GenericArray : public GenericContainer {
+public:
+ /**
+ * The contents type for the array.
+ */
+ typedef std::vector<GenericDatum> Value;
+
+ /**
+ * 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) {
+ }
+
+ /**
+ * Returns the contents of this array.
+ */
+ const Value& value() const {
+ return value_;
+ }
+
+ /**
+ * Returns the reference to the contents of this array.
+ */
+ Value& value() {
+ return value_;
+ }
+private:
+ Value value_;
+};
+
+/**
+ * The generic container for Avro maps.
+ */
+class AVRO_DECL GenericMap : public GenericContainer {
+public:
+ /**
+ * The contents type for the map.
+ */
+ 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) {
+ }
+
+ /**
+ * Returns the contents of this map.
+ */
+ const Value& value() const {
+ return value_;
+ }
+
+ /**
+ * Returns the reference to the contents of this map.
+ */
+ Value& value() {
+ return value_;
+ }
+private:
+ Value value_;
+};
+
+/**
+ * Generic container for Avro enum.
+ */
+class AVRO_DECL GenericEnum : public GenericContainer {
+ size_t value_;
+
+ static size_t index(const NodePtr& schema, const std::string& symbol) {
+ size_t result;
+ if (schema->nameIndex(symbol, result)) {
+ return result;
+ }
+ throw Exception("No such symbol");
+ }
+
+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) {
+ }
+
+ 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) {
+ if (n < schema()->names()) {
+ return schema()->nameAt(n);
+ }
+ throw Exception("Not as many symbols");
+ }
+
+ /**
+ * 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 {
+ return index(schema(), symbol);
+ }
+
+ /**
+ * Set the value for this enum corresponding to the given symbol \c symbol.
+ */
+ size_t set(const std::string& symbol) {
+ return value_ = index(symbol);
+ }
+
+ /**
+ * Set the value for this enum corresponding to the given cardinal \c n.
+ */
+ void set(size_t n) {
+ if (n < schema()->names()) {
+ value_ = n;
+ return;
+ }
+ throw Exception("Not as many symbols");
+ }
+
+ /**
+ * Returns the cardinal for the current value of this enum.
+ */
+ size_t value() const {
+ return value_;
+ }
+
+ /**
+ * Returns the symbol for the current value of this enum.
+ */
+ const std::string& symbol() const {
+ return schema()->nameAt(value_);
+ }
+};
+
+/**
+ * Generic container for Avro fixed.
+ */
+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) {
+ value_.resize(schema->fixedSize());
+ }
+
+ GenericFixed(const NodePtr& schema, const std::vector<uint8_t>& v) :
+ GenericContainer(AVRO_FIXED, schema), value_(v) { }
+
+ /**
+ * Returns the contents of this fixed.
+ */
+ const std::vector<uint8_t>& value() const {
+ return value_;
+ }
+
+ /**
+ * Returns the reference to the contents of this fixed.
+ */
+ std::vector<uint8_t>& value() {
+ return value_;
+ }
+};
+
+inline Type GenericDatum::type() const {
+ return (type_ == AVRO_UNION) ?
+#if __cplusplus >= 201703L
+ std::any_cast<GenericUnion>(&value_)->datum().type() :
+#else
+ boost::any_cast<GenericUnion>(&value_)->datum().type() :
+#endif
+ type_;
+}
+
+inline LogicalType GenericDatum::logicalType() const {
+ return logicalType_;
+}
+
+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_);
+#else
+ boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
+ *boost::any_cast<T>(&value_);
+#endif
+}
+
+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_);
+#else
+ boost::any_cast<GenericUnion>(&value_)->datum().value<T>() :
+ *boost::any_cast<T>(&value_);
+#endif
+}
+
+inline size_t GenericDatum::unionBranch() const {
+#if __cplusplus >= 201703L
+ return std::any_cast<GenericUnion>(&value_)->currentBranch();
+#else
+ return boost::any_cast<GenericUnion>(&value_)->currentBranch();
+#endif
+}
+
+inline void GenericDatum::selectBranch(size_t branch) {
+#if __cplusplus >= 201703L
+ std::any_cast<GenericUnion>(&value_)->selectBranch(branch);
+#else
+ boost::any_cast<GenericUnion>(&value_)->selectBranch(branch);
+#endif
+}
+
+} // namespace avro
+#endif // avro_GenericDatum_hh__