das2C
das core C utilities (v3)
Public Member Functions | Data Fields
DasAry Struct Reference

Dynamic recursive ragged arrays. More...

#include <das2/array.h>

Public Member Functions

DAS_API DasArynew_DasAry (const char *id, das_val_type et, size_t sz_each, const ubyte *fill, int rank, size_t *shape, das_units units)
 Creates a new dynamic array buffer. More...
 
DAS_API unsigned int DasAry_setUsage (DasAry *pThis, unsigned int uFlags)
 Set usage flags to assist arbitrary consumers understand how to use this array. More...
 
DAS_API unsigned int DasAry_getUsage (DasAry *pThis)
 Returns the usage flags for this array.
 
DAS_API int inc_DasAry (DasAry *pThis)
 Increment the count of objects using this Das Array. More...
 
DAS_API int ref_DasAry (const DasAry *pThis)
 Return the reference count of objects using this array.
 
DAS_API void dec_DasAry (DasAry *pThis)
 Maybe remove the array. More...
 
DAS_API ubyte * DasAry_disownElements (DasAry *pThis, size_t *pLen, size_t *pOffset)
 Take ownership of array element memory. More...
 
DAS_API bool DasAry_ownsElements (const DasAry *pThis)
 Does this array own it's own memory? More...
 
DAS_API const char * DasAry_id (const DasAry *pThis)
 Get the name of an array. More...
 
#define DasAry_rank(pThis)   pThis->nRank
 Get the number of dimensions in an array. More...
 
DAS_API das_units DasAry_units (const DasAry *pThis)
 Get the units for the values in the array.
 
DAS_API das_val_type DasAry_valType (const DasAry *pThis)
 Get the type of value stored in the array if knownh. More...
 
DAS_API const char * DasAry_valTypeStr (const DasAry *pThis)
 Get the type of value stored in the array as a text string.
 
DAS_API char * DasAry_toStr (const DasAry *pThis, char *sInfo, size_t uLen)
 Get a informational string representing the array. More...
 
DAS_API size_t DasAry_size (const DasAry *pThis)
 Get the total number of data values in an array, regardless of it's shape. More...
 
DAS_API size_t DasAry_valSize (const DasAry *pThis)
 Get the size in bytes of each element stored in the das array. More...
 
DAS_API size_t DasAry_lengthIn (const DasAry *pThis, int nIdx, ptrdiff_t *pLoc)
 Return the current max value + 1 for any index. More...
 
DAS_API int DasAry_shape (const DasAry *pThis, ptrdiff_t *pShape)
 Return current valid ranges for this array indices. More...
 
DAS_API int DasAry_stride (const DasAry *pThis, ptrdiff_t *pShape, ptrdiff_t *pStride)
 Return the strides used for offest calculations. More...
 
DAS_API bool DasAry_setFill (DasAry *pThis, das_val_type vt, const ubyte *pFill)
 Change the fill value for this array. More...
 
DAS_API bool DasAry_validAt (const DasAry *pThis, ptrdiff_t *pLoc)
 Is a valid item located at a complete index. More...
 
DAS_API const ubyte * DasAry_getAt (const DasAry *pThis, das_val_type et, ptrdiff_t *pLoc)
 Get a pointer to an element at a complete index. More...
 
#define DasAry_getFloatAt(pThis, pLoc)   *((float*)(DasAry_getAt(pThis, vtFloat, pLoc)))
 Wrapper around DasAry_get for IEEE-754 binary32 (float)
 
#define DasAry_getDoubleAt(pThis, pLoc)   *((double*)(DasAry_getAt(pThis, vtDouble, pLoc)))
 Wrapper around DasAry_get for IEEE-754 binary64 (double)
 
#define DasAry_getByteAt(pThis, pLoc)   *((ubyte*)(DasAry_getAt(pThis, vtUByte, pLoc)))
 Wrapper around DasAry_get for unsigned bytes.
 
#define DasAry_getUShortAt(pThis, pLoc)   *((uint16_t*)(DasAry_getAt(pThis, etUint16, pLoc)))
 Wrapper around DasAry_get for unsigned 16-bit integers.
 
