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");
 
   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;
 
  185 #endif // NANOVDB_GRIDVALIDATOR_H_HAS_BEEN_INCLUDED 
#define NANOVDB_MAGIC_NUMBER
 
#define NANOVDB_MAJOR_VERSION_NUMBER
 
__hostdev__ const TreeT & tree() const 
Return a const reference to the tree. 
 
Allows for the construction of NanoVDB grids without any dependecy. 
 
__hostdev__ bool isValid(GridType gridType, GridClass gridClass)
return true if the combination of GridType and GridClass is valid. 
 
Highest level of the data structure. Contains a tree and a world->index transform (that currently onl...
 
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...
 
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
 
Bit-compacted representation of all three version numbers. 
 
static std::string check(const GridT &grid, bool detailed=true)
Returns an error message (an empty string means no error)