libE57Format 3.1.1
C++ library to read & write the E57 file format for point cloud data
Loading...
Searching...
No Matches
e57::CompressedVectorNode Class Reference

An E57 element containing ordered vector of child nodes, stored in an efficient binary format. More...

#include <E57Format.h>

Public Member Functions

 CompressedVectorNode ()=delete
 
 CompressedVectorNode (const ImageFile &destImageFile, const Node &prototype, const VectorNode &codecs)
 Create an empty CompressedVectorNode, for writing, that will store records specified by the prototype.
 
 CompressedVectorNode (const Node &n)
 Downcast a generic Node handle to a CompressedVectorNode handle.
 
void checkInvariant (bool doRecurse=true, bool doUpcast=true) const
 Check whether CompressedVectorNode class invariant is true.
 
int64_t childCount () const
 Get current number of records in a CompressedVectorNode.
 
VectorNode codecs () const
 Get the codecs tree that describes the encoder/decoder configuration of the CompressedVectorNode.
 
ImageFile destImageFile () const
 Get the ImageFile that was declared as the destination for the node when it was created.
 
void dump (int indent=0, std::ostream &os=std::cout) const
 Diagnostic function to print internal state of object to output stream in an indented format.
 
ustring elementName () const
 Get elementName string, that identifies the node in its parent..
 
bool isAttached () const
 Has node been attached into the tree of an ImageFile.
 
bool isRoot () const
 Is this a root node.
 
 operator Node () const
 Upcast a CompressedVectorNode handle to a generic Node handle.
 
Node parent () const
 Return parent of node, or self if a root node.
 
ustring pathName () const
 Get absolute pathname of node.
 
Node prototype () const
 Get the prototype tree that describes the types in the record.
 
CompressedVectorReader reader (const std::vector< SourceDestBuffer > &dbufs)
 Create an iterator object for reading a series of blocks of data from a CompressedVectorNode.
 
CompressedVectorWriter writer (std::vector< SourceDestBuffer > &sbufs)
 Create an iterator object for writing a series of blocks of data to a CompressedVectorNode.
 

Detailed Description

An E57 element containing ordered vector of child nodes, stored in an efficient binary format.

The CompressedVectorNode encodes very long sequences of identically typed records. In an E57 file, the per-point information (coordinates, intensity, color, time stamp etc.) are stored in a CompressedVectorNode. For time and space efficiency, the CompressedVectorNode data is stored in a binary section of the E57 file.

Conceptually, the CompressedVectorNode encodes a structure that looks very much like a homogeneous VectorNode object. However because of the huge volume of data (E57 files can store more than 10 billion points) within a CompressedVectorNode, the functions for accessing the data are dramatically different. CompressedVectorNode data is accessed in large blocks of records (100s to 1000s at a time).

Two attributes are required to create a new CompressedVectorNode.

The first attribute describes the shape of the record that will be stored. This record type description is called the prototype of the CompressedVectorNode. Often the prototype will be a StructNode with a single level of named child elements. However, the prototype can be a tree of any depth consisting of the following node types: IntegerNode, ScaledIntegerNode, FloatNode, StringNode, StructureNode, or VectorNode (i.e. CompressedVectorNode and BlobNode are not allowed). Only the node types and attributes are used in the prototype, the values stored are ignored. For example, if the prototype contains an IntegerNode, with a value=0, minimum=0, maximum=1023, then this means that each record will contain an integer that can take any value in the interval [0,1023]. As a second example, if the prototype contains an ScaledIntegerNode, with a value=0, minimum=0, maximum=1023, scale=.001, offset=0 then this means that each record will contain an integer that can take any value in the interval [0,1023] and if a reader requests the scaledValue of the field, the rawValue should be multiplied by 0.001.

The second attribute needed to describe a new CompressedVectorNode is the codecs description of how the values of the records are to be represented on the disk. The codec object is a VectorNode of a particular format that describes the encoding for each field in the record, which codec will be used to transfer the values to and from the disk. Currently only one codec is defined for E57 files, the bitPackCodec, which copies the numbers from memory, removes any unused bit positions, and stores the without additional spaces on the disk. The bitPackCodec has no configuration options or parameters to tune. In the ASTM standard, if no codec is specified, the bitPackCodec is assumed. So specifying the codecs as an empty VectorNode is equivalent to requesting at all fields in the record be encoded with the bitPackCodec.

Other than the prototype and codecs attributes, the only other state directly accessible is the number of children (records) in the CompressedVectorNode. The read/write access to the contents of the CompressedVectorNode is coordinated by two other Foundation API objects: CompressedVectorReader and CompressedVectorWriter.

