You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by th...@apache.org on 2011/10/21 17:00:26 UTC
svn commit: r1187383 - in /avro/trunk: CHANGES.txt lang/c++/api/Generic.hh
lang/c++/examples/generic.cc lang/c++/impl/Generic.cc
lang/c++/test/CodecTests.cc
Author: thiru
Date: Fri Oct 21 15:00:25 2011
New Revision: 1187383
URL: http://svn.apache.org/viewvc?rev=1187383&view=rev
Log:
AVRO-940. C++ design for generic datum could be better
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/c++/api/Generic.hh
avro/trunk/lang/c++/examples/generic.cc
avro/trunk/lang/c++/impl/Generic.cc
avro/trunk/lang/c++/test/CodecTests.cc
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1187383&r1=1187382&r2=1187383&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Fri Oct 21 15:00:25 2011
@@ -151,6 +151,9 @@ Avro 1.6.0 (unreleased)
AVRO-938. Some more warning when built on RHEL. (thiru)
AVRO-937. C++ CMake keeps generating code even when there is no change. (thiru)
+
+ AVRO-940. C++ design for generic datum could be better. (thiru)
+
BUG FIXES
AVRO-824. Java: Fix usage message of BinaryFragmentToJsonTool.
Modified: avro/trunk/lang/c++/api/Generic.hh
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c%2B%2B/api/Generic.hh?rev=1187383&r1=1187382&r2=1187383&view=diff
==============================================================================
--- avro/trunk/lang/c++/api/Generic.hh (original)
+++ avro/trunk/lang/c++/api/Generic.hh Fri Oct 21 15:00:25 2011
@@ -33,7 +33,6 @@
#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
@@ -65,23 +64,19 @@ class GenericDatum {
template <typename T>
GenericDatum(Type t, const T& v) : type_(t), value_(v) { }
+ void init(const NodePtr& schema);
public:
/**
* The avro data type this datum holds.
*/
- Type type() const {
- return type_;
- }
+ Type type() 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 {
- return *boost::any_cast<T>(&value_);
- }
+ template<typename T> const T& value() const;
/**
* Returns the reference to the value held by this datum, which
@@ -92,10 +87,24 @@ public:
* T The type for the value. This must correspond to the
* avro type returned by type().
*/
- template<typename T>
- T& value() {
- return *boost::any_cast<T>(&value_);
- }
+ 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) { }
@@ -130,30 +139,35 @@ public:
* \param schema The schema that defines the avro type.
*/
GenericDatum(const NodePtr& schema);
+
+ /**
+ * Constructs a datum corresponding to the given avro type.
+ * The value will the appropraite 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 GenericContainer {
- const NodePtr schema_;
+ NodePtr schema_;
+ static void assertType(const NodePtr& schema, Type type);
protected:
/**
* Constructs a container corresponding to the given schema.
*/
- GenericContainer(const NodePtr& s) : schema_(s) { }
+ GenericContainer(Type type, const NodePtr& s) : schema_(s) {
+ assertType(s, type);
+ }
/**
* Asserts if the given generic datum \p v has a type that matches \p n.
*/
static void assertSameType(const GenericDatum& v, const NodePtr& n);
- /**
- * Asserts that the given schema \p schema has the given type \c type.
- * If not, it throws an exception with the given message \c message.
- */
- static void assertType(const NodePtr& schema, Type type,
- const char* message);
public:
/// Returns the schema for this object
const NodePtr& schema() const {
@@ -162,6 +176,64 @@ public:
};
/**
+ * Generic container for unions.
+ */
+class 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()) {
+ }
+
+ /**
+ * 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 type for currently selected branch in this union.
+ */
+ Type type() const {
+ return datum_.type();
+ }
+
+ /**
+ * Returns the value in this union.
+ */
+ template<typename T>
+ const T& value() const {
+ return datum_.value<T>();
+ }
+
+ /**
+ * Returns the reference to the value in this union.
+ */
+ template<typename T>
+ T& value() {
+ return datum_.value<T>();
+ }
+
+};
+
+/**
* The generic container for Avro records.
*/
class GenericRecord : public GenericContainer {
@@ -218,10 +290,7 @@ public:
* Constructs a generic array corresponding to the given schema \p schema,
* which should be of Avro type array.
*/
- GenericArray(const NodePtr& schema) : GenericContainer(schema) {
- if (schema->type() != AVRO_ARRAY) {
- throw Exception("Schema is not an array");
- }
+ GenericArray(const NodePtr& schema) : GenericContainer(AVRO_ARRAY, schema) {
}
/**
@@ -255,8 +324,7 @@ public:
* Constructs a generic map corresponding to the given schema \p schema,
* which should be of Avro type map.
*/
- GenericMap(const NodePtr& schema) : GenericContainer(schema) {
- assertType(schema, AVRO_MAP, "Schema is not a map");
+ GenericMap(const NodePtr& schema) : GenericContainer(AVRO_MAP, schema) {
}
/**
@@ -286,7 +354,8 @@ public:
* Constructs a generic enum corresponding to the given schema \p schema,
* which should be of Avro type enum.
*/
- GenericEnum(const NodePtr& schema) : GenericContainer(schema), value_(0) {
+ GenericEnum(const NodePtr& schema) :
+ GenericContainer(AVRO_ENUM, schema), value_(0) {
}
/**
@@ -355,7 +424,7 @@ public:
* Constructs a generic enum corresponding to the given schema \p schema,
* which should be of Avro type fixed.
*/
- GenericFixed(const NodePtr& schema) : GenericContainer(schema) {
+ GenericFixed(const NodePtr& schema) : GenericContainer(AVRO_FIXED, schema) {
value_.resize(schema->fixedSize());
}
@@ -383,8 +452,7 @@ class GenericReader : boost::noncopyable
const bool isResolving_;
const DecoderPtr decoder_;
- static void read(GenericDatum& datum, const NodePtr& n, Decoder& d,
- bool isResolving);
+ static void read(GenericDatum& datum, Decoder& d, bool isResolving);
public:
/**
* Constructs a reader for the given schema using the given decoder.
@@ -407,6 +475,11 @@ public:
/**
* Reads a generic datum from the stream, using the given schema.
*/
+ static void read(Decoder& d, GenericDatum& g);
+
+ /**
+ * Reads a generic datum from the stream, using the given schema.
+ */
static void read(Decoder& d, GenericDatum& g, const ValidSchema& s);
};
@@ -418,7 +491,7 @@ class GenericWriter : boost::noncopyable
const ValidSchema schema_;
const EncoderPtr encoder_;
- static void write(const GenericDatum& datum, const NodePtr& n, Encoder& e);
+ static void write(const GenericDatum& datum, Encoder& e);
public:
/**
* Constructs a writer for the given schema using the given encoder.
@@ -431,15 +504,52 @@ public:
void write(const GenericDatum& datum) const;
/**
+ * Writes a generic datum on to the stream.
+ */
+ static void write(Encoder& e, const GenericDatum& g);
+
+ /**
* Writes a generic datum on to the stream, using the given schema.
+ * Retained for backward compatibility.
*/
- static void write(Encoder& e, const GenericDatum& g, const ValidSchema& s);
+ static void write(Encoder& e, const GenericDatum& g, const ValidSchema&) {
+ write(e, g);
+ }
};
+inline Type GenericDatum::type() const {
+ return (type_ == AVRO_UNION) ?
+ boost::any_cast<GenericUnion>(&value_)->type() : type_;
+}
+
+template<typename T>
+const T& GenericDatum::value() const {
+ return (type_ == AVRO_UNION) ?
+ boost::any_cast<GenericUnion>(&value_)->value<T>() :
+ *boost::any_cast<T>(&value_);
+}
+
+template<typename T>
+T& GenericDatum::value() {
+ return (type_ == AVRO_UNION) ?
+ boost::any_cast<GenericUnion>(&value_)->value<T>() :
+ *boost::any_cast<T>(&value_);
+}
+
+inline size_t GenericDatum::unionBranch() const {
+ return boost::any_cast<GenericUnion>(&value_)->currentBranch();
+}
+
+inline void GenericDatum::selectBranch(size_t branch) {
+ boost::any_cast<GenericUnion>(&value_)->selectBranch(branch);
+}
+
template <typename T> struct codec_traits;
/**
- * Specialization for codec_traits for Generic datum.
+ * Specialization of codec_traits for Generic datum along with its schema.
+ * This is maintained for compatibility with old code. Please use the
+ * cleaner codec_traits<GenericDatum> instead.
*/
template <> struct codec_traits<std::pair<ValidSchema, GenericDatum> > {
/** Encodes */
@@ -453,6 +563,22 @@ template <> struct codec_traits<std::pai
GenericReader::read(d, p.second, p.first);
}
};
+
+/**
+ * Specialization of codec_traits for GenericDatum.
+ */
+template <> struct codec_traits<GenericDatum> {
+ /** Encodes */
+ static void encode(Encoder& e, const GenericDatum& g) {
+ GenericWriter::write(e, g);
+ }
+
+ /** Decodes */
+ static void decode(Decoder& d, GenericDatum& g) {
+ GenericReader::read(d, g);
+ }
+};
+
} // namespace avro
#endif
Modified: avro/trunk/lang/c++/examples/generic.cc
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c%2B%2B/examples/generic.cc?rev=1187383&r1=1187382&r2=1187383&view=diff
==============================================================================
--- avro/trunk/lang/c++/examples/generic.cc (original)
+++ avro/trunk/lang/c++/examples/generic.cc Fri Oct 21 15:00:25 2011
@@ -29,10 +29,8 @@ main()
avro::DecoderPtr d = avro::binaryDecoder();
d->init(*in);
- std::pair<avro::ValidSchema, avro::GenericDatum> p(cpxSchema,
- avro::GenericDatum(cpxSchema.root()));
- avro::decode(*d, p);
- const avro::GenericDatum& datum = p.second;
+ avro::GenericDatum datum(cpxSchema);
+ avro::decode(*d, datum);
std::cout << "Type: " << datum.type() << std::endl;
if (datum.type() == avro::AVRO_RECORD) {
const avro::GenericRecord& r = datum.value<avro::GenericRecord>();
Modified: avro/trunk/lang/c++/impl/Generic.cc
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c%2B%2B/impl/Generic.cc?rev=1187383&r1=1187382&r2=1187383&view=diff
==============================================================================
--- avro/trunk/lang/c++/impl/Generic.cc (original)
+++ avro/trunk/lang/c++/impl/Generic.cc Fri Oct 21 15:00:25 2011
@@ -28,68 +28,85 @@ using std::ostringstream;
typedef vector<uint8_t> bytes;
-void GenericContainer::assertType(const NodePtr& schema, Type type,
- const char* message)
-{
+void GenericContainer::assertType(const NodePtr& schema, Type type) {
if (schema->type() != type) {
- throw Exception(message);
+ throw Exception(boost::format("Schema type %1 expected %2") %
+ toString(schema->type()) % toString(type));
}
}
+GenericDatum::GenericDatum(const ValidSchema& schema) :
+ type_(schema.root()->type())
+{
+ init(schema.root());
+}
+
GenericDatum::GenericDatum(const NodePtr& schema) : type_(schema->type())
{
+ init(schema);
+}
+
+void GenericDatum::init(const NodePtr& schema)
+{
+ NodePtr sc = schema;
if (type_ == AVRO_SYMBOLIC) {
- type_ = static_cast<NodeSymbolic&>(*schema).type();
+ sc = resolveSymbol(schema);
+ type_ = sc->type();
}
switch (type_) {
- case AVRO_NULL:
- break;
- case AVRO_BOOL:
- value_ = bool();
- break;
- case AVRO_INT:
- value_ = int32_t();
- break;
- case AVRO_LONG:
- value_ = int64_t();
- break;
- case AVRO_FLOAT:
- value_ = float();
- break;
- case AVRO_DOUBLE:
- value_ = double();
- break;
- case AVRO_STRING:
- value_ = string();
- break;
- case AVRO_BYTES:
- value_ = vector<uint8_t>();
- break;
- case AVRO_FIXED:
- value_ = GenericFixed(schema);
- break;
- case AVRO_RECORD:
- value_ = GenericRecord(schema);
- break;
- case AVRO_ENUM:
- value_ = GenericEnum(schema);
- break;
- case AVRO_ARRAY:
- value_ = GenericArray(schema);
- break;
- case AVRO_MAP:
- value_ = GenericMap(schema);
- break;
- case AVRO_UNION:
- throw Exception("Generic datum cannot be a union");
- default:
- throw Exception(boost::format("Unknown schema type %1%") %
- toString(type_));
+ case AVRO_NULL:
+ break;
+ case AVRO_BOOL:
+ value_ = bool();
+ break;
+ case AVRO_INT:
+ value_ = int32_t();
+ break;
+ case AVRO_LONG:
+ value_ = int64_t();
+ break;
+ case AVRO_FLOAT:
+ value_ = float();
+ break;
+ case AVRO_DOUBLE:
+ value_ = double();
+ break;
+ case AVRO_STRING:
+ value_ = string();
+ break;
+ case AVRO_BYTES:
+ value_ = vector<uint8_t>();
+ break;
+ case AVRO_FIXED:
+ value_ = GenericFixed(sc);
+ break;
+ case AVRO_RECORD:
+ value_ = GenericRecord(sc);
+ break;
+ case AVRO_ENUM:
+ value_ = GenericEnum(sc);
+ break;
+ case AVRO_ARRAY:
+ value_ = GenericArray(sc);
+ break;
+ case AVRO_MAP:
+ value_ = GenericMap(sc);
+ break;
+ case AVRO_UNION:
+ value_ = GenericUnion(sc);
+ break;
+ default:
+ throw Exception(boost::format("Unknown schema type %1%") %
+ toString(type_));
}
}
-GenericRecord::GenericRecord(const NodePtr& schema) : GenericContainer(schema) {
+GenericRecord::GenericRecord(const NodePtr& schema) :
+ GenericContainer(AVRO_RECORD, schema) {
fields_.resize(schema->leaves());
+ for (size_t i = 0; i < schema->leaves(); ++i) {
+ fields_[i] = GenericDatum(schema->leafAt(i));
+ }
}
GenericReader::GenericReader(const ValidSchema& s, const DecoderPtr& decoder) :
@@ -108,65 +125,16 @@ GenericReader::GenericReader(const Valid
void GenericReader::read(GenericDatum& datum) const
{
- read(datum, schema_.root(), *decoder_, isResolving_);
-}
-
-static void ensureType(GenericDatum& datum, const NodePtr& n)
-{
- if (datum.type() != n->type()) {
- switch (n->type()) {
- case AVRO_NULL:
- datum = GenericDatum();
- break;
- case AVRO_BOOL:
- datum = bool();
- break;
- case AVRO_INT:
- datum = int32_t();
- break;
- case AVRO_LONG:
- datum = int64_t();
- break;
- case AVRO_FLOAT:
- datum = float();
- break;
- case AVRO_DOUBLE:
- datum = double();
- break;
- case AVRO_STRING:
- datum = string();
- break;
- case AVRO_BYTES:
- datum = bytes();
- break;
- case AVRO_FIXED:
- case AVRO_RECORD:
- case AVRO_ENUM:
- case AVRO_ARRAY:
- case AVRO_MAP:
- datum = n;
- break;
- case AVRO_UNION:
- break;
- default:
- throw Exception("Unknown schema type");
- }
- }
+ datum = GenericDatum(schema_.root());
+ read(datum, *decoder_, isResolving_);
}
-void GenericReader::read(GenericDatum& datum, const NodePtr& n, Decoder& d,
- bool isResolving)
+void GenericReader::read(GenericDatum& datum, Decoder& d, bool isResolving)
{
- NodePtr nn = n;
- if (nn->type() == AVRO_UNION) {
- size_t r = d.decodeUnionIndex();
- nn = nn->leafAt(r);
+ if (datum.isUnion()) {
+ datum.selectBranch(d.decodeUnionIndex());
}
- if (nn->type() == AVRO_SYMBOLIC) {
- nn = static_cast<NodeSymbolic&>(*nn).getNode();
- }
- ensureType(datum, nn);
- switch (nn->type()) {
+ switch (datum.type()) {
case AVRO_NULL:
d.decodeNull();
break;
@@ -192,21 +160,24 @@ void GenericReader::read(GenericDatum& d
d.decodeBytes(datum.value<bytes>());
break;
case AVRO_FIXED:
- d.decodeFixed(nn->fixedSize(), datum.value<GenericFixed>().value());
+ {
+ GenericFixed& f = datum.value<GenericFixed>();
+ d.decodeFixed(f.schema()->fixedSize(), f.value());
+ }
break;
case AVRO_RECORD:
{
GenericRecord& r = datum.value<GenericRecord>();
- size_t c = nn->leaves();
+ size_t c = r.schema()->leaves();
if (isResolving) {
std::vector<size_t> fo =
static_cast<ResolvingDecoder&>(d).fieldOrder();
for (size_t i = 0; i < c; ++i) {
- read(r.fieldAt(fo[i]), nn->leafAt(fo[i]), d, isResolving);
+ read(r.fieldAt(fo[i]), d, isResolving);
}
} else {
for (size_t i = 0; i < c; ++i) {
- read(r.fieldAt(i), nn->leafAt(i), d, isResolving);
+ read(r.fieldAt(i), d, isResolving);
}
}
}
@@ -216,82 +187,52 @@ void GenericReader::read(GenericDatum& d
break;
case AVRO_ARRAY:
{
- vector<GenericDatum>& r = datum.value<GenericArray>().value();
+ GenericArray& v = datum.value<GenericArray>();
+ vector<GenericDatum>& r = v.value();
+ const NodePtr& nn = v.schema()->leafAt(0);
r.resize(0);
size_t start = 0;
for (size_t m = d.arrayStart(); m != 0; m = d.arrayNext()) {
r.resize(r.size() + m);
for (; start < r.size(); ++start) {
- read(r[start], nn->leafAt(0), d, isResolving);
+ r[start] = GenericDatum(nn);
+ read(r[start], d, isResolving);
}
}
}
break;
case AVRO_MAP:
{
- GenericMap::Value& r = datum.value<GenericMap>().value();
+ GenericMap& v = datum.value<GenericMap>();
+ GenericMap::Value& r = v.value();
+ const NodePtr& nn = v.schema()->leafAt(1);
r.resize(0);
size_t start = 0;
for (size_t m = d.mapStart(); m != 0; m = d.mapNext()) {
r.resize(r.size() + m);
for (; start < r.size(); ++start) {
d.decodeString(r[start].first);
- read(r[start].second, nn->leafAt(1), d, isResolving);
+ r[start].second = GenericDatum(nn);
+ read(r[start].second, d, isResolving);
}
}
}
break;
default:
- throw Exception("Unknown schema type");
+ throw Exception(boost::format("Unknown schema type %1%") %
+ toString(datum.type()));
}
}
void GenericReader::read(Decoder& d, GenericDatum& g, const ValidSchema& s)
{
- read(g, s.root(), d, dynamic_cast<ResolvingDecoder*>(&d) != 0);
-}
-
-static void typeMismatch(Type t, Type u)
-{
- throw Exception(boost::format("Type mismatch %1% v %2%") %
- toString(t) % toString(u));
+ g = GenericDatum(s);
+ read(d, g);
}
-template <typename T>
-bool hasSameName(const GenericDatum& datum, const NodePtr& n)
+void GenericReader::read(Decoder& d, GenericDatum& g)
{
- const T& c = datum.value<T>();
- return c.schema()->name() == n->name();
-}
-
-template <typename T>
-void assertSameType(const GenericDatum& datum, const NodePtr& n)
-{
- const T& c = datum.value<T>();
- if (c.schema() != n) {
- typeMismatch(c.schema()->type(), n->type());
- }
-}
-
-static void assertType(const GenericDatum& datum, const NodePtr& n)
-{
- if (datum.type() == n->type()) {
- switch (n->type()) {
- case AVRO_FIXED:
- assertSameType<GenericFixed>(datum, n);
- return;
- case AVRO_RECORD:
- assertSameType<GenericRecord>(datum, n);
- return;
- case AVRO_ENUM:
- assertSameType<GenericEnum>(datum, n);
- return;
- default:
- return;
- }
- } else {
- typeMismatch(datum.type(), n->type());
- }
+ read(g, d, dynamic_cast<ResolvingDecoder*>(&d) != 0);
}
GenericWriter::GenericWriter(const ValidSchema& s, const EncoderPtr& encoder) :
@@ -301,50 +242,15 @@ GenericWriter::GenericWriter(const Valid
void GenericWriter::write(const GenericDatum& datum) const
{
- write(datum, schema_.root(), *encoder_);
+ write(datum, *encoder_);
}
-static size_t selectBranch(const GenericDatum& datum, const NodePtr& n)
+void GenericWriter::write(const GenericDatum& datum, Encoder& e)
{
- size_t c = n->leaves();
- for (size_t i = 0; i < c; ++i) {
- const NodePtr& nn = n->leafAt(i);
- if (datum.type() == nn->type()) {
- switch (datum.type()) {
- case AVRO_FIXED:
- if (hasSameName<GenericFixed>(datum, nn)) return i;
- break;
- case AVRO_RECORD:
- if (hasSameName<GenericRecord>(datum, nn)) return i;
- break;
- case AVRO_ENUM:
- if (hasSameName<GenericEnum>(datum, nn)) return i;
- break;
- default:
- return i;
- }
- }
- }
- ostringstream oss;
- n->printJson(oss, 0);
- throw Exception(boost::format("No match for %1% in %2%") %
- toString(datum.type()) % oss.str());
-}
-
-void GenericWriter::write(const GenericDatum& datum,
- const NodePtr& n, Encoder& e)
-{
- NodePtr nn = n;
- if (nn->type() == AVRO_UNION) {
- size_t br = selectBranch(datum, nn);
- e.encodeUnionIndex(br);
- nn = nn->leafAt(br);
- }
- if (nn->type() == AVRO_SYMBOLIC) {
- nn = static_cast<NodeSymbolic&>(*nn).getNode();
+ if (datum.isUnion()) {
+ e.encodeUnionIndex(datum.unionBranch());
}
- assertType(datum, nn);
- switch (nn->type()) {
+ switch (datum.type()) {
case AVRO_NULL:
e.encodeNull();
break;
@@ -375,9 +281,9 @@ void GenericWriter::write(const GenericD
case AVRO_RECORD:
{
const GenericRecord& r = datum.value<GenericRecord>();
- size_t c = nn->leaves();
+ size_t c = r.schema()->leaves();
for (size_t i = 0; i < c; ++i) {
- write(r.fieldAt(i), nn->leafAt(i), e);
+ write(r.fieldAt(i), e);
}
}
break;
@@ -393,7 +299,7 @@ void GenericWriter::write(const GenericD
for (GenericArray::Value::const_iterator it = r.begin();
it != r.end(); ++it) {
e.startItem();
- write(*it, nn->leafAt(0), e);
+ write(*it, e);
}
}
e.arrayEnd();
@@ -409,21 +315,21 @@ void GenericWriter::write(const GenericD
it != r.end(); ++it) {
e.startItem();
e.encodeString(it->first);
- write(it->second, nn->leafAt(1), e);
+ write(it->second, e);
}
}
e.mapEnd();
}
break;
default:
- throw Exception("Unknown schema type");
+ throw Exception(boost::format("Unknown schema type %1%") %
+ toString(datum.type()));
}
}
-void GenericWriter::write(Encoder& e, const GenericDatum& g,
- const ValidSchema& s)
+void GenericWriter::write(Encoder& e, const GenericDatum& g)
{
- write(g, s.root(), e);
+ write(g, e);
}
} // namespace avro
Modified: avro/trunk/lang/c++/test/CodecTests.cc
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c%2B%2B/test/CodecTests.cc?rev=1187383&r1=1187382&r2=1187383&view=diff
==============================================================================
--- avro/trunk/lang/c++/test/CodecTests.cc (original)
+++ avro/trunk/lang/c++/test/CodecTests.cc Fri Oct 21 15:00:25 2011
@@ -23,6 +23,7 @@
#include "Compiler.hh"
#include "ValidSchema.hh"
#include "Generic.hh"
+#include "Specific.hh"
#include <stdint.h>
#include <vector>
@@ -762,16 +763,14 @@ void testGeneric(const TestData& td) {
DecoderPtr d1 = CodecFactory::newDecoder(vs);
auto_ptr<InputStream> in1 = memoryInputStream(*p);
d1->init(*in1);
- GenericReader gr(vs, d1);
- GenericDatum datum;
- gr.read(datum);
+ GenericDatum datum(vs);
+ avro::decode(*d1, datum);
EncoderPtr e2 = CodecFactory::newEncoder(vs);
auto_ptr<OutputStream> ob = memoryOutputStream();
e2->init(*ob);
- GenericWriter gw(vs, e2);
- gw.write(datum);
+ avro::encode(*e2, datum);
e2->flush();
BOOST_TEST_CHECKPOINT("Test: " << testNo << ' '
@@ -813,9 +812,7 @@ void testGenericResolving(const TestData
EncoderPtr e2 = CodecFactory::newEncoder(rvs);
auto_ptr<OutputStream> ob = memoryOutputStream();
e2->init(*ob);
-
- GenericWriter gw(rvs, e2);
- gw.write(datum);
+ avro::encode(*e2, datum);
e2->flush();
BOOST_TEST_CHECKPOINT("Test: " << testNo << ' '
@@ -859,9 +856,7 @@ void testGenericResolving2(const TestDat
EncoderPtr e2 = CodecFactory::newEncoder(rvs);
auto_ptr<OutputStream> ob = memoryOutputStream();
e2->init(*ob);
-
- GenericWriter gw(rvs, e2);
- gw.write(datum);
+ avro::encode(*e2, datum);
e2->flush();
// We cannot verify with the reader calls because they are for
// the resolving decoder and hence could be in a different order than