#define DasAry_getShortAt(pThis, pLoc)   *((int16_t*)(DasAry_getAt(pThis, etInt16, pLoc)))
 Wrapper around DasAry_get for signed 16-bit integers.
 
#define DasAry_getIntAt(pThis, pLoc)   *((int32_t*)(DasAry_getAt(pThis, etInt32, pLoc)))
 Wrapper around DasAry_get for 32-bit integers.
 
#define DasAry_getLongAt(pThis, pLoc)   *((int64_t*)(DasAry_getAt(pThis, etInt64, pLoc)))
 Wrapper around DasAry_get for signed 64-bit integers.
 
#define DasAry_getTimeAt(pThis, pLoc)   *((das_time*)(DasAry_getAt(pThis, vtTime, pLoc)))
 Wrapper around DasAry_get for das_time_t structures.
 
#define DasAry_getTextAt(pThis, pLoc)   *((char**)(DasAry_getAt(pThis, vtText, pLoc)))
 Wrapper around DasAry_get for pointers to null-terminated strings.
 
DAS_API bool DasAry_putAt (DasAry *pThis, ptrdiff_t *pStart, const ubyte *pVals, size_t uVals)
 Set values starting at a complete index. More...
 
DAS_API const ubyte * DasAry_getIn (const DasAry *pThis, das_val_type et, int nDim, ptrdiff_t *pLoc, size_t *pCount)
 Get a pointer to the elements contained by a partial index. More...
 
#define DasAry_getFloatsIn(T, ...)   (const float*) DasAry_getIn(T, vtFloat, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getDoublesIn(T, ...)   (const double*) DasAry_getIn(T, vtDouble, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getCharsIn(T, ...)   (const char*) DasAry_getIn(T, vtUByte, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getBytesIn(T, ...)   (const ubyte*) DasAry_getIn(T, vtUByte, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getUShortsIn(T, ...)   (const uint16_t*) DasAry_getIn(T, vtUShort, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getShortsIn(T, ...)   (const int16_t*) DasAry_getIn(T, vtShort, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getLongsIn(T, ...)   (const int64_t*) DasAry_getIn(T, vtLong, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getTimesIn(T, ...)   (const das_time*) DasAry_getIn(T, vtTime, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
#define DasAry_getTextIn(T, ...)   (const char**) DasAry_getIn(T, vtText, __VA_ARGS__)
 A wrapper around DasAry_getIn that casts the output and preforms type checking.
 
DAS_API DasAryDasAry_subSetIn (DasAry *pThis, const char *id, int nIndices, ptrdiff_t *pLoc)
 Get a lower rank array that is a sub-set of the current array. More...
 
DAS_API size_t DasAry_qubeIn (DasAry *pThis, int iRecDim)
 Use fill values to make sure the last subset in a dimension is a QUBE. More...
 
DAS_API ubyte * DasAry_append (DasAry *pThis, const ubyte *pVals, size_t uCount)
 Append some number of items to the end of the array. More...
 
DAS_API void DasAry_markEnd (DasAry *pThis, int iDim)
 Mark a ragged dimension as finished. More...
 
DAS_API size_t DasAry_clear (DasAry *pThis)
 Clear all values from the array. More...
 
DAS_API int DasAry_cmp (DasAry *pThis, const ubyte *vpFirst, const ubyte *vpSecond)
 Compare two items of the type in the array. More...
 
DAS_API void DasAry_setSrc (DasAry *pThis, int nPktId, size_t uStartItem, size_t uItems)
 Record which packets contain data destine for this array. More...
 
DAS_API size_t DasDs_clearRagged0Arrays (DasDs *pThis)
 Clear any arrays that are ragged in index l. More...
 

Data Fields

void * pUser
 User data pointer. More...
 

Detailed Description

Dynamic recursive ragged arrays.

This class maps any number of indices, (i,j,k...) to elements stored into a continuous array. Any or all particular indexes of the array may be ragged if desired, though typically for fixed record size data streams, only the first index has an arbitrary length.

