00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef avro_Generic_hh__
00020 #define avro_Generic_hh__
00021
00022 #include <vector>
00023 #include <map>
00024 #include <string>
00025
00026 #include <boost/any.hpp>
00027 #include <boost/utility.hpp>
00028
00029 #include "Config.hh"
00030 #include "Node.hh"
00031 #include "Types.hh"
00032 #include "Encoder.hh"
00033 #include "Decoder.hh"
00034 #include "ValidSchema.hh"
00035
00036 namespace avro {
00059 class AVRO_DECL GenericDatum {
00060 Type type_;
00061 boost::any value_;
00062
00063 GenericDatum(Type t) : type_(t) { }
00064
00065 template <typename T>
00066 GenericDatum(Type t, const T& v) : type_(t), value_(v) { }
00067
00068 void init(const NodePtr& schema);
00069 public:
00073 Type type() const;
00074
00080 template<typename T> const T& value() const;
00081
00091 template<typename T> T& value();
00092
00096 bool isUnion() const { return type_ == AVRO_UNION; }
00097
00102 size_t unionBranch() const;
00103
00108 void selectBranch(size_t branch);
00109
00111 GenericDatum() : type_(AVRO_NULL) { }
00112
00114 GenericDatum(bool v) : type_(AVRO_BOOL), value_(v) { }
00115
00117 GenericDatum(int32_t v) : type_(AVRO_INT), value_(v) { }
00118
00120 GenericDatum(int64_t v) : type_(AVRO_LONG), value_(v) { }
00121
00123 GenericDatum(float v) : type_(AVRO_FLOAT), value_(v) { }
00124
00126 GenericDatum(double v) : type_(AVRO_DOUBLE), value_(v) { }
00127
00129 GenericDatum(const std::string& v) : type_(AVRO_STRING), value_(v) { }
00130
00133 GenericDatum(const std::vector<uint8_t>& v) :
00134 type_(AVRO_BYTES), value_(v) { }
00135
00142 GenericDatum(const NodePtr& schema);
00143
00150 GenericDatum(const ValidSchema& schema);
00151 };
00152
00156 class AVRO_DECL GenericContainer {
00157 NodePtr schema_;
00158 static void assertType(const NodePtr& schema, Type type);
00159 protected:
00163 GenericContainer(Type type, const NodePtr& s) : schema_(s) {
00164 assertType(s, type);
00165 }
00166
00167 public:
00169 const NodePtr& schema() const {
00170 return schema_;
00171 }
00172 };
00173
00177 class AVRO_DECL GenericUnion : public GenericContainer {
00178 size_t curBranch_;
00179 GenericDatum datum_;
00180
00181 public:
00187 GenericUnion(const NodePtr& schema) :
00188 GenericContainer(AVRO_UNION, schema), curBranch_(schema->leaves()) {
00189 }
00190
00194 size_t currentBranch() const { return curBranch_; }
00195
00200 void selectBranch(size_t branch) {
00201 if (curBranch_ != branch) {
00202 datum_ = GenericDatum(schema()->leafAt(branch));
00203 curBranch_ = branch;
00204 }
00205 }
00206
00210 Type type() const {
00211 return datum_.type();
00212 }
00213
00217 template<typename T>
00218 const T& value() const {
00219 return datum_.value<T>();
00220 }
00221
00225 template<typename T>
00226 T& value() {
00227 return datum_.value<T>();
00228 }
00229
00230 };
00231
00235 class AVRO_DECL GenericRecord : public GenericContainer {
00236 std::vector<GenericDatum> fields_;
00237 public:
00242 GenericRecord(const NodePtr& schema);
00243
00247 size_t fieldCount() const {
00248 return fields_.size();
00249 }
00250
00254 const GenericDatum& fieldAt(size_t pos) const {
00255 return fields_[pos];
00256 }
00257
00262 GenericDatum& fieldAt(size_t pos) {
00263 return fields_[pos];
00264 }
00265
00269 void setFieldAt(size_t pos, const GenericDatum& v) {
00270
00271 fields_[pos] = v;
00272 }
00273 };
00274
00278 class AVRO_DECL GenericArray : public GenericContainer {
00279 public:
00283 typedef std::vector<GenericDatum> Value;
00284
00289 GenericArray(const NodePtr& schema) : GenericContainer(AVRO_ARRAY, schema) {
00290 }
00291
00295 const Value& value() const {
00296 return value_;
00297 }
00298
00302 Value& value() {
00303 return value_;
00304 }
00305 private:
00306 Value value_;
00307 };
00308
00312 class AVRO_DECL GenericMap : public GenericContainer {
00313 public:
00317 typedef std::vector<std::pair<std::string, GenericDatum> > Value;
00318
00323 GenericMap(const NodePtr& schema) : GenericContainer(AVRO_MAP, schema) {
00324 }
00325
00329 const Value& value() const {
00330 return value_;
00331 }
00332
00336 Value& value() {
00337 return value_;
00338 }
00339 private:
00340 Value value_;
00341 };
00342
00346 class AVRO_DECL GenericEnum : public GenericContainer {
00347 size_t value_;
00348 public:
00353 GenericEnum(const NodePtr& schema) :
00354 GenericContainer(AVRO_ENUM, schema), value_(0) {
00355 }
00356
00361 const std::string& symbol(size_t n) {
00362 if (n < schema()->names()) {
00363 return schema()->nameAt(n);
00364 }
00365 throw Exception("Not as many symbols");
00366 }
00367
00372 size_t index(const std::string& symbol) const {
00373 size_t result;
00374 if (schema()->nameIndex(symbol, result)) {
00375 return result;
00376 }
00377 throw Exception("No such symbol");
00378 }
00379
00383 size_t set(const std::string& symbol) {
00384 return value_ = index(symbol);
00385 }
00386
00390 void set(size_t n) {
00391 if (n < schema()->names()) {
00392 value_ = n;
00393 return;
00394 }
00395 throw Exception("Not as many symbols");
00396 }
00397
00401 size_t value() const {
00402 return value_;
00403 }
00404
00408 const std::string& symbol() const {
00409 return schema()->nameAt(value_);
00410 }
00411 };
00412
00416 class AVRO_DECL GenericFixed : public GenericContainer {
00417 std::vector<uint8_t> value_;
00418 public:
00423 GenericFixed(const NodePtr& schema) : GenericContainer(AVRO_FIXED, schema) {
00424 value_.resize(schema->fixedSize());
00425 }
00426
00430 const std::vector<uint8_t>& value() const {
00431 return value_;
00432 }
00433
00437 std::vector<uint8_t>& value() {
00438 return value_;
00439 }
00440 };
00441
00442
00446 class AVRO_DECL GenericReader : boost::noncopyable {
00447 const ValidSchema schema_;
00448 const bool isResolving_;
00449 const DecoderPtr decoder_;
00450
00451 static void read(GenericDatum& datum, Decoder& d, bool isResolving);
00452 public:
00456 GenericReader(const ValidSchema& s, const DecoderPtr& decoder);
00457
00463 GenericReader(const ValidSchema& writerSchema,
00464 const ValidSchema& readerSchema, const DecoderPtr& decoder);
00465
00469 void read(GenericDatum& datum) const;
00470
00474 static void read(Decoder& d, GenericDatum& g);
00475
00479 static void read(Decoder& d, GenericDatum& g, const ValidSchema& s);
00480 };
00481
00482
00486 class AVRO_DECL GenericWriter : boost::noncopyable {
00487 const ValidSchema schema_;
00488 const EncoderPtr encoder_;
00489
00490 static void write(const GenericDatum& datum, Encoder& e);
00491 public:
00495 GenericWriter(const ValidSchema& s, const EncoderPtr& encoder);
00496
00500 void write(const GenericDatum& datum) const;
00501
00505 static void write(Encoder& e, const GenericDatum& g);
00506
00511 static void write(Encoder& e, const GenericDatum& g, const ValidSchema&) {
00512 write(e, g);
00513 }
00514 };
00515
00516 inline Type AVRO_DECL GenericDatum::type() const {
00517 return (type_ == AVRO_UNION) ?
00518 boost::any_cast<GenericUnion>(&value_)->type() : type_;
00519 }
00520
00521 template<typename T>
00522 const T& GenericDatum::value() const {
00523 return (type_ == AVRO_UNION) ?
00524 boost::any_cast<GenericUnion>(&value_)->value<T>() :
00525 *boost::any_cast<T>(&value_);
00526 }
00527
00528 template<typename T>
00529 T& GenericDatum::value() {
00530 return (type_ == AVRO_UNION) ?
00531 boost::any_cast<GenericUnion>(&value_)->value<T>() :
00532 *boost::any_cast<T>(&value_);
00533 }
00534
00535 inline size_t GenericDatum::unionBranch() const {
00536 return boost::any_cast<GenericUnion>(&value_)->currentBranch();
00537 }
00538
00539 inline void GenericDatum::selectBranch(size_t branch) {
00540 boost::any_cast<GenericUnion>(&value_)->selectBranch(branch);
00541 }
00542
00543 template <typename T> struct codec_traits;
00544
00550 template <> struct codec_traits<std::pair<ValidSchema, GenericDatum> > {
00552 static void encode(Encoder& e,
00553 const std::pair<ValidSchema, GenericDatum>& p) {
00554 GenericWriter::write(e, p.second, p.first);
00555 }
00556
00558 static void decode(Decoder& d, std::pair<ValidSchema, GenericDatum>& p) {
00559 GenericReader::read(d, p.second, p.first);
00560 }
00561 };
00562
00566 template <> struct codec_traits<GenericDatum> {
00568 static void encode(Encoder& e, const GenericDatum& g) {
00569 GenericWriter::write(e, g);
00570 }
00571
00573 static void decode(Decoder& d, GenericDatum& g) {
00574 GenericReader::read(d, g);
00575 }
00576 };
00577
00578 }
00579 #endif
00580