19 #ifndef avro_NodeImpl_hh__
20 #define avro_NodeImpl_hh__
23 #include "GenericDatum.hh"
34 #include "NodeConcepts.hh"
35 #include "CustomAttributes.hh"
45 class LeafNamesConcept,
46 class MultiAttributesConcept,
55 leafNameAttributes_(),
60 const NameConcept &name,
61 const LeavesConcept &leaves,
62 const LeafNamesConcept &leafNames,
63 const MultiAttributesConcept &customAttributes,
64 const SizeConcept &size) :
Node(type),
68 leafNameAttributes_(leafNames),
69 customAttributes_(customAttributes),
70 sizeAttribute_(size) {}
74 const NameConcept &name,
76 const LeavesConcept &leaves,
77 const LeafNamesConcept &leafNames,
78 const MultiAttributesConcept &customAttributes,
79 const SizeConcept &size) :
Node(type),
83 leafNameAttributes_(leafNames),
84 customAttributes_(customAttributes),
85 sizeAttribute_(size) {}
88 std::swap(nameAttribute_, impl.nameAttribute_);
89 std::swap(docAttribute_, impl.docAttribute_);
91 std::swap(leafNameAttributes_, impl.leafNameAttributes_);
92 std::swap(sizeAttribute_, impl.sizeAttribute_);
93 std::swap(customAttributes_, impl.customAttributes_);
94 std::swap(nameIndex_, impl.nameIndex_);
97 bool hasName()
const override {
99 return NameConcept::hasAttribute;
102 void doSetName(
const Name &name)
override {
103 nameAttribute_.add(name);
106 const Name &name()
const override {
107 return nameAttribute_.get();
110 void doSetDoc(
const std::string &doc)
override {
111 docAttribute_.add(doc);
114 const std::string &getDoc()
const override {
115 return docAttribute_.get();
118 void doAddLeaf(
const NodePtr &newLeaf)
final {
122 size_t leaves()
const override {
126 const NodePtr &leafAt(
size_t index)
const override {
130 void doAddName(
const std::string &name)
override {
131 if (!nameIndex_.add(name, leafNameAttributes_.size())) {
132 throw Exception(boost::format(
"Cannot add duplicate name: %1%") % name);
134 leafNameAttributes_.add(name);
137 size_t names()
const override {
138 return leafNameAttributes_.size();
141 const std::string &nameAt(
size_t index)
const override {
142 return leafNameAttributes_.get(index);
145 bool nameIndex(
const std::string &name,
size_t &index)
const override {
146 return nameIndex_.lookup(name, index);
149 void doSetFixedSize(
size_t size)
override {
150 sizeAttribute_.add(size);
153 size_t fixedSize()
const override {
154 return sizeAttribute_.get();
157 bool isValid()
const override = 0;
159 void printBasicInfo(std::ostream &os)
const override;
161 void setLeafToSymbolic(
size_t index,
const NodePtr &node)
override;
163 void doAddCustomAttribute(
const CustomAttributes &customAttributes)
override {
164 customAttributes_.add(customAttributes);
173 const NodePtr &node = reader.leafAt(0);
174 match = resolve(*node);
181 for (
size_t i = 0; i < reader.leaves(); ++i) {
183 const NodePtr &node = reader.leafAt(i);
203 NameConcept nameAttribute_;
209 LeafNamesConcept leafNameAttributes_;
210 MultiAttributesConcept customAttributes_;
211 SizeConcept sizeAttribute_;
248 void printJson(std::ostream &os,
size_t depth)
const override;
250 bool isValid()
const override {
254 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
258 using NodeWeakPtr = std::weak_ptr<Node>;
268 void printJson(std::ostream &os,
size_t depth)
const override;
270 bool isValid()
const override {
271 return (nameAttribute_.size() == 1);
274 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
277 return (actualNode_.lock() !=
nullptr);
280 NodePtr getNode()
const {
281 NodePtr node = actualNode_.lock();
283 throw Exception(boost::format(
"Could not follow symbol %1%") % name());
288 void setNode(
const NodePtr &node) {
293 NodeWeakPtr actualNode_;
297 std::vector<GenericDatum> defaultValues;
303 std::vector<GenericDatum> dv);
308 defaultValues(std::move(dv)) {
314 const std::vector<GenericDatum>& dv,
323 const std::vector<GenericDatum>& dv,
331 NodeImplRecord::swap(r);
332 defaultValues.swap(r.defaultValues);
337 void printJson(std::ostream &os,
size_t depth)
const override;
339 bool isValid()
const override {
340 return ((nameAttribute_.size() == 1) &&
341 (leafAttributes_.size() == leafNameAttributes_.size()) &&
342 (customAttributes_.size() == 0 ||
343 customAttributes_.size() == leafAttributes_.size()));
346 const GenericDatum &defaultValueAt(
size_t index)
override {
347 return defaultValues[index];
350 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
354 void leafNameCheck() {
355 for (
size_t i = 0; i < leafNameAttributes_.size(); ++i) {
356 if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
358 "Cannot add duplicate field: %1%")
359 % leafNameAttributes_.get(i));
370 for (
size_t i = 0; i < leafNameAttributes_.size(); ++i) {
371 if (!nameIndex_.add(leafNameAttributes_.get(i), i)) {
372 throw Exception(boost::format(
"Cannot add duplicate enum: %1%") % leafNameAttributes_.get(i));
379 void printJson(std::ostream &os,
size_t depth)
const override;
381 bool isValid()
const override {
383 (nameAttribute_.size() == 1) && (leafNameAttributes_.size() > 0));
386 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
397 void printJson(std::ostream &os,
size_t depth)
const override;
399 bool isValid()
const override {
400 return (leafAttributes_.size() == 1);
403 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
416 std::swap(leafAttributes_.get(0), leafAttributes_.get(1));
421 void printJson(std::ostream &os,
size_t depth)
const override;
423 bool isValid()
const override {
424 return (leafAttributes_.size() == 2);
427 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
438 void printJson(std::ostream &os,
size_t depth)
const override;
440 bool isValid()
const override {
441 std::set<std::string> seen;
442 if (leafAttributes_.size() >= 1) {
443 for (
size_t i = 0; i < leafAttributes_.size(); ++i) {
445 const NodePtr &n = leafAttributes_.get(i);
482 name = n->name().fullname();
484 default:
return false;
486 if (seen.find(name) != seen.end()) {
496 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
507 void printJson(std::ostream &os,
size_t depth)
const override;
509 bool isValid()
const override {
511 (nameAttribute_.size() == 1) && (sizeAttribute_.size() == 1));
514 void printDefaultToJson(
const GenericDatum &g, std::ostream &os,
size_t depth)
const override;
517 template<
class A,
class B,
class C,
class D,
class E>
520 if (!B::hasAttribute) {
521 throw Exception(
"Cannot change leaf node for nonexistent leaf");
524 auto &replaceNode =
const_cast<NodePtr &
>(leafAttributes_.get(index));
525 if (replaceNode->name() != node->name()) {
526 throw Exception(
"Symbolic name does not match the name of the schema it references");
529 auto symbol = std::make_shared<NodeSymbolic>();
530 symbol->setName(node->name());
531 symbol->setNode(node);
532 replaceNode = symbol;
535 template<
class A,
class B,
class C,
class D,
class E>
537 NodeImpl<A, B, C, D, E>::printBasicInfo(std::ostream &os)
const {
540 os <<
' ' << nameAttribute_.get();
543 if (E::hasAttribute) {
544 os <<
" " << sizeAttribute_.get();
547 size_t count = leaves();
548 count = count ? count : names();
549 for (
size_t i = 0; i < count; ++i) {
550 if (C::hasAttribute) {
551 os <<
"name " << nameAt(i) <<
'\n';
553 if (type() !=
AVRO_SYMBOLIC && leafAttributes_.hasAttribute) {
554 leafAt(i)->printBasicInfo(os);
558 os <<
"end " << type() <<
'\n';
562 inline NodePtr resolveSymbol(
const NodePtr &node) {
564 throw Exception(
"Only symbolic nodes may be resolved");
566 std::shared_ptr<NodeSymbolic> symNode = std::static_pointer_cast<NodeSymbolic>(node);
567 return symNode->getNode();
571 inline std::string intToHex(T i) {
572 std::stringstream stream;
574 << std::setfill(
'0') << std::setw(
sizeof(T))