Class Invariant

A class invariant is a list of statements about an object that are always true before and after any operation on the object. An invariant is useful for testing correct operation of an implementation. Statements in an invariant can involve only externally visible state, or can refer to internal implementation-specific state that is not visible to the API user. The following C++ code checks externally visible state for consistency and throws an exception if the invariant is violated:

void CompressedVectorNode::checkInvariant( bool doRecurse, bool doUpcast ) const
{
// If destImageFile not open, can't test invariant (almost every call would throw)
if ( !destImageFile().isOpen() )
{
return;
}
// If requested, call Node::checkInvariant
if ( doUpcast )
{
static_cast<Node>( *this ).checkInvariant( false, false );
}
// Check prototype is good Node
prototype().checkInvariant( doRecurse );
// prototype attached state not same as this attached state
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
// prototype not root
if ( !prototype().isRoot() )
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
// prototype dest ImageFile not same as this dest ImageFile
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
// Check codecs is good Node
codecs().checkInvariant( doRecurse );
// codecs attached state not same as this attached state
if ( codecs().isAttached() != isAttached() )
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
// codecs not root
if ( !codecs().isRoot() )
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
// codecs dest ImageFile not same as this dest ImageFile
{
throw E57_EXCEPTION1( ErrorInvarianceViolation );
}
}
bool isRoot() const
Is this a root node.
Definition: CompressedVectorNode.cpp:224
Node prototype() const
Get the prototype tree that describes the types in the record.
Definition: CompressedVectorNode.cpp:302
void checkInvariant(bool doRecurse=true, bool doUpcast=true) const
Check whether CompressedVectorNode class invariant is true.
Definition: CompressedVectorNode.cpp:44
ImageFile destImageFile() const
Get the ImageFile that was declared as the destination for the node when it was created.
Definition: CompressedVectorNode.cpp:254
bool isAttached() const
Has node been attached into the tree of an ImageFile.
Definition: CompressedVectorNode.cpp:261
VectorNode codecs() const
Get the codecs tree that describes the encoder/decoder configuration of the CompressedVectorNode.
Definition: CompressedVectorNode.cpp:322
Generic handle to any of the 8 types of E57 element objects.
Definition: E57Format.h:248
void checkInvariant(bool doRecurse=true, bool doDowncast=true)
Check whether Node class invariant is true.
Definition: Node.cpp:62
void checkInvariant(bool doRecurse=true, bool doUpcast=true) const
Check whether VectorNode class invariant is true.
Definition: VectorNode.cpp:42
@ ErrorInvarianceViolation
class invariance constraint violation in debug mode
Definition: E57Exception.h:133
See also
CompressedVectorReader, CompressedVectorWriter, Node

Constructor & Destructor Documentation

◆ CompressedVectorNode() [1/3]

e57::CompressedVectorNode::CompressedVectorNode ( )
delete

◆ CompressedVectorNode() [2/3]

CompressedVectorNode::CompressedVectorNode ( const ImageFile destImageFile,
const Node prototype,
const VectorNode codecs 
)
explicit

Create an empty CompressedVectorNode, for writing, that will store records specified by the prototype.

Parameters
[in]destImageFileThe ImageFile where the new node will eventually be stored.
[in]prototypeA tree that describes the fields in each record of the CompressedVectorNode.
[in]codecsA VectorNode describing which codecs should be used for each field described in the prototype.

The destImageFile indicates which ImageFile the CompressedVectorNode will eventually be attached to. A node is attached to an ImageFile by adding it underneath the predefined root of the ImageFile (gotten from ImageFile::root). It is not an error to fail to attach the CompressedVectorNode to the destImageFile. It is an error to attempt to attach the CompressedVectorNode to a different ImageFile. The CompressedVectorNode may not be written to until it is attached to the destImageFile tree.

The prototype may be any tree consisting of only the following node types: IntegerNode, ScaledIntegerNode, FloatNode, StringNode, StructureNode, or VectorNode (i.e. CompressedVectorNode and BlobNode are not allowed). See CompressedVectorNode for discussion about the prototype argument.

The codecs must be a heterogeneous VectorNode with children as specified in the ASTM E57 data format standard. Since currently only one codec is supported (bitPackCodec), and it is the default, passing an empty VectorNode will specify that all record fields will be encoded with bitPackCodec.

