GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/io/File.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 12 12 100.0%
Functions: 2 2 100.0%
Branches: 11 20 55.0%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file File.h
5
6 #ifndef OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
7 #define OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
8
9 #include <openvdb/version.h>
10 #include "io.h" // for MappedFile::Notifier
11 #include "Archive.h"
12 #include "GridDescriptor.h"
13 #include <algorithm> // for std::copy()
14 #include <iosfwd>
15 #include <iterator> // for std::back_inserter()
16 #include <map>
17 #include <memory>
18 #include <string>
19
20
21 class TestFile;
22 class TestStream;
23
24 namespace openvdb {
25 OPENVDB_USE_VERSION_NAMESPACE
26 namespace OPENVDB_VERSION_NAME {
27 namespace io {
28
29 /// Grid archive associated with a file on disk
30 class OPENVDB_API File: public Archive
31 {
32 public:
33 using NameMap = std::multimap<Name, GridDescriptor>;
34 using NameMapCIter = NameMap::const_iterator;
35
36 explicit File(const std::string& filename);
37 ~File() override;
38
39 /// @brief Copy constructor
40 /// @details The copy will be closed and will not reference the same
41 /// file descriptor as the original.
42 File(const File& other);
43 /// @brief Assignment
44 /// @details After assignment, this File will be closed and will not
45 /// reference the same file descriptor as the source File.
46 File& operator=(const File& other);
47
48 /// @brief Return a copy of this archive.
49 /// @details The copy will be closed and will not reference the same
50 /// file descriptor as the original.
51 SharedPtr<Archive> copy() const override;
52
53 /// @brief Return the name of the file with which this archive is associated.
54 /// @details The file does not necessarily exist on disk yet.
55 const std::string& filename() const;
56
57 /// @brief Open the file, read the file header and the file-level metadata,
58 /// and populate the grid descriptors, but do not load any grids into memory.
59 /// @details If @a delayLoad is true, map the file into memory and enable delayed loading
60 /// of grids, and if a notifier is provided, call it when the file gets unmapped.
61 /// @note Define the environment variable @c OPENVDB_DISABLE_DELAYED_LOAD to disable
62 /// delayed loading unconditionally.
63 /// @throw IoError if the file is not a valid VDB file.
64 /// @return @c true if the file's UUID has changed since it was last read.
65 /// @see setCopyMaxBytes
66 bool open(bool delayLoad = true, const MappedFile::Notifier& = MappedFile::Notifier());
67
68 /// Return @c true if the file has been opened for reading.
69 bool isOpen() const;
70
71 /// Close the file once we are done reading from it.
72 void close();
73
74 /// @brief Return this file's current size on disk in bytes.
75 /// @throw IoError if the file size cannot be determined.
76 Index64 getSize() const;
77
78 /// @brief Return the size in bytes above which this file will not be
79 /// automatically copied during delayed loading.
80 Index64 copyMaxBytes() const;
81 /// @brief If this file is opened with delayed loading enabled, make a private copy
82 /// of the file if its size in bytes is less than the specified value.
83 /// @details Making a private copy ensures that the file can't change on disk
84 /// before it has been fully read.
85 /// @warning If the file is larger than this size, it is the user's responsibility
86 /// to ensure that it does not change on disk before it has been fully read.
87 /// Undefined behavior and/or a crash might result otherwise.
88 /// @note Copying is enabled by default, but it can be disabled for individual files
89 /// by setting the maximum size to zero bytes. A default size limit can be specified
90 /// by setting the environment variable @c OPENVDB_DELAYED_LOAD_COPY_MAX_BYTES
91 /// to the desired number of bytes.
92 void setCopyMaxBytes(Index64 bytes);
93
94 /// Return @c true if a grid of the given name exists in this file.
95 bool hasGrid(const Name&) const;
96
97 /// Return (in a newly created MetaMap) the file-level metadata.
98 MetaMap::Ptr getMetadata() const;
99
100 /// Read the entire contents of the file and return a list of grid pointers.
101 GridPtrVecPtr getGrids() const;
102
103 /// @brief Read just the grid metadata and transforms from the file and return a list
104 /// of pointers to grids that are empty except for their metadata and transforms.
105 /// @throw IoError if this file is not open for reading.
106 GridPtrVecPtr readAllGridMetadata();
107
108 /// @brief Read a grid's metadata and transform only.
109 /// @return A pointer to a grid that is empty except for its metadata and transform.
110 /// @throw IoError if this file is not open for reading.
111 /// @throw KeyError if no grid with the given name exists in this file.
112 GridBase::Ptr readGridMetadata(const Name&);
113
114 /// Read an entire grid, including all of its data blocks.
115 GridBase::Ptr readGrid(const Name&);
116 /// @brief Read a grid, including its data blocks, but only where it
117 /// intersects the given world-space bounding box.
118 GridBase::Ptr readGrid(const Name&, const BBoxd&);
119
120 /// @todo GridPtrVec readAllGrids(const Name&)
121
122 /// @brief Write the grids in the given container to the file whose name
123 /// was given in the constructor.
124 void write(const GridCPtrVec&, const MetaMap& = MetaMap()) const override;
125
126 /// @brief Write the grids in the given container to the file whose name
127 /// was given in the constructor.
128 template<typename GridPtrContainerT>
129 void write(const GridPtrContainerT&, const MetaMap& = MetaMap()) const;
130
131 /// A const iterator that iterates over all names in the file. This is only
132 /// valid once the file has been opened.
133 class OPENVDB_API NameIterator
134 {
135 public:
136 3 NameIterator(const NameMapCIter& iter): mIter(iter) {}
137 NameIterator(const NameIterator&) = default;
138 ~NameIterator() {}
139
140 6 NameIterator& operator++() { mIter++; return *this; }
141
142 bool operator==(const NameIterator& iter) const { return mIter == iter.mIter; }
143 bool operator!=(const NameIterator& iter) const { return mIter != iter.mIter; }
144
145 12 Name operator*() const { return this->gridName(); }
146
147
4/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
24 Name gridName() const { return GridDescriptor::nameAsString(mIter->second.uniqueName()); }
148
149 private:
150 NameMapCIter mIter;
151 };
152
153 /// @return a NameIterator to iterate over all grid names in the file.
154 NameIterator beginName() const;
155
156 /// @return the ending iterator for all grid names in the file.
157 NameIterator endName() const;
158
159 private:
160 /// Read in all grid descriptors that are stored in the given stream.
161 void readGridDescriptors(std::istream&);
162
163 /// @brief Return an iterator to the descriptor for the grid with the given name.
164 /// If the name is non-unique, return an iterator to the first matching descriptor.
165 NameMapCIter findDescriptor(const Name&) const;
166
167 /// Return a newly created, empty grid of the type specified by the given grid descriptor.
168 GridBase::Ptr createGrid(const GridDescriptor&) const;
169
170 /// @brief Read a grid, including its data blocks, but only where it
171 /// intersects the given world-space bounding box.
172 GridBase::Ptr readGridByName(const Name&, const BBoxd&);
173
174 /// Read in and return the partially-populated grid specified by the given grid descriptor.
175 GridBase::ConstPtr readGridPartial(const GridDescriptor&, bool readTopology) const;
176
177 /// Read in and return the grid specified by the given grid descriptor.
178 GridBase::Ptr readGrid(const GridDescriptor&) const;
179 /// Read in and return the region of the grid specified by the given grid descriptor
180 /// that intersects the given world-space bounding box.
181 GridBase::Ptr readGrid(const GridDescriptor&, const BBoxd&) const;
182 /// Read in and return the region of the grid specified by the given grid descriptor
183 /// that intersects the given index-space bounding box.
184 GridBase::Ptr readGrid(const GridDescriptor&, const CoordBBox&) const;
185
186 /// @brief Partially populate the given grid by reading its metadata and transform and,
187 /// if the grid is not an instance, its tree structure, but not the tree's leaf nodes.
188 void readGridPartial(GridBase::Ptr, std::istream&, bool isInstance, bool readTopology) const;
189
190 /// @brief Retrieve a grid from @c mNamedGrids. Return a null pointer
191 /// if @c mNamedGrids was not populated (because this file is random-access).
192 /// @throw KeyError if no grid with the given name exists in this file.
193 GridBase::Ptr retrieveCachedGrid(const Name&) const;
194
195 void writeGrids(const GridCPtrVec&, const MetaMap&) const;
196
197 MetaMap::Ptr fileMetadata();
198 MetaMap::ConstPtr fileMetadata() const;
199
200 const NameMap& gridDescriptors() const;
201 NameMap& gridDescriptors();
202
203 std::istream& inputStream() const;
204
205 friend class ::TestFile;
206 friend class ::TestStream;
207
208 struct Impl;
209 std::unique_ptr<Impl> mImpl;
210 };
211
212
213 ////////////////////////////////////////
214
215
216 inline void
217 18 File::write(const GridCPtrVec& grids, const MetaMap& meta) const
218 {
219
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
28 this->writeGrids(grids, meta);
220 28 }
221
222
223 template<typename GridPtrContainerT>
224 inline void
225
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 File::write(const GridPtrContainerT& container, const MetaMap& meta) const
226 {
227 32 GridCPtrVec grids;
228
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 std::copy(container.begin(), container.end(), std::back_inserter(grids));
229
2/2
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 1 times.
32 this->writeGrids(grids, meta);
230 31 }
231
232 } // namespace io
233 } // namespace OPENVDB_VERSION_NAME
234 } // namespace openvdb
235
236 #endif // OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
237