The backing buffers for the array grow as needed when new elements are appended. Individual elements may be arbitrary composite types, though extra capabilites are provided for a handful of known types.

Handling ragged data comes at a cost in that the length of each continuous run of elements must also be stored in an ancillary array since address strides are not necessarily constant. This cost is 8 to 16 bytes times the size of all indexes, except the last. For example, an array of shape (10,100,40) would use 10*100*16 extra bytes compared to a simple strideable array, though this is typically much smaller than the 10*100*40*element_size bytes used by the primary data buffer.

Handling ragged data also comes at a cost in terms of potential cache misses. For example to lookup a value in a rank 3 array requires accessing three dynamically allocated buffers. One for each dimension of the array. The first two are offset value buffers, the last is the actual data buffer.

Automatically switching to more efficent strided index calculations in cases where all records are of a constant size has yet to be implemented, though the DasAry_stride() function can be used to stride across the raw data buffer efficently if desired.

// For this example, assume the file below consists of big endian floats
const char* my_file = "my_big_endian_datafile.dat";
FILE* in_file = fopen(my_file, "rb");
// The following Rank 2 array is initially 0 records long and has
// 152 values per record. Thus it starts as a 0 by 152 array
Array* pAry = new_Array("amplitudes", etFloat, 0, NULL, RANK_2(0, 152));
// Set byte order for input values. This will trigger swapping if host
// byte order is different from input order. Note that this only works
// for the types in the element_type enumeration. For unknown types you'll
// have to do your own byte swapping.
DasAry_inputBO(pAry, DAS2ARY_BIG_ENDIAN);
// Read values into the array
float buf[152] = {0.0f};
while(fread(buf, sizeof(float), 152, in_file) == 152)
DasAry_append(pAry, buf, 152);
// Get the shape of the first index.
printf("%d records read from %s\n", DasAry_lengthIn(pAry, DIM0), my_file);
// Print the values in the array, loop below works with ragged arrays and
// reduces function call overhead by accessing a full record at a time
float* pVals;
size_t uVals;
for(size_t i = 0; i < DasAry_lengthIn(pAry, DIM0); ++i){
pVals = DasAry_getFloatsIn(pAry, DIM1_AT(i), &uVals);
for(size_t j = 0; j < uVals; ++j){
if( j > 0) printf(", ");
printf("%.4e", pVals[j]);
}
printf("\n");
}
#define DasAry_getFloatsIn(T,...)
A wrapper around DasAry_getIn that casts the output and preforms type checking.
Definition: array.h:962
DAS_API ubyte * DasAry_append(DasAry *pThis, const ubyte *pVals, size_t uCount)
Append some number of items to the end of the array.
DAS_API size_t DasAry_lengthIn(const DasAry *pThis, int nIdx, ptrdiff_t *pLoc)
Return the current max value + 1 for any index.

Member Function Documentation

◆ new_DasAry()

DAS_API DasAry * new_DasAry ( const char *  id,
das_val_type  et,
size_t  sz_each,
const ubyte *  fill,
int  rank,
size_t *  shape,
das_units  units 
)

Creates a new dynamic array buffer.

Parameters
idA string token for this array. Must not be null, must not be more than 63 characaters long. In general it follows the rules for variable names in most languages.
Todo:
see if these restrictions can be lifted.
Parameters
etThe element type, for arbitrary element storage use vtUnknown, specific types are provided in enum element_type.
sz_eachThe size of each element in the array in bytes. This parameter is only used when the element type is vtUnknown.
fillA pointer to the value for initializing all empty array records. The value should be size_each bytes long. These bytes are copied into the array and this pointer need not remain valid after the constructor call. For unknown types (et = etUnknown) this is a required, non NULL parameter. For known types you can use NULL to automatically set fill to the following values, based on the element_type:
  • etByte 0
  • etUShort 65535
  • etShort -32767
  • etInt -2147483647
  • etLong -9223372036854775807L
  • etFloat -1.0e31
  • etDouble -1.0e31
  • etTime 0000-01-01T00:00:00.000

pFill can point to stack memory as the fill bytes are copied in.