Precondition
The destImageFile must be open (i.e. destImageFile.isOpen() must be true).
The destImageFile must have been opened in write mode (i.e. destImageFile.isWritable() must be true).
prototype must be an unattached root node (i.e. !prototype.isAttached() && prototype.isRoot())
prototype cannot contain BlobNodes or CompressedVectorNodes.
codecs must be an unattached root node (i.e. !codecs.isAttached() && codecs.isRoot())
Postcondition
prototype.isAttached()
codecs.isAttached()
Exceptions
ErrorImageFileNotOpen
ErrorFileReadOnly
ErrorBadPrototype
ErrorBadCodecs
ErrorAlreadyHasParent
ErrorDifferentDestImageFile
ErrorInternalAll objects in undocumented state
See also
SourceDestBuffer, Node, CompressedVectorNode::reader, CompressedVectorNode::writer

◆ CompressedVectorNode() [3/3]

CompressedVectorNode::CompressedVectorNode ( const Node n)
explicit

Downcast a generic Node handle to a CompressedVectorNode handle.

Parameters
[in]nThe generic handle to downcast.

The handle n must be for an underlying CompressedVectorNode, otherwise an exception is thrown. In designs that need to avoid the exception, use Node::type() to determine the actual type of the n before downcasting. This function must be explicitly called (c++ compiler cannot insert it automatically).

Exceptions
ErrorBadNodeDowncast
See also
Node::type(), CompressedVectorNode::operator, Node()

Member Function Documentation

◆ checkInvariant()

void CompressedVectorNode::checkInvariant ( bool  doRecurse = true,
bool  doUpcast = true 
) const

Check whether CompressedVectorNode class invariant is true.

Parameters
[in]doRecurseIf true, also check invariants of all children or sub-objects recursively.
[in]doUpcastIf true, also check invariants of the generic Node class.

This function checks at least the assertions in the documented class invariant description (see class reference page for this object). Other internal invariants that are implementation-dependent may also be checked. If any invariant clause is violated, an ErrorInvarianceViolation E57Exception is thrown.

Checking the invariant recursively may be expensive if the tree is large, so should be used judiciously, in debug versions of the application.

Postcondition
No visible state is modified.
Exceptions
ErrorInvarianceViolationor any other E57 ErrorCode

◆ childCount()

int64_t CompressedVectorNode::childCount ( ) const

Get current number of records in a CompressedVectorNode.

For a CompressedVectorNode with an active CompressedVectorWriter, the returned number will reflect any writes completed.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
Current number of records in CompressedVectorNode.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
CompressedVectorNode::reader, CompressedVectorNode::writer

◆ codecs()

VectorNode CompressedVectorNode::codecs ( ) const

Get the codecs tree that describes the encoder/decoder configuration of the CompressedVectorNode.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
A smart VectorNode handle referencing the root of the codecs tree.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
CompressedVectorNode::CompressedVectorNode, SourceDestBuffer, CompressedVectorNode::reader, CompressedVectorNode::writer

◆ destImageFile()

ImageFile CompressedVectorNode::destImageFile ( ) const

Get the ImageFile that was declared as the destination for the node when it was created.

