QUB_Tree

A class to work with QUB trees in c++.

#include <QUB_Tree.h>

QUB_Tree QUB_Tree::Create( string name = "" )

name      the new node's name.

Creates a new unconnected node.

QUB_Tree QUB_Tree::CreateComment( string text )

text      the comment's text

Creates a new node that will appear in the text representation as a one-line comment.

QUB_Tree QUB_Tree::Open( string path, bool readOnly = false )

path      path to an existing file
readOnly      whether to open the file read-only

Opens a qubtree binary file and returns the root node. Leaves the file open. If root.IsNull, the file could not be opened.

QUB_Tree QUB_Tree::ReadText( string path )

path      path to an existing file

Reads in a tree from a plain-text file. Does not leave the file open.

QUB_Tree QUB_Tree::CreateFromString( string treeString )

treeString      a qub tree in plain-text format

Reads in a tree from the string.

QUB_Tree QUB_Tree::CreateFromStream( std::istream& in )

Reads in a plain-text qub tree from the stream

QUB_Tree QUB_Tree::CreateFromBuffer( const char *buffer )

Reads in a binary qubtree (identical to the bytes in a qubtree file).

QUB_Tree()

Constructs a null QUB_Tree (see isNull()).
Please do not ever say "new QUB_Tree", as QUB_Tree already acts as a pointer to a QTR_Impl.

QUB_Tree( QTR_Impl *impl )

Constructs a QUB_Tree which points to impl, and increments impl's reference count.

QUB_Tree( QUB_Tree &example )

Constructs a QUB_Tree which points to the same QTR_Impl as example.

operator=( QUB_Tree &example )

points this QUB_Tree at the same QTR_Impl as example.

QUB_Tree clone( bool deep = true )

deep      true: copy the subtree rooted here. false: copy just this node and its data.

Makes a copy of this node.

bool isNull()

Returns true if this QUB_Tree does not point to a valid QTR_Impl.

bool equals( QUB_Tree& other)

Returns true if this QUB_Tree points at the same QTR_Impl as other.

bool save()

If inFile(), saves changes to disk.

bool saveAs( string path )

Saves the node as a binary file, and leaves the file open for further modifications.
This node will be the root of that file's tree. If it has a parent, it will be removed first.

bool close()

If inFile(), closes the file without saving. The file's contents remain available in memory.

To avoid copying a large file into memory when you're done with it, make sure you hold no references except the root node (make sure any QUB_Tree variables pointing into the tree go out of scope, or set them to QUB_Tree()), then set rootNode to QUB_Tree() or let it go out of scope. The file is closed automatically when there are no references to its root node.

bool inFile()

True if this node is in an open file.

string path()

If inFile(), returns the path to the file.

bool saveTextCopy( string path )

Saves a copy of the tree rooted here as a plain-text qubtree file.

string toString()

Gets a copy of the tree rooted here as a plain-text qubtree.

string toStream( std::ostream& out, string indent )

Writes a copy of the tree rooted here as a plain-text qubtree.

string toBufferSize()

Returns the number of bytes required to store this (sub)tree in binary form

string toBuffer( char *buffer )

Copies this (sub)tree into the buffer. The buffer should have room for toBufferSize() bytes. The buffer can be written to disk as a qubtree file, or read back in by CreateFromBuffer().

string name()

Returns this node's name.

void setName( string name )

Sets this node's name. qubtree wastes disk space when you change the name of a disk-resident node. Better to Create() or insertChild() with the right name.

bool hasLineComment()

string getLineComment()

void setLineComment( string comment )

In the text format, each line can have a comment after it.

QTR_Impl *getImpl()

Returns a pointer to the underlying C node struct. Useful for passing nodes to Delphi. If you're planning on keeping this pointer around, please QTR_INCREF( impl ), then when you're done, QTR_DECREF( impl ).

bool lock( int timeoutMS = INFINITE )

timeoutMS      how long to wait for the mutex before giving up
returns      true if we got the mutex

The mutex controls all access to the node; most importantly its reference count. Don't hold it for too long.

void unlock()

Releases the mutex.

QUB_Tree child()