Parameters
rankThe number of dimensions in the array. This sets the number of arguments needed in the get() function call. To make your code easier to read, the defines RANK_1, RANK_2, ... RANK_8 are provided.
shapeThe initial shape of the array. One integer is needed here for each dimension in the array. Use the value 0 to set a dimension to be unbounded. Multi-dimension arrays used to hold an arbitrarily long set of records are typically only unbounded in the first index, though see the example in DasAry_markEnd for handling multiply ragged arrays.
Returns
A new array buffer allocated on the heap.
// Create a rank 3 array that is ragged only in the first index, with a
// fill value of -1.0f, useful for storing a stream of fixed size MARSIS
// AIS records
float fill = -1.0f;
Array* pA = new_Array("fee", etFloat, 0, &fill, RANK_3(0,160,80));
// Create an empty Rank 2 array, that is ragged in both indices.
// (Useful for Cassini WBR data)
Array* pA = new_Array("fi", etFloat, 0, NULL, RANK_2(0,0));
// Theoretical example of creating a triply ragged array to hold
// text from a document, where the first index is the page the
// second is the line and the third is the byte in a line
Array* pA = new_Array("text", etByte, 0, NULL, RANK_3(0,0,0));
Warning
The number of shape parameters must be equal to the rank of the array. The compiler can't check this, but you will get segfaults if the value of rank does not match the number of shape values. To help avoid this the use of the RANK_* macros is highly recommended.

◆ DasAry_setUsage()

DAS_API unsigned int DasAry_setUsage ( DasAry pThis,
unsigned int  uFlags 
)

Set usage flags to assist arbitrary consumers understand how to use this array.

das arrays can store co-opertive flags, these do not change the array API but do indicate how the array should be used. The following two usage flags are currently defined:

  • D2ARY_AS_SUBSEQ : Contains Sub-sequences
  • D2ARY_FILL_TERM : Contains FILL terminated sub-sequences
  • D2ARY_AS_STRING : Contains FILL terminated sub-sequences and FILL is 0

You can add your own flags as well so long as they have the value:

  • 0x0001000

or higher they will be preserved through calls to setUsage and getUsage

Parameters
pThis
uFlagsAll the flag values to set at once.
Returns
The old flag setting

◆ inc_DasAry()

DAS_API int inc_DasAry ( DasAry pThis)

Increment the count of objects using this Das Array.

Returns
The new count.

◆ dec_DasAry()

DAS_API void dec_DasAry ( DasAry pThis)

Maybe remove the array.

Calling this function decrements the reference count for the array. If the count reaches zero all backing buffers (owned by this array) are deleted.

◆ DasAry_disownElements()

DAS_API ubyte * DasAry_disownElements ( DasAry pThis,
size_t *  pLen,
size_t *  pOffset 
)

Take ownership of array element memory.

Internally all Das Array elements are stored in a single continuous 1-D buffer. When the Das Array is deleted, this buffer is removed as well, if it's owned by the das array.

Parameters
pThisA pointer to a das array structure
pLenA pointer to a variable to hold the length of the element array in elements (not bytes). If the array had no values then length is set to 0
pOffsetWhere to store the offset in elements (not bytes) to the start of valid values. Internally arrays may have invalid values in the memory buffer before valid values start.
Returns
A pointer to the raw 1-D element buffer if the Array actually owned the elements, NULL otherwise. If not NULL the returned pointer may be passed to the free() function. See additional return notes below.

Return Notes: Buffer memory is not allocated until elements are inserted (lazy allocation) thus an empty array WILL NOT own any elements. So this this function will ALWAYS return NULL for an empty array. Use the value returned by pLen to see if the NULL return was because the array didn't own it's elements or if there were no elements to own.

Once elements are disowed, they can't be disowned again. Calling disownElements twice in succession in a single threaded program will always return NULL on the second call.

Implementation detail: The internal ragged index tracking arrays may still be owned by the DasAry object and will be deleted when the overall structure is deleted

◆ DasAry_ownsElements()

DAS_API bool DasAry_ownsElements ( const DasAry pThis)

