19 #ifndef avro_NodeImpl_hh__
20 #define avro_NodeImpl_hh__
23 #include "GenericDatum.hh"
27 #include <boost/weak_ptr.hpp>
30 #include "NodeConcepts.hh"
41 class LeafNamesConcept,
53 leafNameAttributes_(),
58 const NameConcept &name,
59 const LeavesConcept &leaves,
60 const LeafNamesConcept &leafNames,
61 const SizeConcept &size) :
64 leafAttributes_(leaves),
65 leafNameAttributes_(leafNames),
70 std::swap(nameAttribute_, impl.nameAttribute_);
71 std::swap(leafAttributes_, impl.leafAttributes_);
72 std::swap(leafNameAttributes_, impl.leafNameAttributes_);
73 std::swap(sizeAttribute_, impl.sizeAttribute_);
74 std::swap(nameIndex_, impl.nameIndex_);
77 bool hasName()
const {
78 return NameConcept::hasAttribute;
81 void doSetName(
const Name &name) {
82 nameAttribute_.add(name);
85 const Name &name()
const {
86 return nameAttribute_.get();
89 void doAddLeaf(
const NodePtr &newLeaf) {
90 leafAttributes_.add(newLeaf);
93 size_t leaves()
const {
94 return leafAttributes_.size();
97 const NodePtr &leafAt(
int index)
const {
98 return leafAttributes_.get(index);
101 void doAddName(
const std::string &name) {
102 if (! nameIndex_.add(name, leafNameAttributes_.size())) {
103 throw Exception(boost::format(
"Cannot add duplicate name: %1%") % name);
105 leafNameAttributes_.add(name);
108 size_t names()
const {
109 return leafNameAttributes_.size();
112 const std::string &nameAt(
int index)
const {
113 return leafNameAttributes_.get(index);
116 bool nameIndex(
const std::string &name,
size_t &index)
const {
117 return nameIndex_.lookup(name, index);
120 void doSetFixedSize(
int size) {
121 sizeAttribute_.add(size);
124 int fixedSize()
const {
125 return sizeAttribute_.get();
128 virtual bool isValid()
const = 0;
130 void printBasicInfo(std::ostream &os)
const;
132 void setLeafToSymbolic(
int index,
const NodePtr &node);
140 const NodePtr &node = reader.leafAt(0);
141 match = resolve(*node);
149 for(
size_t i= 0; i < reader.leaves(); ++i) {
151 const NodePtr &node = reader.leafAt(i);
171 NameConcept nameAttribute_;
172 LeavesConcept leafAttributes_;
173 LeafNamesConcept leafNameAttributes_;
174 SizeConcept sizeAttribute_;
206 NodeImplPrimitive(type)
211 void printJson(std::ostream &os,
int depth)
const;
213 bool isValid()
const {
220 typedef boost::weak_ptr<Node> NodeWeakPtr;
229 NodeImplSymbolic(
AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoSize())
233 NodeImplSymbolic(
AVRO_SYMBOLIC, name, NoLeaves(), NoLeafNames(), NoSize()), actualNode_(n)
237 void printJson(std::ostream &os,
int depth)
const;
239 bool isValid()
const {
240 return (nameAttribute_.size() == 1);
244 return (actualNode_.lock() != 0);
247 NodePtr getNode()
const {
248 NodePtr node = actualNode_.lock();
250 throw Exception(boost::format(
"Could not follow symbol %1%") % name());
255 void setNode(
const NodePtr &node) {
261 NodeWeakPtr actualNode_;
266 std::vector<GenericDatum> defaultValues;
269 NodeRecord(
const HasName &name,
const MultiLeaves &fields,
270 const LeafNames &fieldsNames,
271 const std::vector<GenericDatum>& dv) :
272 NodeImplRecord(
AVRO_RECORD, name, fields, fieldsNames, NoSize()),
274 for (
size_t i = 0; i < leafNameAttributes_.size(); ++i) {
275 if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
277 "Cannot add duplicate name: %1%") %
278 leafNameAttributes_.get(i));
284 NodeImplRecord::swap(r);
285 defaultValues.swap(r.defaultValues);
290 void printJson(std::ostream &os,
int depth)
const;
292 bool isValid()
const {
293 return ((nameAttribute_.size() == 1) &&
294 (leafAttributes_.size() == leafNameAttributes_.size()));
298 return defaultValues[index];
310 NodeEnum(
const HasName &name,
const LeafNames &symbols) :
311 NodeImplEnum(
AVRO_ENUM, name, NoLeaves(), symbols, NoSize())
313 for(
size_t i=0; i < leafNameAttributes_.size(); ++i) {
314 if(!nameIndex_.add(leafNameAttributes_.get(i), i)) {
315 throw Exception(boost::format(
"Cannot add duplicate name: %1%") % leafNameAttributes_.get(i));
322 void printJson(std::ostream &os,
int depth)
const;
324 bool isValid()
const {
326 (nameAttribute_.size() == 1) &&
327 (leafNameAttributes_.size() > 0)
340 explicit NodeArray(
const SingleLeaf &items) :
341 NodeImplArray(
AVRO_ARRAY, NoName(), items, NoLeafNames(), NoSize())
346 void printJson(std::ostream &os,
int depth)
const;
348 bool isValid()
const {
349 return (leafAttributes_.size() == 1);
364 explicit NodeMap(
const SingleLeaf &values) :
365 NodeImplMap(
AVRO_MAP, NoName(), values, NoLeafNames(), NoSize())
372 std::swap(leafAttributes_.get(0), leafAttributes_.get(1));
377 void printJson(std::ostream &os,
int depth)
const;
379 bool isValid()
const {
380 return (leafAttributes_.size() == 2);
392 explicit NodeUnion(
const MultiLeaves &types) :
393 NodeImplUnion(
AVRO_UNION, NoName(), types, NoLeafNames(), NoSize())
398 void printJson(std::ostream &os,
int depth)
const;
400 bool isValid()
const {
401 std::set<std::string> seen;
402 if (leafAttributes_.size() >= 1) {
403 for (
size_t i = 0; i < leafAttributes_.size(); ++i) {
405 const NodePtr& n = leafAttributes_.get(i);
442 name = n->name().fullname();
447 if (seen.find(name) != seen.end()) {
466 NodeFixed(
const HasName &name,
const HasSize &size) :
467 NodeImplFixed(
AVRO_FIXED, name, NoLeaves(), NoLeafNames(), size)
472 void printJson(std::ostream &os,
int depth)
const;
474 bool isValid()
const {
476 (nameAttribute_.size() == 1) &&
477 (sizeAttribute_.size() == 1)
482 template <
class A,
class B,
class C,
class D >
486 if(!B::hasAttribute) {
487 throw Exception(
"Cannot change leaf node for nonexistent leaf");
490 NodePtr &replaceNode =
const_cast<NodePtr &
>(leafAttributes_.get(index));
491 if(replaceNode->name() != node->name()) {
492 throw Exception(
"Symbolic name does not match the name of the schema it references");
495 NodePtr symbol(
new NodeSymbolic);
496 NodeSymbolic *ptr =
static_cast<NodeSymbolic *
> (symbol.get());
498 ptr->setName(node->name());
500 replaceNode.swap(symbol);
503 template <
class A,
class B,
class C,
class D >
505 NodeImpl<A,B,C,D>::printBasicInfo(std::ostream &os)
const
509 os <<
' ' << nameAttribute_.get();
512 if(D::hasAttribute) {
513 os <<
" " << sizeAttribute_.get();
516 int count = leaves();
517 count = count ? count : names();
518 for(
int i= 0; i < count; ++i) {
519 if( C::hasAttribute ) {
520 os <<
"name " << nameAt(i) <<
'\n';
522 if( type() !=
AVRO_SYMBOLIC && leafAttributes_.hasAttribute) {
523 leafAt(i)->printBasicInfo(os);
527 os <<
"end " << type() <<
'\n';
532 inline NodePtr resolveSymbol(
const NodePtr &node)
535 throw Exception(
"Only symbolic nodes may be resolved");
537 boost::shared_ptr<NodeSymbolic> symNode = boost::static_pointer_cast<NodeSymbolic>(node);
538 return symNode->getNode();
Node is the building block for parse trees.
Definition: Node.hh:88
Definition: NodeImpl.hh:302
The schemas match at a cursory level.
Definition: SchemaResolution.hh:38
Type
The "type" for the schema.
Definition: Types.hh:31
A bunch of templates and specializations for encoding and decoding specific types.
Definition: AvroParse.hh:31
Definition: NodeImpl.hh:218
Definition: NodeImpl.hh:332
SchemaResolution
Definition: SchemaResolution.hh:27
Definition: NodeImpl.hh:201
Definition: NodeImpl.hh:353
Definition: NodeConcepts.hh:132
Definition: NodeConcepts.hh:86
The schemas definitely do not match.
Definition: SchemaResolution.hh:31
Wrapper for std::runtime_error that provides convenience constructor for boost::format objects...
Definition: Exception.hh:31
Definition: NodeConcepts.hh:51
Definition: NodeImpl.hh:265
Implementation details for Node.
Definition: NodeImpl.hh:44
Definition: NodeImpl.hh:384
bool isCompound(Type t)
Returns true if and only if the given type is a non primitive valid type.
Definition: Types.hh:72
Generic datum which can hold any Avro type.
Definition: GenericDatum.hh:55
Definition: NodeImpl.hh:458