Returns this node's first child, possibly null.

QUB_Tree sibling()

Returns this node's next sibling (parent's next child)

QUB_Tree parent()

Returns the node which has this node as a child, possibly null

QUB_Tree operator[ string childName ]

Returns the first child by that name. If none exist, one will be created and appended.

QUB_TreeIter children()

Returns an iterator pointed at the first child.

QUB_TreeIter end()

Returns an iterator pointed one past the last child. (at a null node)

QUB_TreeIter find( string childName )

Returns an iterator pointed at the first child named childName. If none, points at the end().

QUB_TreeIter rfind( string childName )

Returns an iterator pointed at the last child named childName. If none, points at the end().

void appendChild( string newChildName )

void appendChild( QUB_Tree newChild )

Appends a child node as the last child of this node. If newChild already has a parent, removes it first.
Repeatedly calling appendChild() is very inefficient. Use
insertChild() or QUB_TreeIter.insert() instead.

void appendClone( QUB_Tree template, bool deep = true )

Appends a copy of template as the last child of this node. If deep, copies template's children as well.

void insertChild( string newChildName )

void insertChild( QUB_Tree newChild )

void insertChild( QUB_Tree afterChild, string newChildName )

void insertChild( QUB_Tree afterChild, QUB_Tree newChild )

Inserts a child node as the first child, or after afterChild.
If newChild already has a parent, removes it first.

void insertClone( QUB_Tree template, bool deep = true )

void insertClone( QUB_Tree afterChild, QUB_Tree template, bool deep = true )

Inserts a copy of template as the first child, or after afterChild.
If deep, copies template's children as well.

bool isPreload()

When re-reading this node from disk, is data read into RAM or skipped until you loadData()?

void setPreload( bool shouldPreload )

setPreload(false) to save some RAM next time you load this node from disk.

void setChanged()

Marks this node as needing to be written when its file is saved. The changed flag is set automatically for structural changes, but if you modify the data's contents it's up to you to call setChanged().

bool dataIs( QTR_DataType type )

Returns true if dataType() == type.

QTR_DataType dataType()

Returns the type of the data.

uint dataSize()

Returns the size of one row of data (e.g. dataCols() * sizeof(int)).

uint dataCount()

Returns the number of units of data ( dataRows()*dataCols() or string length).

uint dataCols()

Returns the number of columns of data (for strings: number of characters).

uint dataRows()

Returns the number of rows of data (for strings: 1).

void loadedFirst()

Returns the first row index in the loaded range of data.

void loadedLast()

Returns the last row index in the loaded range of data.

void loadedCount()

Returns the number of data rows loaded.

void loadedFirstItem()

Returns the first index in the loaded range of data.

void loadedLastItem()

Returns the last index in the loaded range of data.

void loadedItemCount()

Returns the number of data items loaded.

void* data( bool autoload = true )

autoload      true: if no data is loaded, load it all first

Returns a pointer to the loaded portion of the data.

bool setNumData( QTR_DataType type, uint rows, uint cols, void *initVals = 0 )

bool setNumData( QTR_DataType type, uint rows, uint cols, void **initVals )

type      e.g. QTR_TYPE_INT, QTR_TYPE_DOUBLE (numeric types only)
rows      the number of rows
cols      the number of columns
initVals      stuff to memcpy() into the newly allocated data, unless NULL

Replaces any existing data with a fresh matrix of numbers. If the node is on disk and preload() == false, the data will stay unloaded (no RAM allocated).

bool setData( QTR_DataType type, uint rowSize, uint rowCount, void *initVals )

type      e.g. QTR_TYPE_INT, QTR_TYPE_FLOAT, QTR_TYPE_STRING
rowSize      how many bytes one row takes up
rowCount      how many rows
initVals      stuff to memcpy() into the newly allocated data, unless NULL

Replaces any existing data with a fresh array/matrix. If the node is on disk and preload() == false, the data will stay unloaded (no RAM allocated).

bool setData( QTR_DataType type, T initVal )

type      e.g. QTR_TYPE_INT, QTR_TYPE_FLOAT, QTR_TYPE_STRING
initVal      a value to copy into data

