A Data_Block manages access to a block of binary data bytes. More...
#include <Data_Block.hh>
Public Types | |
enum | Data_Order { MSB, LSB } |
Data order specification. More... | |
enum | Array_Index_Counts { ELEMENT_INDEX, INDEX_COUNT } |
Symbolic references to element index and value count pairs. More... | |
enum | Array_Offset_Counts { ELEMENT_OFFSET, OFFSET_COUNT } |
Symbolic references to element offset and value count pairs. More... | |
typedef unsigned int | Index |
Element index, offset and array count values. | |
typedef std::vector< Index > | Value_List |
Value list. | |
typedef void(* | Copier )(unsigned char *destination, int destination_amount, const unsigned char *source, int source_amount) |
Pointer to a function that copies bytes from a source to a destination. | |
Public Member Functions | |
Data_Block () | |
Constructs an empty Data_Block. | |
Data_Block (void *const data, const Index *offsets, Index total_elements=0, const Index *array_counts=NULL, bool native_order=true) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and, optionally, array value counts. | |
Data_Block (void *const data, const Value_List &offsets, const Value_List &array_counts, bool native_order=true) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and array value counts. | |
Data_Block (void *const data, const Value_List &offsets, bool native_order=true) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block. | |
Data_Block (void *const data, const Index *offsets, Index total_elements, const Index *array_counts, Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, array value counts, and the byte order of the data block. | |
Data_Block (void *const data, const Value_List &offsets, const Value_List &array_counts, Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, array value counts, and the byte order of the data block. | |
Data_Block (void *const data, const Index *offsets, Index total_elements, Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block. | |
Data_Block (void *const data, const Index *offsets, Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block. | |
Data_Block (void *const data, const Value_List &offsets, Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block. | |
Data_Block (void *const data, const Index *offsets, const Index indexed_counts[][2], Data_Order data_order) | |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, a set of array counts for various elements, and the byte order of the data block. | |
Data_Block (const Data_Block &data_block) | |
Constructs a Data_Block as a copy of another Data_Block. | |
Data_Block & | operator= (const Data_Block &data_block) |
Assigns the data block, structure, and data order of another Data_Block to this Data_Block. | |
virtual | ~Data_Block () |
bool | native () const |
Tests if the data is specified in native order. | |
Data_Block & | native (bool native_order) |
Sets whether the data is in native order. | |
Data_Order | data_order () const |
Gets the data ordering. | |
Data_Block & | data_order (Data_Order order) |
Sets the data ordering. | |
unsigned char * | data () const |
Gets the address of the data storage area. | |
virtual Data_Block & | data (void *const block) |
Sets the address of the data storage area. | |
Index | size () const |
Gets the size (bytes) of the element containing data block. | |
Value_List | element_offsets_list () const |
Gets the element offsets list of the data block structure. | |
Index * | element_offsets () |
Gets the element offsets list of the data block structure. | |
bool | element_offsets (const Value_List &offsets) |
Sets the element offsets of the data block structure. | |
bool | element_offsets (const Index *offsets, Index total_elements=NO_INDEX) |
Sets the element offsets of the data block structure. | |
bool | element_sizes (const Value_List &sizes) |
Sets the element offsets of the data block structure based on the size of each element. | |
bool | element_sizes (const Index *sizes, Index total_elements=NO_INDEX) |
Sets the element offsets of the data block structure based on the size of each element. | |
Index | offset_of (Index element) const |
Gets the offset of a data block element. | |
bool | offset_of (Index element, Index offset) |
Sets the offset of a data block element. | |
bool | insert_element (Index offset, Index size, Index array_count=1) |
Inserts a new element. | |
Data_Block & | delete_element (Index element) |
Deletes an element. | |
Data_Block & | shift_offsets (int amount) |
Shift all the element offset locations. | |
Index | elements () const |
Gets the number of elements in the data block. | |
Index | size_of (Index element) const |
Gets the size of a data block element. | |
bool | size_of (Index element, Index size) |
Sets the size of a data block element. | |
Index | value_size_of (Index element) const |
Gets the size of a data block element value. | |
Data_Block & | value_size_of (Index element, Index size) |
Sets the size of a data block element value. | |
Index | index_of (Index offset) const |
Gets the element index for a data block offset. | |
Value_List | array_counts_list () const |
Gets the list of element array value counts. | |
Index * | array_counts () |
Gets the list of array element value counts. | |
Data_Block & | array_counts (const Value_List &counts, Index begin=0) |
Sets the count of array values for elements of the data block. | |
Data_Block & | array_counts (const Index *counts, Index begin=0, Index end=NO_INDEX) |
Sets the count of array values for elements of the data block. | |
Data_Block & | array_indexed_counts (const Index indexed_counts[][2], Index total_counts=NO_INDEX) |
Sets the element counts for arrays keyed by element Index. | |
Data_Block & | array_offset_counts (const Index offset_counts[][2], Index total_counts=NO_INDEX) |
Sets the element counts for arrays at various data block offsets. | |
Index | count_of (Index element) const |
Gets the number of values in a data block element. | |
Data_Block & | count_of (Index element, Index count) |
Sets the array value count for an element. | |
bool | reset_counts (bool unconditional=true, Index begin=0, Index end=NO_INDEX) |
Resets element array value counts. | |
template<typename T , bool limits_check> | |
const Data_Block & | get (T &value, const Index element, const Index index=0) const |
Get data from the block into a value of any type. | |
template<typename T > | |
const Data_Block & | get (T &value, const Index element, const Index index=0) const |
Get data from the block into a value of any type. | |
template<typename T , bool limits_check> | |
T | get (const Index element, const Index index=0) const |
Get a datum of any type from the block. | |
template<typename T > | |
T | get (const Index element, const Index index=0) const |
Get a datum of any type from the block. | |
template<typename T , bool limits_check> | |
Data_Block & | put (T &value, const Index element, const Index index=0) |
Put data into the block from a value of any type. | |
template<typename T > | |
Data_Block & | put (T &value, const Index element, const Index index=0) |
Put data into the block from a value of any type. | |
template<typename T , bool limits_check> | |
const Data_Block & | get (T *array, const Index element, Index count=0) const |
Get data from the block into an array of values of any type. | |
template<typename T > | |
const Data_Block & | get (T *array, const Index element, Index count=0) const |
Get data from the block into an array of values of any type. | |
template<typename T , bool limits_check> | |
Data_Block & | put (T *array, const Index element, Index count=0) |
Put data into the block from an array of values of any type. | |
template<typename T > | |
Data_Block & | put (T *array, const Index element, Index count=0) |
Put data into the block from an array of values of any type. | |
std::istream & | input (std::istream &stream) |
Input data bytes from a stream into the data block. | |
std::ostream & | output (std::ostream &stream) const |
Output data bytes from the data block into a stream. | |
std::ostream & | print (std::ostream &stream=std::cout) const |
Static Public Member Functions | |
static Data_Order | native_order () |
Gets the native order of the host system. | |
static Value_List & | sizes_to_offsets (Value_List &sizes) |
Converts a vector of size values to offset values. | |
static Index * | sizes_to_offsets (Index *sizes, Index total_elements=NO_INDEX) |
Converts an array of size values to an array of offset values. | |
static Value_List & | offsets_to_sizes (Value_List &offsets) |
Converts a vector of offset values to size values. | |
static Index * | offsets_to_sizes (Index *offsets, Index total_elements=NO_INDEX) |
Converts an array of offset values to size values. | |
Public Attributes | |
Copier | Get |
Pointer to a Copier function that gets data from the Block (source) into a host (destination) variable in the correct order. | |
Copier | Put |
Pointer to a Copier function that puts data into the Block (destination) from a host (source) variable in the correct order. | |
Static Public Attributes | |
static const char *const | ID = "PIRL::Data_Block ($Revision: 1.34 $ $Date: 2010/11/11 20:42:16 $)" |
Class identification name with source code version and date. | |
static const Index | NO_INDEX = static_cast<Data_Block::Index>(-1) |
An Index value (-1) meaning an invalid or non-existent Index value. | |
Protected Member Functions | |
void | limits_checker (const Index element, const Index index, bool getter, bool array) const |
Limits checker used by the I/O template functions. | |
Static Protected Member Functions | |
static void | get_forwards (unsigned char *host, int host_amount, const unsigned char *data, int data_amount) |
Get data from the block into a host variable in native order. | |
static void | get_backwards (unsigned char *host, int host_amount, const unsigned char *data, int data_amount) |
Get data from the block into a host variable in reverse order. | |
static void | put_forwards (unsigned char *data, int data_amount, const unsigned char *host, int host_amount) |
Put data from a host variable into the block in native order. | |
static void | put_backwards (unsigned char *data, int data_amount, const unsigned char *host, int host_amount) |
Put data from a host variable into the block in reverse order. |
A Data_Block manages access to a block of binary data bytes.
The binary data structure is described by the starting address of a suitable data storage area and the byte offset from this address to the first byte of each element of the structure, plus an end-of-elements offset to the byte following the last element.
The data storage area for the binary block of data is owned by the user, not the Data_Block. It is the responsibility of the user to provide sufficient storage for all elements that will be accessed.
All elements defined for the data block are contiguous. The first element of the data block is not required to be located at the beginning of the data storage area, nor is the last element required to end at the end of the storage area.
Each element offset location in the data storage area is maintained in an ordered (lowest to highest) list that is referenced by an element Index. Typically the application uses a simple enum list to provide element index values symbollically.
Optionally, any element of the structure may be described as an array of equal sized values by providing a count of the number of values in the element. Element array values may be accessed as a group by their element index, or individually by also providing the element array value index.
The element binary values in the user provided storage may be be specified to be byte ordered (their endianness) differently from the native host order, in which case data transfers between the data block and application variables will reverse the byte order.
Typically a binary data block is managed by a struct definition. The Data_Block is not a substitute for a struct. The Data_Block offers special capabilities:
The block of data being managed may contain values that are byte ordered differently than the host system where the values will be used. Data transfers between the data block and application variables will be reordered appropriately. This capability is especially useful when the byte ordering of a data block read from an external source should be hidden from the application using the data. For example, the data may have been written on a host architecture with a specific byte ordering, but the application using the data needs to use the values consistently on different host architectures. The application may specify the byte ordering of the data set to the Data_Block. For any access to an element value data ordering is transparent to the application; binary values are always provided in the native order of the host system. An application may also specify the data order before creating and writing a data set to ensure a specific external order.
The block of data being managed is not constrained by the byte alignment requirements of the host architecture. This is a significant, and usually hidden, problem with struct definitions of external data blocks. Odd data sizes - e.g. three byte integers - and odd data locations - e.g. four byte integers that do not begin at an even address - are acceptable. Also values in Elements that are a different size than the application variables that are to receive them will be correctly coerced and aligned during transfers between data block and variable storage.
The structure of the block of data being managed is defined at run time rather than compile time. It may be that information in the data itself, or from an external source, dictates an alteration in the presumed structure of a block of data. It is also possible that the structure of a block of data may be obtained from an external description or user interaction.
Any block of data may have more than one Data_Block structure associated with it. This is conceptually similar to a union. For example, one Data_Block might provide Elements with four byte integers while another provides an array of single bytes for the same block of data, and yet another provides different array organization or integer sizes.
typedef unsigned int PIRL::Data_Block::Index |
Element index, offset and array count values.
typedef std::vector<Index> PIRL::Data_Block::Value_List |
Value list.
typedef void(* PIRL::Data_Block::Copier)(unsigned char *destination, int destination_amount, const unsigned char *source, int source_amount) |
Pointer to a function that copies bytes from a source to a destination.
Data order specification.
Multi-byte data values are ordered with either the Most or the Least Significant Byte as the first accessed (lowest address). If a multi-byte datum (e.g. an int) has the value of 1, then first byte of LSB data will also have a value of 1 or the first byte of MSB data will have a value of 0.
Symbolic references to element offset and value count pairs.
The count of values in array elements may be defined by element offset and value count pairs. This enum helps make it clear which is which.
Data_Block::Data_Block | ( | ) |
Constructs an empty Data_Block.
Warning: This Data_Block will not have any data storage area associated with it.
The data order mode will be set to native host order.
References native().
Data_Block::Data_Block | ( | void *const | data, |
const Index * | offsets, | ||
Index | total_elements = 0 , |
||
const Index * | array_counts = NULL , |
||
bool | native_order = true |
||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and, optionally, array value counts.
The byte order of the data block values may be specified as non-native.
data | The address of the data block to be managed. |
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure, plus the offset to the next byte after the last element of the structure. For an alternative method of describing the data block element locations see element_sizes. |
total_elements | The number of elements in the data block. If the total_elements argument is not provided, then the final entry (after the end-of-elements offset) in the offsets array must be 0, and the total_elements value will be determined by counting, from the second offsets entry (because the first is expected to be 0), the number of non-0 offsets array entries and subtracting one for the final end-of-elements offset. |
array_counts | A list of array value counts for each element in the data block. This list corresponds to the offsets list, but without the extra end-of-elements entry. A count of 0 or 1 means the corresponding data block element is not an array (has one value). If array_counts is NULL, the data block contains no arrays, and the count of each element will be set to 1. For an alternative method of specifying data block array counts see array_offset_counts. |
native_order | true if the data is in native host order; false otherwise. |
Data_Block::Data_Block | ( | void *const | data, |
const Value_List & | offsets, | ||
const Value_List & | array_counts, | ||
bool | native_order = true |
||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and array value counts.
The byte order of the data block values may be specified as non-native.
data | The address of the data block to be managed. |
offsets | A vector of element offset values, plus the end-of-elements offset. |
array_counts | A vector of array value counts for each element in the data block. This list corresponds to the offsets list, but without the extra end-of-elements entry. A count of 0 or one means the corresponding data block element is not an array (has one value). Any unspecified array counts are set to 1. Extra values are ignored. For an alternative method of specifying data block array counts see array_offset_counts. |
native_order | true if the data is in native host order; false otherwise. |
Data_Block::Data_Block | ( | void *const | data, |
const Value_List & | offsets, | ||
bool | native_order = true |
||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block.
All elements of the data block have a single value.
The byte order of the data block values may be specified as non-native.
data | The address of the data block to be managed. |
offsets | A vector of element offset values, plus the end-of-elements offset. |
native_order | true if the data is in native host order; false otherwise. |
Data_Block::Data_Block | ( | void *const | data, |
const Index * | offsets, | ||
Index | total_elements, | ||
const Index * | array_counts, | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, array value counts, and the byte order of the data block.
data | The address of the data block to be managed. |
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure, plus the offset to the next byte after the last element of the structure. For an alternative method of describing the data block element locations see element_sizes. |
total_elements | The number of elements in the data block. This corresponds to one less than the number of entries in the offsets array because it excludes the final end-of-elements offset. N.B.: the offsets array must contain one more entry (the end-of-elements offset) than the total_elements value. However, if the total_elements argument is not provided, then the final entry (after the end-of-elements offset) in the offsets array must be 0, and the total_elements value will be determined by counting, from the second offsets entry (because the first is expected to be 0), the number of non-0 offsets array entries and subtracting one for the final end-of-elements offset. N.B.: In this case if the first element of the data block is located at the beginning of the data block (which is typical) then this 0 offset must be the first offsets array entry or it will be seen as marking the end of the list. |
array_counts | A list of array value counts for each element in the data block. This list corresponds to the offsets list, but without the extra end-of-elements entry. A count of 0 or one means the corresponding data block element is not an array. If array_counts is NULL, the data block contains no arrays and the count of each element will be set to 1. For an alternative method of specifying data block array counts see array_offset_counts. |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | void *const | data, |
const Value_List & | offsets, | ||
const Value_List & | array_counts, | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, array value counts, and the byte order of the data block.
data | The address of the data block to be managed. |
offsets | A vector of element offset values, plus the end-of-elements offset. |
array_counts | A vector of array value counts for each element in the data block. This list corresponds to the offsets list, but without the extra end-of-elements entry. A count of 0 or one means the corresponding data block element is not an array (has one value). Any unspecified array counts are set to 1. Extra values are ignored. For an alternative method of specifying data block array counts see array_offset_counts. |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | void *const | data, |
const Index * | offsets, | ||
Index | total_elements, | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block.
All elements of the data block have a single value.
data | The address of the data block to be managed. |
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure, plus the offset to the next byte after the last element of the structure. For an alternative method of describing the data block element locations see element_sizes. |
total_elements | The number of elements in the data block. |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | void *const | data, |
const Index * | offsets, | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block.
All elements of the data block have a single value.
data | The address of the data block to be managed. |
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure, plus the offset to the next byte after the last element of the structure. The end of the list must be marked with a 0 entry (the first entry may be also be valid 0 offset). |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | void *const | data, |
const Value_List & | offsets, | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets and the byte order of the data block.
All elements of the data block have a single value.
data | The address of the data block to be managed. |
offsets | A vector of element offset values, plus the end-of-elements offset. |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | void *const | data, |
const Index * | offsets, | ||
const Index | indexed_counts[][2], | ||
Data_Order | data_order | ||
) |
Constructs a Data_Block for a block of data having a structure defined by its element offsets, a set of array counts for various elements, and the byte order of the data block.
data | The address of the data block to be managed. |
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure, plus the offset to the next byte after the last element of the structure. The end of the list must be marked with a 0 entry (the first entry may be also be valid 0 offset). |
indexed_counts | An array[][2] of element index,count pairs; where indexed_counts[][ELEMENT_INDEX] is the index for the element to have its array value count set, and indexed_counts[][INDEX_COUNT] is the count of values in the array. The entries do not need to be ordered. All elements not specified are taken to have a single value. A count of 0 or one means the corresponding element is not an array. |
data_order | A Data_Order value of either MSB or LSB to indicated that the values in the data block are ordered Most or Least Significant Byte first. |
Data_Block::Data_Block | ( | const Data_Block & | data_block ) |
Constructs a Data_Block as a copy of another Data_Block.
N.B.: The data storage area is shared by both objects; only the pointer to the storage area is copied, not the data itself. This allows a single storage area to be managed with different structure definitions.
data_block | A reference to the Data_Block to be copied. |
Data_Block::~Data_Block | ( | ) | [virtual] |
Data_Block & Data_Block::operator= | ( | const Data_Block & | data_block ) |
Assigns the data block, structure, and data order of another Data_Block to this Data_Block.
N.B.: The data storage area is shared by both objects; only the pointer to the storage area is copied, not the data itself. This allows a single storage area to be managed with different structure definitions.
data_block | A reference to the Data_Block to be copied. |
bool PIRL::Data_Block::native | ( | ) | const [inline] |
Tests if the data is specified in native order.
Referenced by Data_Block().
Data_Block & Data_Block::native | ( | bool | native_order ) |
Sets whether the data is in native order.
native_order | true if the data is to be treated as in host native data order; false otherwise. |
static Data_Order PIRL::Data_Block::native_order | ( | ) | [inline, static] |
Gets the native order of the host system.
References PIRL::host_is_high_endian(), LSB, and MSB.
Data_Block::Data_Order Data_Block::data_order | ( | ) | const |
Gets the data ordering.
References PIRL::host_is_high_endian(), LSB, and MSB.
Data_Block & Data_Block::data_order | ( | Data_Order | order ) |
Sets the data ordering.
order | A Data_Order value of either MSB or LSB. |
References PIRL::host_is_high_endian().
unsigned char* PIRL::Data_Block::data | ( | ) | const [inline] |
Data_Block & Data_Block::data | ( | void *const | block ) | [virtual] |
Sets the address of the data storage area.
N.B.: Changing the data storage location does not change the existing data structure description.
block | The address (void* const) of the new data storage block. |
Index PIRL::Data_Block::size | ( | ) | const [inline] |
Gets the size (bytes) of the element containing data block.
Referenced by delete_element().
Value_List PIRL::Data_Block::element_offsets_list | ( | ) | const [inline] |
Gets the element offsets list of the data block structure.
Index* PIRL::Data_Block::element_offsets | ( | ) | [inline] |
Gets the element offsets list of the data block structure.
CAUTION: This method does not return a copy of the element offsets values; a pointer to the list of values in use by the object is returned. Direct modification of the list contents can result in structure inconsistencies such that subsequent operations may not work correctly. The list will become invalid when the object with which it is associated is deleted. Use of the structure modification methods is the recommended approach.
bool Data_Block::element_offsets | ( | const Value_List & | offsets ) |
Sets the element offsets of the data block structure.
This method determines the total number of elements in the data block.
N.B.: The count of array values for each element is reset to 1 if the element has a size of 0 or is not an even multiple of its current array value count.
offsets | A vector of Index values specifying the byte offset from the data block address to each element of the data block structure. In addition, the last value is the offset to the next byte after the last element of the structure. N.B.: There is one more offset value than the number of elements in the data block structure. The offset value entries may be in any order; they will be sorted. If the offsets vector is empty there are no elements. |
length_error | If the offsets vector only contains a single value. |
Sets the element offsets of the data block structure.
This method determines the total number of elements in the data block.
N.B.: The count of array values for each element is reset to 1 if the element has a size of 0 or is not an even multiple of its current array value count.
A Single Empty Element: To specify a single empty element without specifying the total_elements argument provide an offsets array containing only two 0 values. This is a special case where a single element at offset 0 is empty so it has an end-of-elements offset of 0, also, which can only occur in this case.
offsets | An array of Index values specifying the byte offset from the data block address to each element of the data block structure. In addition, the last value is the offset to the next byte after the last element of the structure. Typically, but not necessarily, the first offset is 0 and the last offset is the size of the data block. N.B.: There is one more offset than the number of elements in the data block structure. The offset value entries may be in any order (except see the discussion of the total_elements argument); they will be sorted. If offsets is NULL there are no elements. |
total_elements | The number of elements in the data block. This corresponds to one less than the number of entries in the offsets array because it excludes the final end-of-elements offset. N.B.: The offsets array must contain one more entry (the end-of-elements offset) than the total_elements value. However, if the total_elements value is not provided, then the final entry (after the end-of-elements offset) in the offsets array must be 0, and the total_elements value will be determined by counting, from the second offsets entry (because the first is expected to be 0), the number of non-0 offsets entries and subtracting one for the final end-of-elements offset. N.B.: In this case if the first element of the data block is located at the beginning of the data block (which is typical) then this 0 offset must be the first offsets array entry or it will be seen as marking the end of the list. If total_elements is 0 there are no elements. |
length_error | If the offsets vector only contains a single non-zero offset value and total_elements was not specified. |
bool Data_Block::element_sizes | ( | const Value_List & | sizes ) |
Sets the element offsets of the data block structure based on the size of each element.
This method determines the total number of elements in the data block.
N.B.: The count of array values for each element is reset to 1 if the element has a size of 0 or is not an even multiple of its current array value count.
sizes | A vector of Index values specifying the size in bytes of each element of the data block structure. The size entries must be in the same order as the elements of the data block. |
Sets the element offsets of the data block structure based on the size of each element.
This method determines the total number of elements in the data block.
N.B.: The count of array values for each element is reset to 1 if the element has a size of 0 or is not an even multiple of its current array value count.
sizes | An array of Index values specifying the size in bytes of each element of the data block structure. The size entries must be in the same order as the elements of the data block. |
total_elements | The number of elements in the data block. If the total_elements value is not provided, then the final entry in the sizes array must be 0, and the total_elements value will be determined by counting the number of non-0 offsets array entries. |
Data_Block::Index Data_Block::offset_of | ( | Index | element ) | const |
Gets the offset of a data block element.
element | The data block element to examine. |
std::out_of_range | If an invalid element is specified. |
Sets the offset of a data block element.
CAUTION: After the element offset is set the list of offset values for all elements is sorted to ensure that they remain in offset order. This could result in an element effectively being relocated to a new Index position; but element data will not be relocated.
WARNING: The element array value counts are each reset if the amount of space available to the element is no longer a multiple of the number of array values.
element | The element for which to set the data block offset. |
offset | The byte offset of the element from the beginning of the data block. |
std::out_of_range | If an invalid element is specified. |
std::length_error | If the offset is beyond the end of the data block. |
Inserts a new element.
The new element is inserted before the first element at the same or greater offset than the new element. If there is no such element, the new element is appended to the elements list and the end-of-elements offset is addusted accordingly. All following elements at higher offsets (if any) are shifted up by the size of the new element. The size of the preceding element (if any) will be changed if the offset of the new element is not the same as an existing element or the end-of-elements offset. In this case the array value count of the preceding element is reset to 1.
offset | The offset of the new element. |
size | The size of the new element. |
array_count | The count of array values for the element. |
length_error | If the size is not an integer multiple of the array_count. |
Data_Block & Data_Block::delete_element | ( | Index | element ) |
Deletes an element.
All following elements at higher offsets are shifted down by the size of the deleted element.
element | The Index of the element to be deleted. |
References size().
Data_Block & Data_Block::shift_offsets | ( | int | amount ) |
Shift all the element offset locations.
The shift may be positive or negative. However, the result of the shift may not move the first element to a negative offset.
amount | The amount of the offsets shift. |
invalid_argument | If a negative shift amount would result in a negative first element offset. |
Index PIRL::Data_Block::elements | ( | ) | const [inline] |
Gets the number of elements in the data block.
Data_Block::Index Data_Block::size_of | ( | Index | element ) | const |
Gets the size of a data block element.
element | The data block element to examine. |
std::out_of_range | If an invalid element is specified. |
Sets the size of a data block element.
WARNING: The offsets of all elements beyond the resized element are adjusted. This will alter the effective and expected size of the data storage area of the data block for which the user must allow.
CAUTION: If the array value count of the resized element does not accommodate the new size, the count is reset to 1.
element | The data block element to examine. |
size | The size (bytes) of the entire element. |
std::out_of_range | If an invalid element is specified. |
Data_Block::Index Data_Block::value_size_of | ( | Index | element ) | const |
Gets the size of a data block element value.
If the element is not an array of values the size of the element is returned (same as size_of (Index)). Otherwise the size of a single array value is returned.
element | The data block element to examine. |
std::out_of_range | If an invalid element is specified. |
Data_Block & Data_Block::value_size_of | ( | Index | element, |
Index | size | ||
) |
Sets the size of a data block element value.
If the element is an array of values, the size of each value is set; otherwise the size of the element is set (same as size_of (Index, Index)).
element | The data block element to examine. |
size | The size (bytes) of a single element value, or the entire element if it has only one value. |
std::out_of_range | If an invalid element is specified. |
Data_Block::Index Data_Block::index_of | ( | Index | offset ) | const |
Gets the element index for a data block offset.
offset | The data block offset to find. |
Value_List PIRL::Data_Block::array_counts_list | ( | ) | const [inline] |
Gets the list of element array value counts.
Index* PIRL::Data_Block::array_counts | ( | ) | [inline] |
Gets the list of array element value counts.
CAUTION: This method does not return a copy of the array counts values; a pointer to the list of values in use by the object is returned. Direct modification of the list contents can result in structure inconsistencies such that subsequent operations may not work correctly. The list will become invalid when the object with which it is associated is deleted. Use of the structure modification methods is the recommended approach.
Data_Block & Data_Block::array_counts | ( | const Value_List & | counts, |
Index | begin = 0 |
||
) |
Sets the count of array values for elements of the data block.
counts | A vector of value counts. The values must be in the same order as the elements of the data block. A count of 0 (which will be coerced to 1) or 1 means the corresponding data block element is not an array. |
begin | The index of the first element to have its count set. |
std::length_error | If the size of an element is not an integral multiple of the array value count to be set for it. |
Data_Block & Data_Block::array_counts | ( | const Index * | counts, |
Index | begin = 0 , |
||
Index | end = NO_INDEX |
||
) |
Sets the count of array values for elements of the data block.
counts | An array of value counts for each element in the [being,end) range. The values must be in the same order as the elements of the data block. A count of 0 (which will be coerced to 1) or 1 means the corresponding data block element is not an array. If counts is NULL, the elements contain no arrays, and the count of each element will be reset to 1. |
begin | The index of the first element to have its count set. |
end | The index of the last element (exclusive) in the range of elements for which array counts are to be set. If end is beyond the end of the element range it is limited to the end of the element range. If not specified it is taken to be the end of the element range. |
std::length_error | If the size of an element can not accommodate the array value count or is not an integral multiple of the count. |
Data_Block & Data_Block::array_indexed_counts | ( | const Index | indexed_counts[][2], |
Index | total_counts = NO_INDEX |
||
) |
Sets the element counts for arrays keyed by element Index.
indexed_counts | An array[][2] of element index,count pairs; where indexed_counts[][ELEMENT_INDEX] is the index for the element to have its array value count set, and indexed_counts[][INDEX_COUNT] is the count of values in the array. The entries do not need to be ordered. Duplicate index values are allowed; each is applied in the order they occur in the array. A count of 0 or one means the corresponding data block element is not an array. If indexed_counts is NULL, all counts will be reset to 1. |
total_counts | The total number of index,count pairs. If this argument is not provided, then the end of the list must be marked by index and count values of 0. |
std::out_of_range | If an invalid element index is specified. |
std::length_error | If the size of an element can not accommodate the array value count or is not an integral multiple of the count. |
Data_Block & Data_Block::array_offset_counts | ( | const Index | offset_counts[][2], |
Index | total_counts = NO_INDEX |
||
) |
Sets the element counts for arrays at various data block offsets.
N.B.: When setting both offsets and value counts, always set the offsets first.
offset_counts | An array[][2] of offset,count Index pairs; where offset_counts[][ELEMENT_OFFSET] is the offset in the data block for the element, and offset_counts[][OFFSET_COUNT] is the count of values in the element. Each offset is matched with its element. A count of 0 or one means the corresponding data block element is not an array. The entries do not need to be ordered. Duplicate offset values are allowed; each is applied in the order they occur in the array. If offset_counts is NULL, all counts will be reset to 1. |
total_counts | The total number of offset,count pairs. If this argument is not provided, then the end of the list must be marked by offset and count values 0. |
std::invalid_argument | If no matching element for an offset can be found. |
std::length_error | If the size of an element can not accommodate the array value count or is not an integral multiple of the count. |
Data_Block::Index Data_Block::count_of | ( | Index | element ) | const |
Gets the number of values in a data block element.
The return value will be 0 if, and only if, the size of the element is 0.
element | The data block element to examine. |
std::out_of_range | If an invalid element is specified. |
Data_Block & Data_Block::count_of | ( | Index | element, |
Index | count | ||
) |
Sets the array value count for an element.
element | The element for which to set the array value count. |
count | The number of array values in the element. A count of 0 or one means the corresponding data block element is not an array (has 1 value). |
std::out_of_range | If an invalid element is specified. |
std::length_error | If the size of the element can not accommodate the array value count or is not an integral multiple of the count. |
Resets element array value counts.
Each affected array count is reset to 1.
unconditional | If true, the array counts are unconditionally reset; otherwise only elements with a size that is not a multiple of the count of its array values are reset. |
begin | The index of the first element to have its count reset. |
end | The index of the last element (exclusive) in the range of elements for which array counts are to be reset. If end is beyond the end of the element range it is limited to the end of the element range. If not specified it is taken to be the end of the element range. |
const Data_Block& PIRL::Data_Block::get | ( | T & | value, |
const Index | element, | ||
const Index | index = 0 |
||
) | const [inline] |
Get data from the block into a value of any type.
If the element index is to an array element, only one value will be transferred. If the data block element value is larger than the application value, then only the least significant bytes from the data block that will fit in the variable are transferred (this corresponds to an integer downcast). If the data block element value is smaller than the application value, then the data bytes are transferred into the least significant bytes of the variable.
N.B.: No type conversion is done (the data types of data block elements are unknown). Transferring data between mismatched type values or sizes may produced unexpected results.
T | The data type of the value to be assigned. |
limits_check | True if limit checking for the element and index arguments is to be applied; otherwise no limit checking is done, which is slightly faster. |
value | A reference to a variable of type T that will receive the data. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and limits_check is true. |
References Get, and limits_checker().
const Data_Block& PIRL::Data_Block::get | ( | T & | value, |
const Index | element, | ||
const Index | index = 0 |
||
) | const [inline] |
Get data from the block into a value of any type.
Equivalent to the template with the same signature except DATA_BLOCK_LIMITS_CHECK is used by default.
T | The data type of the value to be assigned. |
value | A reference to a variable of type T that will receive the data. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
T PIRL::Data_Block::get | ( | const Index | element, |
const Index | index = 0 |
||
) | const [inline] |
Get a datum of any type from the block.
T | The data type of the value to be returned. |
limits_check | True if limit checking for the element and index arguments is to be applied; otherwise no limit checking is done, which is slightly faster. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
T PIRL::Data_Block::get | ( | const Index | element, |
const Index | index = 0 |
||
) | const [inline] |
Get a datum of any type from the block.
Equivalent to the template with the same signature except DATA_BLOCK_LIMITS_CHECK is used by default.
T | The data type of the value to be returned. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
Data_Block& PIRL::Data_Block::put | ( | T & | value, |
const Index | element, | ||
const Index | index = 0 |
||
) | [inline] |
Put data into the block from a value of any type.
If the element index is to an array element, only one value will be transferred. If the data block element value is larger than the application value, then the variable bytes are transferred into the least significant bytes of the data element value. If the data block element value is smaller than the application value, then only the least significant bytes from the application variable that will fit in the data element value are transferred (this corresponds to an integer downcast).
N.B.: No type conversion is done (the data types of data block elements are unknown). Transferring data between mismatched type values or sizes may produced unexpected results.
T | The data type of the value to be transferred. |
limits_check | True if limit checking for the element and index arguments is to be applied; otherwise no limit checking is done, which is slightly faster. |
value | A reference to a variable of type T that contains the data to be transferred. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and limits_check is true. |
References limits_checker(), and Put.
Data_Block& PIRL::Data_Block::put | ( | T & | value, |
const Index | element, | ||
const Index | index = 0 |
||
) | [inline] |
Put data into the block from a value of any type.
Equivalent to the template with the same signature except DATA_BLOCK_LIMITS_CHECK is used by default.
T | The data type of the value to be transferred. |
value | A reference to a variable of type T that contains the data to be transferred. |
element | A data block element offset entry Index. |
index | An array element value index. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
const Data_Block& PIRL::Data_Block::get | ( | T * | array, |
const Index | element, | ||
Index | count = 0 |
||
) | const [inline] |
Get data from the block into an array of values of any type.
A data block element with a single value (non-array element) is the same as an array element with only one value.
T | The data type of the array values. |
limits_check | True if limit checking for the element and index arguments is to be applied; otherwise no limit checking is done, which is slightly faster. |
array | A pointer to an array of values of type T. |
element | A data block element offset entry Index. |
count | The number of values to transfer. If this value is 0 then all array values at the element offset indexed will be transferred (make sure the array has sufficient space). If this value is larger than the number of element array values, then only the number of element array values will be transferred. |
std::out_of_range | If an invalid element or index is specified and limits_check is true. |
References data(), Get, and limits_checker().
const Data_Block& PIRL::Data_Block::get | ( | T * | array, |
const Index | element, | ||
Index | count = 0 |
||
) | const [inline] |
Get data from the block into an array of values of any type.
Equivalent to the template with the same signature except DATA_BLOCK_LIMITS_CHECK is used by default.
T | The data type of the array values. |
array | A pointer to an array of values of type T. |
element | A data block element offset entry Index. |
count | The number of values to transfer. If this value is 0 then all array values at the element offset indexed will be transferred (make sure the array has sufficient space). If this value is larger than the number of element array values, then only the number of element array values will be transferred. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
Data_Block& PIRL::Data_Block::put | ( | T * | array, |
const Index | element, | ||
Index | count = 0 |
||
) | [inline] |
Put data into the block from an array of values of any type.
A data block element with a single value (non-array element) is the same as an array element with only one value.
T | The data type of the array values. |
limits_check | True if limit checking for the element and index arguments is to be applied; otherwise no limit checking is done, which is slightly faster. |
array | A pointer to an array of values of type T. |
element | A data block element offset entry Index. |
count | The number of values to transfer. If this value is 0 then all array values at the element offset indexed will be filled (make sure the array has sufficient values). If this value is larger than the number of element array values, then only the number of element array values will be filled. |
std::out_of_range | If an invalid element or index is specified and limits_check is true. |
References data(), limits_checker(), and Put.
Data_Block& PIRL::Data_Block::put | ( | T * | array, |
const Index | element, | ||
Index | count = 0 |
||
) | [inline] |
Put data into the block from an array of values of any type.
Equivalent to the template with the same signature except DATA_BLOCK_LIMITS_CHECK is used by default.
T | The data type of the array values. |
array | A pointer to an array of values of type T. |
element | A data block element offset entry Index. |
count | The number of values to transfer. If this value is 0 then all array values at the element offset indexed will be filled (make sure the array has sufficient values). If this value is larger than the number of element array values, then only the number of element array values will be filled. |
std::out_of_range | If an invalid element or index is specified and DATA_BLOCK_LIMITS_CHECK is true. |
istream & Data_Block::input | ( | std::istream & | stream ) |
Input data bytes from a stream into the data block.
stream | The istream from which to read the data. |
Referenced by PIRL::operator>>=().
ostream & Data_Block::output | ( | std::ostream & | stream ) | const |
Output data bytes from the data block into a stream.
stream | The ostream to which to write the data. |
Referenced by PIRL::operator<<=().
std::ostream & Data_Block::print | ( | std::ostream & | stream = std::cout ) |
const |
Referenced by PIRL::operator<<().
Data_Block::Value_List & Data_Block::sizes_to_offsets | ( | Value_List & | sizes ) | [static] |
Converts a vector of size values to offset values.
N.B.: The size values are converted to offset values in place.
Each size value is added to its new offset value to determine the new offset value of the next value. The first value is set to a 0 offset. An additional final offset value is appended that is the end-of-elements value.
sizes | A vector of size values. |
Data_Block::Index * Data_Block::sizes_to_offsets | ( | Index * | sizes, |
Index | total_elements = NO_INDEX |
||
) | [static] |
Converts an array of size values to an array of offset values.
N.B.: The size values are converted to offset values in place.
Each size value is added to its new offset value to determine the new offset value of the next value. The first value is set to a 0 offset. An additional final offset value is appended that is the end-of-elements value.
The array must have room for one more element than the number of size elements (total_elements). This is typically done by putting a 0 in this extra location to mark the end of the array and then omitting the total_elements argument. After conversion the final, formerly extra, value will be filled with the end-of-elements offset value.
sizes | An array of size values (plus one extra). If NULL nothing is done. |
total_elements | The total number of size values in the array. If 0, nothing is done. If this argument is omitted then the end of the array must be marked with a 0 value. |
Data_Block::Value_List & Data_Block::offsets_to_sizes | ( | Value_List & | offsets ) | [static] |
Converts a vector of offset values to size values.
N.B.: The offset values are converted to size values in place.
The vector values are sorted into increasing value order. Then each value is replaced with the difference between the next value and the current value. The exception is the last value which is removed from the vector.
offsets | A vector of offset values. |
std::length_error | If the offsets vector contains only one value. |
Data_Block::Index * Data_Block::offsets_to_sizes | ( | Index * | offsets, |
Index | total_elements = NO_INDEX |
||
) | [static] |
Converts an array of offset values to size values.
N.B.: The offset values are converted to size values in place.
The array values are sorted into increasing value order. Then each value is replaced with the difference between the next value and the current value. The exception is the last value which is replaced with a 0 value.
offsets | An array of offset values. |
total_elements | The total number of offset values to be converted. N.B.: This does not include the final end-of-elements offset value. If this argument is omitted then the end of the array must be marked with a 0 value. N.B.: If one of the offset values is 0 (which is typical) and the total_elements argument is omitted, then the 0 offset must be the first entry in the array or it will be misinterpreted as marking the end of the array. |
std::length_error | If the offsets array contains only one value. |
void Data_Block::get_forwards | ( | unsigned char * | host, |
int | host_amount, | ||
const unsigned char * | data, | ||
int | data_amount | ||
) | [static, protected] |
Get data from the block into a host variable in native order.
References PIRL::host_is_high_endian().
void Data_Block::get_backwards | ( | unsigned char * | host, |
int | host_amount, | ||
const unsigned char * | data, | ||
int | data_amount | ||
) | [static, protected] |
Get data from the block into a host variable in reverse order.
References PIRL::host_is_high_endian().
void Data_Block::put_forwards | ( | unsigned char * | data, |
int | data_amount, | ||
const unsigned char * | host, | ||
int | host_amount | ||
) | [static, protected] |
Put data from a host variable into the block in native order.
Put data into the Block.
References PIRL::host_is_high_endian().
void Data_Block::put_backwards | ( | unsigned char * | data, |
int | data_amount, | ||
const unsigned char * | host, | ||
int | host_amount | ||
) | [static, protected] |
Put data from a host variable into the block in reverse order.
Put data into the Block.
References PIRL::host_is_high_endian().
const char *const Data_Block::ID = "PIRL::Data_Block ($Revision: 1.34 $ $Date: 2010/11/11 20:42:16 $)" [static] |
Class identification name with source code version and date.
const Data_Block::Index Data_Block::NO_INDEX = static_cast<Data_Block::Index>(-1) [static] |
An Index value (-1) meaning an invalid or non-existent Index value.