| 90 | } |
| 91 | |
| 92 | void printAttributes(std::ostream& out, const orc::Type& type, const std::string& name, |
| 93 | bool* hasAnyAttributes) { |
| 94 | const auto& attributeKeys = type.getAttributeKeys(); |
| 95 | bool typeHasAttrs = !attributeKeys.empty(); |
| 96 | if (typeHasAttrs) { |
| 97 | // 'hasAnyAttributes' is only needed to deal with commas properly. |
| 98 | if (*hasAnyAttributes) { |
| 99 | out << ','; |
| 100 | } else { |
| 101 | *hasAnyAttributes = true; |
| 102 | } |
| 103 | out << "\n \"" << name << "\": {"; |
| 104 | } |
| 105 | for (uint64_t i = 0; i < attributeKeys.size(); ++i) { |
| 106 | const auto& key = attributeKeys[i]; |
| 107 | const auto& value = type.getAttributeValue(key); |
| 108 | out << "\"" << key << "\": \"" << value << "\""; |
| 109 | if (i < attributeKeys.size() - 1) { |
| 110 | out << ", "; |
| 111 | } |
| 112 | } |
| 113 | if (typeHasAttrs) { |
| 114 | out << '}'; |
| 115 | } |
| 116 | for (uint64_t i = 0; i < type.getSubtypeCount(); ++i) { |
| 117 | const auto& child = *type.getSubtype(i); |
| 118 | std::string fieldName; |
| 119 | if (type.getKind() == orc::STRUCT) { |
| 120 | fieldName = type.getFieldName(i); |
| 121 | } else if (type.getKind() == orc::LIST) { |
| 122 | fieldName = "_elem"; |
| 123 | } else if (type.getKind() == orc::MAP) { |
| 124 | fieldName = i == 0 ? "_key" : "_value"; |
| 125 | } else { |
| 126 | fieldName = "_field_" + std::to_string(i); |
| 127 | } |
| 128 | std::string childName = (name.empty() ? "" : name + '.') + fieldName; |
| 129 | printAttributes(out, child, childName, hasAnyAttributes); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | void printMetadata(std::ostream& out, const char* filename, bool verbose) { |
| 134 | orc::ReaderOptions readerOpts; |
no test coverage detected