Does this array own it's own memory?

If an array owns it's element memory then DasAry_disownElements will return a valid memory buffer if there are any valid values.

Returns
true if the array owns it's element memory, false otherwise.

◆ DasAry_id()

DAS_API const char * DasAry_id ( const DasAry pThis)

Get the name of an array.

Parameters
pThisA constant pointer to this array structure
Returns
A constant pointer to the identifier for the array

◆ DasAry_valType()

DAS_API das_val_type DasAry_valType ( const DasAry pThis)

Get the type of value stored in the array if knownh.

This function is used by dataset objects to know how to cast pointers to different data array values.

Parameters
pThisA constant pointer to this array structure
Returns
A constant pointer to string containing the name for the values in the array, or NULL if the value type has not been set.

◆ DasAry_toStr()

DAS_API char * DasAry_toStr ( const DasAry pThis,
char *  sInfo,
size_t  uLen 
)

Get a informational string representing the array.

Parameters
pThisThe Array in question
sInfopointer to the destination to hold the info string
uLenthe length of the sInfo buffer
Returns
the pointer sInfo

◆ DasAry_size()

DAS_API size_t DasAry_size ( const DasAry pThis)

Get the total number of data values in an array, regardless of it's shape.

Parameters
pThisA constant pointer to this array structure
Returns
The total number of items stored in the array, regardless of it's shape.

◆ DasAry_valSize()

DAS_API size_t DasAry_valSize ( const DasAry pThis)

Get the size in bytes of each element stored in the das array.

Parameters
pThisThe Array in question
Returns
The size of each element in bytes

◆ DasAry_lengthIn()

DAS_API size_t DasAry_lengthIn ( const DasAry pThis,
int  nIdx,
ptrdiff_t *  pLoc 
)

Return the current max value + 1 for any index.

This is a more general version of DasAry_shape that works for both cubic arrays and those with ragged dimensions. For any index to be inspected, the value of all previous indices must be given. This is less confusing then it sounds, see the example below

