| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright Contributors to the OpenVDB Project | ||
| 2 | // SPDX-License-Identifier: MPL-2.0 | ||
| 3 | |||
| 4 | #include "MetaMap.h" | ||
| 5 | |||
| 6 | #include "util/logging.h" | ||
| 7 | #include <sstream> | ||
| 8 | |||
| 9 | |||
| 10 | namespace openvdb { | ||
| 11 | OPENVDB_USE_VERSION_NAMESPACE | ||
| 12 | namespace OPENVDB_VERSION_NAME { | ||
| 13 | |||
| 14 |
1/2✓ Branch 1 taken 2866 times.
✗ Branch 2 not taken.
|
2866 | MetaMap::MetaMap(const MetaMap& other) |
| 15 | { | ||
| 16 |
1/2✓ Branch 1 taken 2866 times.
✗ Branch 2 not taken.
|
2866 | this->insertMeta(other); |
| 17 | 2866 | } | |
| 18 | |||
| 19 | |||
| 20 | MetaMap::Ptr | ||
| 21 | 12 | MetaMap::copyMeta() const | |
| 22 | { | ||
| 23 | 12 | MetaMap::Ptr ret(new MetaMap); | |
| 24 | ret->mMeta = this->mMeta; | ||
| 25 | 12 | return ret; | |
| 26 | } | ||
| 27 | |||
| 28 | |||
| 29 | MetaMap::Ptr | ||
| 30 | ✗ | MetaMap::deepCopyMeta() const | |
| 31 | { | ||
| 32 | ✗ | return MetaMap::Ptr(new MetaMap(*this)); | |
| 33 | } | ||
| 34 | |||
| 35 | |||
| 36 | MetaMap& | ||
| 37 | 7578 | MetaMap::operator=(const MetaMap& other) | |
| 38 | { | ||
| 39 |
1/2✓ Branch 0 taken 7578 times.
✗ Branch 1 not taken.
|
7578 | if (&other != this) { |
| 40 | this->clearMetadata(); | ||
| 41 | // Insert all metadata into this map. | ||
| 42 | 7578 | ConstMetaIterator iter = other.beginMeta(); | |
| 43 |
2/2✓ Branch 0 taken 1166 times.
✓ Branch 1 taken 7578 times.
|
8744 | for ( ; iter != other.endMeta(); ++iter) { |
| 44 | 1166 | this->insertMeta(iter->first, *(iter->second)); | |
| 45 | } | ||
| 46 | } | ||
| 47 | 7578 | return *this; | |
| 48 | } | ||
| 49 | |||
| 50 | |||
| 51 | void | ||
| 52 | 222 | MetaMap::readMeta(std::istream &is) | |
| 53 | { | ||
| 54 | // Clear out the current metamap if need be. | ||
| 55 | this->clearMetadata(); | ||
| 56 | |||
| 57 | // Read in the number of metadata items. | ||
| 58 | 222 | Index32 count = 0; | |
| 59 | 222 | is.read(reinterpret_cast<char*>(&count), sizeof(Index32)); | |
| 60 | |||
| 61 | // Read in each metadata. | ||
| 62 |
2/2✓ Branch 0 taken 833 times.
✓ Branch 1 taken 222 times.
|
1055 | for (Index32 i = 0; i < count; ++i) { |
| 63 | // Read in the name. | ||
| 64 | 833 | Name name = readString(is); | |
| 65 | |||
| 66 | // Read in the metadata typename. | ||
| 67 |
1/2✓ Branch 1 taken 833 times.
✗ Branch 2 not taken.
|
833 | Name typeName = readString(is); |
| 68 | |||
| 69 | // Read in the metadata value and add it to the map. | ||
| 70 |
3/4✓ Branch 1 taken 833 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 823 times.
✓ Branch 4 taken 10 times.
|
833 | if (Metadata::isRegisteredType(typeName)) { |
| 71 |
1/2✓ Branch 1 taken 823 times.
✗ Branch 2 not taken.
|
823 | Metadata::Ptr metadata = Metadata::createMetadata(typeName); |
| 72 |
1/2✓ Branch 1 taken 823 times.
✗ Branch 2 not taken.
|
823 | metadata->read(is); |
| 73 |
1/2✓ Branch 1 taken 823 times.
✗ Branch 2 not taken.
|
823 | insertMeta(name, *metadata); |
| 74 | } else { | ||
| 75 | 10 | UnknownMetadata metadata(typeName); | |
| 76 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | metadata.read(is); // read raw bytes into an array |
| 77 | // only add unknown metadata to the grid if not temporary, | ||
| 78 | // denoted by a double underscore prefix (such as __metadata) | ||
| 79 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | bool temporary = typeName.compare(0, 2, "__") == 0; |
| 80 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
|
10 | if (!temporary) { |
| 81 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | insertMeta(name, metadata); |
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | 222 | } | |
| 86 | |||
| 87 | |||
| 88 | void | ||
| 89 | 247 | MetaMap::writeMeta(std::ostream &os) const | |
| 90 | { | ||
| 91 | // Write out the number of metadata items we have in the map. Note that we | ||
| 92 | // save as Index32 to save a 32-bit number. Using size_t would be platform | ||
| 93 | // dependent. | ||
| 94 | 247 | Index32 count = static_cast<Index32>(metaCount()); | |
| 95 | 247 | os.write(reinterpret_cast<char*>(&count), sizeof(Index32)); | |
| 96 | |||
| 97 | // Iterate through each metadata and write it out. | ||
| 98 |
2/2✓ Branch 0 taken 1092 times.
✓ Branch 1 taken 247 times.
|
1339 | for (ConstMetaIterator iter = beginMeta(); iter != endMeta(); ++iter) { |
| 99 | // Write the name of the metadata. | ||
| 100 | 1092 | writeString(os, iter->first); | |
| 101 | |||
| 102 | // Write the type name of the metadata. | ||
| 103 |
1/2✓ Branch 2 taken 1092 times.
✗ Branch 3 not taken.
|
2184 | writeString(os, iter->second->typeName()); |
| 104 | |||
| 105 | // Write out the metadata value. | ||
| 106 | iter->second->write(os); | ||
| 107 | } | ||
| 108 | 247 | } | |
| 109 | |||
| 110 | |||
| 111 | void | ||
| 112 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23802 times.
|
23802 | MetaMap::insertMeta(const Name &name, const Metadata &m) |
| 113 | { | ||
| 114 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 23802 times.
|
23802 | if (name.size() == 0) |
| 115 | ✗ | OPENVDB_THROW(ValueError, "Metadata name cannot be an empty string"); | |
| 116 | |||
| 117 | // See if the value already exists, if so then replace the existing one. | ||
| 118 |
2/2✓ Branch 0 taken 23690 times.
✓ Branch 1 taken 112 times.
|
23802 | MetaIterator iter = mMeta.find(name); |
| 119 | |||
| 120 |
2/2✓ Branch 0 taken 23690 times.
✓ Branch 1 taken 112 times.
|
23802 | if (iter == mMeta.end()) { |
| 121 | // Create a copy of the metadata and store it in the map | ||
| 122 | 23690 | Metadata::Ptr tmp = m.copy(); | |
| 123 |
1/2✓ Branch 1 taken 23690 times.
✗ Branch 2 not taken.
|
23690 | mMeta[name] = tmp; |
| 124 | } else { | ||
| 125 |
2/4✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 112 times.
|
224 | if (iter->second->typeName() != m.typeName()) { |
| 126 | ✗ | std::ostringstream ostr; | |
| 127 | ostr << "Cannot assign value of type " | ||
| 128 | ✗ | << m.typeName() << " to metadata attribute " << name | |
| 129 | ✗ | << " of " << "type " << iter->second->typeName(); | |
| 130 | ✗ | OPENVDB_THROW(TypeError, ostr.str()); | |
| 131 | } | ||
| 132 | // else | ||
| 133 | 112 | Metadata::Ptr tmp = m.copy(); | |
| 134 | iter->second = tmp; | ||
| 135 | } | ||
| 136 | 23802 | } | |
| 137 | |||
| 138 | |||
| 139 | void | ||
| 140 | 2882 | MetaMap::insertMeta(const MetaMap& other) | |
| 141 | { | ||
| 142 |
2/2✓ Branch 0 taken 1483 times.
✓ Branch 1 taken 2882 times.
|
4365 | for (ConstMetaIterator it = other.beginMeta(), end = other.endMeta(); it != end; ++it) { |
| 143 |
1/2✓ Branch 0 taken 1483 times.
✗ Branch 1 not taken.
|
1483 | if (it->second) this->insertMeta(it->first, *it->second); |
| 144 | } | ||
| 145 | 2882 | } | |
| 146 | |||
| 147 | |||
| 148 | void | ||
| 149 | 14350 | MetaMap::removeMeta(const Name &name) | |
| 150 | { | ||
| 151 |
2/2✓ Branch 0 taken 831 times.
✓ Branch 1 taken 13519 times.
|
14350 | MetaIterator iter = mMeta.find(name); |
| 152 |
2/2✓ Branch 0 taken 831 times.
✓ Branch 1 taken 13519 times.
|
14350 | if (iter != mMeta.end()) { |
| 153 | 831 | mMeta.erase(iter); | |
| 154 | } | ||
| 155 | 14350 | } | |
| 156 | |||
| 157 | |||
| 158 | bool | ||
| 159 |
2/2✓ Branch 0 taken 6217 times.
✓ Branch 1 taken 3 times.
|
6220 | MetaMap::operator==(const MetaMap& other) const |
| 160 | { | ||
| 161 | // Check if the two maps have the same number of elements. | ||
| 162 |
2/2✓ Branch 0 taken 6217 times.
✓ Branch 1 taken 3 times.
|
6220 | if (this->mMeta.size() != other.mMeta.size()) return false; |
| 163 | // Iterate over the two maps in sorted order. | ||
| 164 | 6217 | for (ConstMetaIterator it = beginMeta(), otherIt = other.beginMeta(), end = endMeta(); | |
| 165 |
2/2✓ Branch 0 taken 221 times.
✓ Branch 1 taken 6209 times.
|
6430 | it != end; ++it, ++otherIt) |
| 166 | { | ||
| 167 | // Check if the two keys match. | ||
| 168 |
2/2✓ Branch 0 taken 219 times.
✓ Branch 1 taken 2 times.
|
227 | if (it->first != otherIt->first) return false; |
| 169 | // Check if the two values are either both null or both non-null pointers. | ||
| 170 |
1/2✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
|
219 | if (bool(it->second) != bool(otherIt->second)) return false; |
| 171 | // If the two values are both non-null, compare their contents. | ||
| 172 |
4/6✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 219 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 213 times.
✓ Branch 5 taken 6 times.
|
438 | if (it->second && otherIt->second && *it->second != *otherIt->second) return false; |
| 173 | } | ||
| 174 | 6209 | return true; | |
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | std::string | ||
| 179 | 16 | MetaMap::str(const std::string& indent) const | |
| 180 | { | ||
| 181 | 32 | std::ostringstream ostr; | |
| 182 | 16 | char sep[2] = { 0, 0 }; | |
| 183 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
|
64 | for (ConstMetaIterator iter = beginMeta(); iter != endMeta(); ++iter) { |
| 184 | ostr << sep << indent << iter->first; | ||
| 185 |
1/2✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
|
48 | if (iter->second) { |
| 186 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | const std::string value = iter->second->str(); |
| 187 |
1/2✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
|
48 | if (!value.empty()) ostr << ": " << value; |
| 188 | } | ||
| 189 | 48 | sep[0] = '\n'; | |
| 190 | } | ||
| 191 | 16 | return ostr.str(); | |
| 192 | } | ||
| 193 | |||
| 194 | std::ostream& | ||
| 195 | ✗ | operator<<(std::ostream& ostr, const MetaMap& metamap) | |
| 196 | { | ||
| 197 | ✗ | ostr << metamap.str(); | |
| 198 | ✗ | return ostr; | |
| 199 | } | ||
| 200 | |||
| 201 | } // namespace OPENVDB_VERSION_NAME | ||
| 202 | } // namespace openvdb | ||
| 203 |