Replaces any data with a 1x1 matrix of type, and initializes it with initVal.
Please make sure type matches T.

bool setData( string data )

data      the desired contents of the data

Replaces any data with this string. dataType() == QTR_TYPE_STRING

bool resizeData( uint newRowCount )

newRowCount      how many rows you want the data to have
returns      true if successful

You can only resize if
dataRows() is nonzero.
Sorry, you can't change the number of columns.

bool clearData()

Removes any data.

bool loadData( uint firstRow=BEGIN, uint lastRow=END, bool doRead = true )

Makes data() point to the beginning of firstRow, valid up to and including lastRow.
If (! doRead) then just allocate the memory, but don't read from disk.

Nodes on disk can keep the data on disk and load portions into RAM as needed. See also: isPreload()

bool unloadData( bool doWrite = true )

doWrite      true: write the loaded region to disk false: just free its RAM.
returns      true if successful

Free up some RAM when your node resides in a file by paging data out to disk. If you know it hasn't changed, use doWrite = false.

uint readDataInto( void *buf, uint firstRow, uint lastRow )

uint readDataInto( void **buf, uint firstRow, uint lastRow )

buf      some memory to fill with the requested data
firstRow      the first row index in the range you're requesting
lastRow      the row index in the range you're requesting (inclusive)
returns      the number of rows read

Reads a portion of the data into your buffer, whether or not that data is already loaded in RAM.

uint writeDataFrom(void *buf, uint firstRow, uint lastRow )

buf      some memory containing the data you wish to write
firstRow      the first row index in the range you're overwriting
lastRow      the last row index in the range you're overwriting (inclusive)
returns      the number of rows written

Overwrites a portion of the data with the contents of your buffer, regardless of what's loaded.

T& dataAs( int i, T dummy )

i      the index of an element between loadedFirstItem() and loadedLastItem().
dummy      lets the compiler know what type T is (value doesn't matter).

Returns a reference to the i'th item, assuming it's loaded.

T& dataAs( int r, int c, T dummy )

r      the index of a row between loadedFirst() and loadedLast().
r      the index of a column
dummy      lets the compiler know what type T is (value doesn't matter).

Returns a reference to the item at row r, column c, assuming it's loaded.

string dataToStream( std::ostream& out, string indent, bool forFile )

out      a stream to write on
indent      a string to preface each line with
forFile      Whether to intersperse line comments and the multi-line string indicator ('\').

Writes this node's data as a string, regardless of dataType().

string dataAsString( bool convert = true )

convert      true: represent non-string data as in the text representation
false: treat the raw bytes as a character array

Returns a copy of the data as a string, whether or not dataType() == QTR_TYPE_STRING.

int dataAsInt( int default = 0, int r = 0, int c = 0 )

default      If data is empty or not convertible, return this value
r, c      Which matrix element to read

Returns a data element cast to an int.

double dataAsDouble( double default = 0, int r = 0, int c = 0 )

default      If data is empty or not convertible, return this value
r, c      Which matrix element to read

Returns a data element cast to a double.

uint getDataAsInts( int *buf, uint firstRow, uint lastRow )

uint getDataAsInts( int **buf, uint firstRow, uint lastRow )

buf      some memory to fill with converted data
firstRow      the first row index in the requested range
lastRow      the last row index (inclusive) in the requested range
returns      the number of rows read

Fills buf with a range of data, converted if necessary.

uint getDataAsFloats( float *buf, uint firstRow, uint lastRow )

uint getDataAsFloats( float **buf, uint firstRow, uint lastRow )

buf      some memory to fill with converted data
firstRow      the first row index in the requested range
lastRow      the last row index (inclusive) in the requested range
returns      the number of rows read

Fills buf with a range of data, converted if necessary.

uint getDataAsDoubles( double *buf, uint firstRow, uint lastRow )

uint getDataAsDoubles( double **buf, uint firstRow, uint lastRow )

buf      some memory to fill with converted data
firstRow      the first row index in the requested range
lastRow      the last row index (inclusive) in the requested range
returns      the number of rows read

Fills buf with a range of data, converted if necessary.