See also
DasAry_shape For simple arrays that are only ragged in the first index.
Parameters
pThisA pointer to an array object
nIdxThe number of location indices, should be less than the rank in order to get the length of a range of values. The macros DIM0, DIM1_AT, DIM2_AT, etc. are provided which combine this argument and the one below to make calling code more readable, see the example below.
pLocA list of the values for previous indices. The macros DIM1, DIM2_AT, DIM3_AT etc. are provided which combine this argument with the one above to make calling code more readable, see the example below.
Returns
The current maximum valid value for the ith index at current location in the previous indices.
// Here pWBR is a ragged array of all waveform amplitudes taken in a single
// capture. Dimension 0 corresponds to the capture time point and dimension
// 1 corresponds to each sample in a capture.
// Print the number of samples in each waveform.
size_t uWaveforms = DasAry_lengthIn(pWBR, DIM0);
for(size_t u = 0; u &lt; uWaveforms; ++u)
print("Capture %zu has %zu samples\n", u, DasAry_lengthIn(pWBR, DIM1_AT(u));
See also
DasAry_getAt to obtain both the length and a pointer to a continuous range of data Values an once.

◆ DasAry_shape()

DAS_API int DasAry_shape ( const DasAry pThis,
ptrdiff_t *  pShape 
)

Return current valid ranges for this array indices.

See also
DasAry_lengthIn
Parameters
pThispointer to an array object
[out]pShapepointer to an array to received the current number of entries in each dimension, should be at least RANK in length. Each element of the output array will be one of the following.
  • An integer from 0 to LONG_MAX to indicate a valid index range
  • The value DASIDX_RAGGED to indicate that the valid index is variable and depends on the values of other indices.
Returns
The rank of the array.

◆ DasAry_stride()

DAS_API int DasAry_stride ( const DasAry pThis,
ptrdiff_t *  pShape,
ptrdiff_t *  pStride 
)

Return the strides used for offest calculations.

To support fast iteration over array data it's often useful to get a raw pointer and then stride across the 1-D array using an index calculation. Ragged arrays do not have a uniform stride, but many arrays are not ragged and sub-sections of ragged arrays may not be ragged. Use this function to get the stride coefficents.

Parameters
pThispointer to an array object
[out]pShapeThe extent of the array in each index. The total number of elements is just the multiple of all values in this array up to the rank.
[out]pStridepointer to an array to recive the number of elements to increment for each successive value of this index. Note that this is not the number of bytes to stride. Use DasAry_valSize() to get the size of each element.
Returns
the rank of the array, or -1 if an input error is detected.

◆ DasAry_setFill()

DAS_API bool DasAry_setFill ( DasAry pThis,
das_val_type  vt,
const ubyte *  pFill 
)

Change the fill value for this array.

Set the fill value but don't re-write the data in the array. Any data locations in the array will still have the fill value. To change them iterate over the array looking for the old fill value an replace them in a loop.

Parameters
pThisThe array to structure to alter
pFillPointer to the relpacement fill value, use NULL to set this to the connonical fill value for this type.
vtThe element type for the new fill value. This is used as a cross check. The element type of the new fill value must match the old one.
Returns
true if fill setting succeeded, false otherwise.

◆ DasAry_validAt()

DAS_API bool DasAry_validAt ( const DasAry pThis,
ptrdiff_t *  pLoc 
)

Is a valid item located at a complete index.

Parameters
pThisA pointer to the array
pLocAn array of indices of length RANK. A rank 1 Das Array requires two indices to access an element, a rank 2 requires three, etc. The macros LOC_1, LOC_2, etc have been provided to make code more readable. See the example below.
Returns
true the location list refers to a valid array index set. False otherwise. Not that the actual value at the index may be a fill value.
Array* pAry = new_Array("amplitudes", FLOAT, NULL, RANK_3(0, 160, 80));
size_t uRec = 0;
// See if we have a complete MARSIS frame for this record...
if(! DasAry_validAt(pAry, IDX3(uRec, 159, 79)))
fprintf(stderr, "Error: Short frame count in record %zu", uRec);
DAS_API bool DasAry_validAt(const DasAry *pThis, ptrdiff_t *pLoc)
Is a valid item located at a complete index.

◆ DasAry_getAt()

DAS_API const ubyte * DasAry_getAt ( const DasAry pThis,
das_val_type  et,
ptrdiff_t *  pLoc 
)

Get a pointer to an element at a complete index.

For type safety the macros DasAry_getFloat, DasAry_getDouble, etc have been provided and should be used instead of the base function here.

Parameters
pThisA pointer to the array
etThe element type pointer expected at the given location, this is used by the type checking macros DasAry_getFloat and friends.
pLocAn array of indices of length RANK. A rank 2 Das Array requires two indices to access an element, a rank 3 requires three, etc. The macros IDX0, IDX1, IDX2, etc have been provided to make code more readable. See the example below.
Returns
a pointer to value at the given indices, or NULL if that location is not valid and das_return_on_error() has been called.
// Uses type checking macro's
das_time_t dt = DasAry_getTimeAt(pAry, IDX0(uRec));
// Get last event, whereever it is
const char* sEvent = DasAry_getTextAt(pAry, IDX0(-1));
#define DasAry_getTimeAt(pThis, pLoc)
Wrapper around DasAry_get for das_time_t structures.
Definition: array.h:877
#define DasAry_getTextAt(pThis, pLoc)
Wrapper around DasAry_get for pointers to null-terminated strings.
Definition: array.h:880
See also
DasAry_getIn to access multiple Values at once avoiding function call overhead in tight loops.

◆ DasAry_putAt()

DAS_API bool DasAry_putAt ( DasAry pThis,
ptrdiff_t *  pStart,
const ubyte *  pVals,
size_t  uVals 
)

Set values starting at a complete index.

Note, this will not expand the size of the array. Use the function append() to automatically grow the array to store the desired number of items.

Parameters
pThisA pointer to the array
pStartThe complete index to the starting point to write values, use the macros IDX1, IDX2, etc. to make calling code more readable
pValsThe values to write
uValsThe number of values to write
Returns
true if the items could be written, false if the array is not large enough to hold all the values or if any other error is encountered

◆ DasAry_getIn()

DAS_API const ubyte * DasAry_getIn ( const DasAry pThis,
das_val_type  et,
int  nDim,
ptrdiff_t *  pLoc,
size_t *  pCount 
)

Get a pointer to the elements contained by a partial index.

Parameters
pThisA Array containing the data of interest
etThe expected type of element to be returned. This is used by the type safe macros DasAry_getDoubleAt, DasAry_getTextAt, etc.
nDimThe number of location indices, should be less than the rank in order to get the length of a range of values. The macros DIM0, DIM1_AT, DIM2_AT, etc. are provided which combine this argument and the one below to make calling code more readable, see the example below.
pLocAn array of location indices, nDim long. Use the macros DIM0, DIM1_AT, DIM2_AT, etc. for cleaner code.
pCountA pointer to a variable to hold the number of elements under the given index. If nIndices is equal to the array rank the returned value will be at most 1.
Returns
A pointer a continuous subset of elements, or NULL if no elements are located at the given index set. You will have to cast this pointer to the element type.
// Print all the events in an array
size_t uVals;
char** events = DasAry_getTextIn(pAry, DIM1, &uVals);
for(size_t u = 0; u < uVals; ++u)
printf("Event %06zu: %s\n", u, events[u]);
#define DasAry_getTextIn(T,...)
A wrapper around DasAry_getIn that casts the output and preforms type checking.
Definition: array.h:998
// Print all the magnetic amplitudes for a single time slice at index 117
size_t uVals;
cost float* pAmp = DasAry_getFloatsIn(pAry, DIM2_AT(117), &uVals);
for(size_t u = 0; u < uVals; ++u)
printf("Amp at freq %03zu: %s nT**2/Hz \n", u, events[u]);

◆ DasAry_subSetIn()

DAS_API DasAry * DasAry_subSetIn ( DasAry pThis,
const char *  id,
int  nIndices,
ptrdiff_t *  pLoc 
)

Get a lower rank array that is a sub-set of the current array.

For some given number of indices, produce a sub-array. This is similar to DasAry_getAt but produces a whole new Array object whose data are provided stored in a separate Array.

// Get all data for the 10th record of a 2-D dataset, would often be a
// time slice for das2 streams.
Array* pRec = DasAry_subSetIn(pAllData, INDEX_0, 10);
// Get the time delays for frequency index 100 for time point 22 of a
// MARSIS AIS data stream
Array* pDelays = DasAry_subSetIn(pAllData, "rec_22", DIM2_AT(22, 100));
DAS_API DasAry * DasAry_subSetIn(DasAry *pThis, const char *id, int nIndices, ptrdiff_t *pLoc)
Get a lower rank array that is a sub-set of the current array.
Parameters
pThisA pointer to the array to subset. It is not a constant pointer due to the need to increment the reference count.
idA identifying name for the new sub-array
nIndicesThe number of location indices, should be less than the rank in order to get a range of values. Use the macros DIM0, DIM1_AT, DIM2_AT, etc. for cleaner code.
pLocAn array of location indices, nIndices long. Use the macros DIM0, DIM1_AT, DIM2_AT, etc. for cleaner code.
Returns
A new Array allocated on the heap that does not own it's backing buffer.

◆ DasAry_qubeIn()

DAS_API size_t DasAry_qubeIn ( DasAry pThis,
int  iRecDim 
)

Use fill values to make sure the last subset in a dimension is a QUBE.

Parameters
pThisthe array
iRecDimThe dimension to qube, typically the last dimension in the array, dimensions are numbered starting from 0. Use the macro's DIM1, DIM2, etc. to make the code more readable. Dimension 0 can't be marked as ended and the macro DIM0 will not work here.
Returns
the number of fill values added to the array
Array* pAry = new_Array("marsis", etFloat, 0, NULL, RANK_3(0, 160, 80));
//Example 1: Read a complete sets of delay times
float buf[80];
size_t uRead = fread(buf, sizeof(float), 80, stdin);
DasAry_append(pAry, buf, uRead);
DasAry_qubeIn(pAry, DIM2);
//Example 2: Read in complete ionograms
float buf[160*80];
size_t uRead = fread(buf, sizeof(float), 80*160, stdin);
DasAry_append(pAry, buf, uRead);
DasAry_qubeIn(pAry, DIM1);
DAS_API size_t DasAry_qubeIn(DasAry *pThis, int iRecDim)
Use fill values to make sure the last subset in a dimension is a QUBE.
See also
DasAry_append

◆ DasAry_append()

DAS_API ubyte * DasAry_append ( DasAry pThis,
const ubyte *  pVals,
size_t  uCount 
)

Append some number of items to the end of the array.

This works as you would expect for all arrays that are only ragged in the 0th dimension.

See also
DasAry_markEnd. Arrays that are ragged in dimension other that the 0th need some way to know that it's time to roll the index back to 0 on the next append operation, DasAry_markEnd sets the needed flags.
Parameters
pThisThe array which should copy in the new values.
pValsA constant pointer to values to add MAY BE NULL! If NULL uCount fill values are appended
uCountThe number of values to add
Returns
A pointer to the first value written or NULL if an error occurred

◆ DasAry_markEnd()

DAS_API void DasAry_markEnd ( DasAry pThis,
int  iDim 
)

Mark a ragged dimension as finished.

Parameters
pThisThe das array
iDimThe dimension which should have it's index rolled back to zero on the next insert. Marking the end of a low index (say 1) automatically marks the end of any higher indices (ex 2,3).
// Read in lines of text into an array that stores data by page number,
// line number and the byte number. Input processing is simplistic in
// order to focus on Array calls.
byte fill = 0;
Array* pAry = new_Array("source", etByte, 0, &fill, RANK_3(0,0,0));
char sBuf[1024] = {'\0'};
size_t uLen = 0;
while(!eof(stdin)){
while(fgets(sBuf, 1024, stdin)){
uLen = strlen(sBuf);
if(sBuf[0] == 0x0C) DasAry_markEnd(pAry, DIM1); // end page
DasAry_append(pAry, sBuf, uLen+1); // keep NULL terminators
if(sBuf[uLen - 1] == '\n') DasAry_markEnd(pAry, DIM2); // end line
}
}
DAS_API void DasAry_markEnd(DasAry *pThis, int iDim)
Mark a ragged dimension as finished.

◆ DasAry_clear()

DAS_API size_t DasAry_clear ( DasAry pThis)

Clear all values from the array.

This operation internally just resets the count of items to 0 in all arrays it does not free memory. Dimensions above the 0th retain their shape.

Parameters
pThisThe array to clear
Returns
then number of items cleared

◆ DasAry_cmp()

DAS_API int DasAry_cmp ( DasAry pThis,
const ubyte *  vpFirst,
const ubyte *  vpSecond 
)

Compare two items of the type in the array.

Returns
A value less than zero if *pFirst is less than *pSecond, a value greater than zero if *pFirst is greater than *pSecond and 0 if both values are equal

◆ DasAry_setSrc()

DAS_API void DasAry_setSrc ( DasAry pThis,
int  nPktId,
size_t  uStartItem,
size_t  uItems 
)

Record which packets contain data destine for this array.

Parameters
pThisThe array
nPktIdThe id of the Das packet which contains values that should be added to this array
uStartItemThe location in the packet where this array's data starts
uItemsThe number of items to add from each packet

◆ DasDs_clearRagged0Arrays()

DAS_API size_t DasDs_clearRagged0Arrays ( DasDs pThis)

Clear any arrays that are ragged in index l.

This function is handy when reading data to insure that memory usage does not grow without limit. Any memory allocated is not freed, but the write points are reset so that the same buffers can be used over and over again.

Parameters
pThisA dataset
Returns
The number of bytes cleared.

Field Documentation

◆ pUser

void* pUser

User data pointer.

The stream -> dataset -> array hierarchy provides a goood organizational structure for application data, especially applications that filter streams. It is initialized to NULL when a variable is created but otherwise the library dosen't deal with it.


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