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 |