14 #ifndef NANOVDB_GRIDVALIDATOR_H_HAS_BEEN_INCLUDED
15 #define NANOVDB_GRIDVALIDATOR_H_HAS_BEEN_INCLUDED
27 template <
typename ValueT>
28 bool isValid(
const NanoGrid<ValueT> &grid,
bool detailed =
true,
bool verbose =
false);
31 template <
typename ValueT>
35 inline static void checkTree(
const GridT&, std::string&,
bool);
36 inline static void checkRoot(
const GridT&, std::string&,
bool);
37 inline static void checkNodes(
const GridT&, std::string&);
46 static std::string
check(
const GridT &grid,
bool detailed =
true);
52 template <
typename ValueT>
61 errorStr.assign(
"Grid is not 32B aligned");
64 const char *c0 = (
const char*)&(data->mMagic), *c1=(
const char*)&magic1, *c2=(
const char*)&magic2;
65 ss <<
"Incorrect magic number: Expected \"";
66 for (
int i=0; i<8; ++i) ss << c1[i];
68 for (
int i=0; i<8; ++i) ss << c2[i];
69 ss <<
"\", but found \"";
70 for (
int i=0; i<8; ++i) ss << c0[i];
74 errorStr.assign(
"Mis-matching checksum");
78 }
else if (data->mVersion <
Version(29,0,0) && data->mVersion.
id() != 28u) {
79 ss <<
"Invalid old major version number: Expected 28 or newer, but read " << data->mVersion.id();
82 errorStr.assign(
"Invalid GridClass");
84 errorStr.assign(
"Invalid GridType");
85 }
else if (data->mGridType != mapToGridType<ValueT>()) {
86 errorStr.assign(
"Invalid combination of ValueType and GridType");
87 }
else if (!
isValid(data->mGridType, data->mGridClass)) {
88 errorStr.assign(
"Invalid combination of GridType and GridClass");
89 }
else if ( (
const uint8_t*)(&(grid.
tree())) != (
const uint8_t*)(&grid+1) ) {
90 errorStr.assign(
"Invalid Tree pointer");
92 checkTree(grid, errorStr, detailed);
99 template<
typename ValueT>
103 errorStr.assign(
"Tree is not 32B aligned");
104 }
else if ( (
const uint8_t*)(&grid.tree().root()) < (
const uint8_t*)(&grid.tree()+1)) {
105 errorStr.assign(
"Invalid root pointer (should be located after the Grid and Tree)");
106 }
else if ( (
const uint8_t*)(&grid.tree().root()) > (
const uint8_t*)(&grid) + grid.gridSize() -
sizeof(grid.tree().root()) ) {
107 errorStr.assign(
"Invalid root pointer (appears to be located after the end of the buffer)");
109 checkRoot(grid, errorStr, detailed);
115 template<
typename ValueT>
116 void GridValidator<ValueT>::checkRoot(
const GridT &grid, std::string &errorStr,
bool detailed)
118 auto &root = grid.tree().root();
119 auto *data = root.data();
121 errorStr.assign(
"Root is not 32B aligned");
123 const uint8_t *minPtr = (
const uint8_t*)(&root + 1);
124 const uint8_t *maxPtr = (
const uint8_t*)(&root) + root.memUsage();
125 for (uint32_t i = 0; errorStr.empty() && i<data->mTableSize; ++i) {
126 const auto *tile = data->tile(i);
127 if ( (
const uint8_t *) tile < minPtr ) {
128 errorStr.assign(
"Invalid root tile pointer (below lower bound");
129 }
else if ( (
const uint8_t *) tile > maxPtr -
sizeof(*tile) ) {
130 errorStr.assign(
"Invalid root tile pointer (above higher bound");
133 if (detailed && errorStr.empty()) {
134 checkNodes(grid, errorStr);
139 template<
typename ValueT>
140 void GridValidator<ValueT>::checkNodes(
const GridT &grid, std::string &errorStr)
142 auto &root = grid.tree().root();
143 const uint8_t *minPtr = (
const uint8_t*)(&root) + root.memUsage();
144 const uint8_t *maxPtr = (
const uint8_t*)(&grid) + grid.gridSize();
146 auto check = [&](
const void * ptr,
size_t ptrSize) ->
bool {
148 errorStr.assign(
"Invalid node pointer: not 32B aligned");
149 }
else if ( (
const uint8_t *) ptr < minPtr ) {
150 errorStr.assign(
"Invalid node pointer: below lower bound");
151 }
else if ( (
const uint8_t *) ptr > maxPtr - ptrSize ) {
152 errorStr.assign(
"Invalid node pointer: above higher bound");
154 return errorStr.empty();
157 for (
auto it2 = grid.tree().root().cbeginChild(); it2; ++it2) {
159 if (!check(&node2,
sizeof(node2)))
return;
160 for (
auto it1 = node2.cbeginChild(); it1; ++it1) {
162 if (!check(&node1,
sizeof(node1)))
return;
163 for (
auto it0 = node1.cbeginChild(); it0; ++it0) {
165 if (!check(&node2,
sizeof(node2)))
return;
175 template <
typename ValueT>
179 if (verbose && !str.empty()) std::cerr <<
"Validation failed: " << str << std::endl;
Computes a pair of 32bit checksums, of a Grid, by means of Cyclic Redundancy Check (CRC)
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
#define NANOVDB_MAGIC_GRID
Definition: NanoVDB.h:127
#define NANOVDB_MAJOR_VERSION_NUMBER
Definition: NanoVDB.h:133
#define NANOVDB_MAGIC_NUMBER
Definition: NanoVDB.h:126
Allows for the construction of NanoVDB grids without any dependecy.
Definition: GridValidator.h:33
static std::string check(const GridT &grid, bool detailed=true)
Returns an error message (an empty string means no error)
Definition: GridValidator.h:53
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
Definition: NanoVDB.h:3699
const TreeT & tree() const
Return a const reference to the tree.
Definition: NanoVDB.h:3753
Bit-compacted representation of all three version numbers.
Definition: NanoVDB.h:948
uint32_t getMajor() const
Definition: NanoVDB.h:971
uint32_t id() const
Definition: NanoVDB.h:970
Convert a base-pointer to an openvdb grid, denoted srcGrid, to a nanovdb grid of the same type,...
Definition: NanoVDB.h:247
static bool isValid(const void *p)
return true if the specified pointer is aligned and not NULL
Definition: NanoVDB.h:743
bool validateChecksum(const NanoGrid< BuildT > &grid, ChecksumMode mode=ChecksumMode::Default)
Return true if the checksum of the grid matches the expected value already encoded into the grid's me...
Struct with all the member data of the Grid (useful during serialization of an openvdb grid)
Definition: NanoVDB.h:3512