The first argument of the constructors of each of the 8 types of nodes is an ImageFile that indicates which ImageFile the node will eventually be attached to. This function returns that constructor argument. It is an error to attempt to attach the node to a different ImageFile. However it is not an error to not attach the node to any ImageFile (it's just wasteful). Use Node::isAttached to check if the node actually did get attached.

Postcondition
No visible object state is modified.
Returns
The ImageFile that was declared as the destination for the node when it was created.
See also
Node::isAttached, StructureNode::StructureNode(), VectorNode::VectorNode(), CompressedVectorNode::CompressedVectorNode(), IntegerNode::IntegerNode(), ScaledIntegerNode::ScaledIntegerNode(), FloatNode::FloatNode(), StringNode::StringNode(), BlobNode::BlobNode()

◆ dump()

void CompressedVectorNode::dump ( int  indent = 0,
std::ostream &  os = std::cout 
) const

Diagnostic function to print internal state of object to output stream in an indented format.

Parameters
[in]indentNumber of spaces to indent all the printed lines of this object.
[in]osOutput stream to print on.

All objects in the E57 Foundation API (with exception of E57Exception) support a dump() function. These functions print out to the console a detailed listing of the internal state of objects. The content of these printouts is not documented, and is really of interest only to implementation developers/maintainers or the really adventurous users. In implementations of the API other than the Reference Implementation, the dump() functions may produce no output (although the functions should still be defined). The output format may change from version to version.

Postcondition
No visible object state is modified.
Exceptions
NoE57Exceptions

◆ elementName()

ustring CompressedVectorNode::elementName ( ) const

Get elementName string, that identifies the node in its parent..

The elementName is a string associated with each parent-child link between nodes. For a given parent, the elementName uniquely identifies each of its children. Thus, any node in a tree can be identified by a sequence of elementNames that form a path from the tree's root node (see Node::pathName for more details).

Three types of nodes (the container node types) can be parents: StructureNode, VectorNode, and CompressedVectorNode. The children of a StructureNode are explicitly given unique elementNames when they are attached to the parent (using StructureNode::set). The children of VectorNode and CompressedVectorNode are implicitly given elementNames based on their position in the list (starting at "0"). In a CompressedVectorNode, the elementName can become quite large: "1000000000" or more. However in a CompressedVectorNode, the elementName string is not stored in the file and is deduced by the position of the child.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
The element name of the node, or "" if a root node.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
Node::pathName, Node::parent, Node::isRoot

◆ isAttached()

bool CompressedVectorNode::isAttached ( ) const

Has node been attached into the tree of an ImageFile.

Nodes are attached into an ImageFile tree by inserting them as children (directly or indirectly) of the ImageFile's root node. Nodes can also be attached to an ImageFile if they are used in the codecs or prototype trees of an CompressedVectorNode that is attached. Attached nodes will be saved to disk when the ImageFile is closed, and restored when the ImageFile is read back in from disk. Unattached nodes will not be saved to disk. It is not recommended to create nodes that are not eventually attached to the ImageFile.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible object state is modified.
Returns
true if node is child of (or in codecs or prototype of a child CompressedVectorNode of) the root node of an ImageFile.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
Node::destImageFile, ImageFile::root

◆ isRoot()

bool CompressedVectorNode::isRoot ( ) const

Is this a root node.

A root node has itself as a parent (it is not a child of any node). Newly constructed nodes (before they are inserted into an ImageFile tree) start out as root nodes. It is possible to temporarily create small trees that are unattached to any ImageFile. In these temporary trees, the top-most node will be a root node. After the tree is attached to the ImageFile tree, the only root node will be the pre-created one of the ImageTree (the one returned by ImageFile::root). The concept of attachment is slightly larger than that of the parent-child relationship (see Node::isAttached and CompressedVectorNode::CompressedVectorNode for more details).

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
true if this node is a root node.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
Node::parent, Node::isAttached, CompressedVectorNode::CompressedVectorNode

◆ operator Node()

CompressedVectorNode::operator Node ( ) const

Upcast a CompressedVectorNode handle to a generic Node handle.

An upcast is always safe, and the compiler can automatically insert it for initializations of Node variables and Node function arguments.

Returns
A smart Node handle referencing the underlying object.
Exceptions
NoE57Exceptions.
See also
explanation in Node, Node::type(), CompressedVectorNode(const Node&)

◆ parent()

Node CompressedVectorNode::parent ( ) const

Return parent of node, or self if a root node.

Nodes are organized into trees (acyclic graphs) with a distinguished node (the "top-most" node) called the root node. A parent-child relationship is established between nodes to form a tree. Nodes can have zero or one parent. Nodes with zero parents are called root nodes.

In the API, if a node has zero parents it is represented by having itself as a parent. Due to the set-once design of the API, a parent-child relationship cannot be modified once established. A child node can be any of the 8 node types, but a parent node can only be one of the 3 container node types (TypeStructure, TypeVector, and TypeCompressedVector). Each parent-child link has a string name (the elementName) associated with it (See Node::elementName for more details). More than one tree can be formed at any given time. Typically small trees are temporarily constructed before attachment to an ImageFile so that they will be written to the disk.

Warning
User algorithms that use this function to walk the tree must take care to handle the case where a node is its own parent (it is a root node). Use Node::isRoot to avoid infinite loops or infinite recursion.
Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
A smart Node handle referencing the parent node or this node if is a root node.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
Node::isRoot, Node::isAttached, CompressedVectorNode::CompressedVectorNode, Node::elementName

◆ pathName()

ustring CompressedVectorNode::pathName ( ) const

Get absolute pathname of node.

Nodes are organized into trees (acyclic graphs) by a parent-child relationship between nodes. Each parent-child relationship has an associated elementName string that is unique for a given parent. Any node in a given tree can be identified by a sequence of elementNames of how to get to the node from the root of the tree. An absolute pathname string that is formed by arranging this sequence of elementNames separated by the "/" character with a leading "/" prepended.

Some example absolute pathNames: "/data3D/0/points/153/cartesianX", "/data3D/0/points", "/cameraImages/1/pose/rotation/w", and "/". These examples have probably been attached to an ImageFile. Here is an example absolute pathName of a node in a pose tree that has not yet been attached to an ImageFile: "/pose/rotation/w".

A technical aside: the elementName of a root node does not appear in absolute pathnames, since the "path" is between the staring node (the root) and the ending node. By convention, in this API, a root node has the empty string ("") as its elementName.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
The absolute path name of the node.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
Node::elementName, Node::parent, Node::isRoot

◆ prototype()

Node CompressedVectorNode::prototype ( ) const

Get the prototype tree that describes the types in the record.

Precondition
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
Postcondition
No visible state is modified.
Returns
A smart Node handle referencing the root of the prototype tree.
Exceptions
ErrorImageFileNotOpen
ErrorInternalAll objects in undocumented state
See also
CompressedVectorNode::CompressedVectorNode, SourceDestBuffer, CompressedVectorNode::reader, CompressedVectorNode::writer

◆ reader()

CompressedVectorReader CompressedVectorNode::reader ( const std::vector< SourceDestBuffer > &  dbufs)

Create an iterator object for reading a series of blocks of data from a CompressedVectorNode.

Parameters
[in]dbufsVector of memory buffers that will receive data read from a CompressedVectorNode.

The pathNames in the dbufs must identify terminal nodes (i.e. node that can have no children: IntegerNode, ScaledIntegerNode, FloatNode, StringNode) in this CompressedVectorNode's prototype. It is an error for two SourceDestBuffers in dbufs to identify the same terminal node in the prototype. It is not an error to create a CompressedVectorReader for an empty CompressedVectorNode.

Precondition
dbufs can't be empty
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
The destination ImageFile can't have any writers open (destImageFile().writerCount()==0)
This CompressedVectorNode must be attached (i.e. isAttached()).
Returns
A smart CompressedVectorReader handle referencing the underlying iterator object.
Exceptions
ErrorBadAPIArgument
ErrorImageFileNotOpen
ErrorTooManyWriters
ErrorNodeUnattached
ErrorPathUndefined
ErrorBufferSizeMismatch
ErrorBufferDuplicatePathName
ErrorBadCVHeader
ErrorInternalAll objects in undocumented state
See also
CompressedVectorReader, SourceDestBuffer, CompressedVectorNode::CompressedVectorNode, CompressedVectorNode::prototype

◆ writer()

CompressedVectorWriter CompressedVectorNode::writer ( std::vector< SourceDestBuffer > &  sbufs)

Create an iterator object for writing a series of blocks of data to a CompressedVectorNode.

Parameters
[in]sbufsVector of memory buffers that will hold data to be written to a CompressedVectorNode.

See CompressedVectorWriter::write(std::vector<SourceDestBuffer>&, unsigned) for discussion about restrictions on sbufs.

The pathNames in the sbufs must match one-to-one with the terminal nodes (i.e. nodes that can have no children: IntegerNode, ScaledIntegerNode, FloatNode, StringNode) in this CompressedVectorNode's prototype. It is an error for two SourceDestBuffers in dbufs to identify the same terminal node in the prototype.

It is an error to call this function if the CompressedVectorNode already has any records (i.e. a CompressedVectorNode cannot be set twice).

Precondition
sbufs can't be empty (i.e. sbufs.length() > 0).
The destination ImageFile must be open (i.e. destImageFile().isOpen()).
The destImageFile must have been opened in write mode (i.e. destImageFile.isWritable()).
The destination ImageFile can't have any readers or writers open (destImageFile().readerCount()==0 && destImageFile().writerCount()==0)
This CompressedVectorNode must be attached (i.e. isAttached()).
This CompressedVectorNode must have no records (i.e. childCount() == 0).
Returns
A smart CompressedVectorWriter handle referencing the underlying iterator object.
Exceptions
ErrorBadAPIArgument
ErrorImageFileNotOpen
ErrorFileReadOnly
ErrorSetTwice
ErrorTooManyWriters
ErrorTooManyReaders
ErrorNodeUnattached
ErrorPathUndefined
ErrorBufferSizeMismatch
ErrorBufferDuplicatePathName
ErrorNoBufferForElement
ErrorInternalAll objects in undocumented state
See also
CompressedVectorWriter, SourceDestBuffer, CompressedVectorNode::CompressedVectorNode, CompressedVectorNode::prototype

The documentation for this class was generated from the following files: