Cabinet keys are NULL-terminated C strings. This constant declares the maximum length of one component of that string.
The characters in the key string must all be low ASCII alphanumeric characters, such as '0'- '9', 'a'- 'z', 'A'- 'Z'.
You can burrow through multiple levels of a cabinet heirarchy by passing in a string of individual key names separated by colons.
For example, ASCabGetInt(cab, "Hello:World",-1); is equivalent to ASCabGetInt(ASCabGetCab(cab, "Hello"), "World",-1);.
Similarly, ASCabPutInt(theCab, "Hello:World", 33); will create an integer key named "World" inside the "Hello" cabinet inside theCab, creating the "Hello" key and cabinet if necessary.
#define MAX_ASCAB_KEY 1024
ASCab objects ( cabinets) can be used to store arbitrary key/value pairs. The keys are always NULL-terminated strings containing only low ASCII alphanumeric characters and spaces (ASCII character 32). Key names cannot begin or end with a space.
Every time you place a non-scalar value inside a cabinet, you are handing that value to the ASCab implementation to manage. Putting a value in a cabinet is always a handoff operation. For example, if you create an ASText object and add it as a value in an ASCab, the ASText object is no longer managed by you; it is managed by the ASCab. The ASCab will destroy the ASText object when its associated key is removed or the key's value is overwritten. Pointer values are a special case discussed in more detail below.
The routine naming convention is as follows:
Name | Description
|
|---|---|
Get
| Get routines return a value. These objects are owned by the ASCab and should not be destroyed by the caller of Get. |
GetCopy
| GetCopy routines make a copy of the data; the GetCopy client owns the resulting information and can modify it at will; it is also responsible for destroying it. |
Detach
| Detach routines work the same way as Get routines, but the key is removed from the ASCab without destroying the associated value that is passed back to the client of Detach. The client is responsible for destroying the returned object. |
Normally, pointers are treated the same way as scalars; the ASCab passes the pointer value back and forth but does not manage the data to which it points. This all changes if the pointer has an associated destroyProc. If the destroyProc is set, the ASCab will reference count the pointer to track how many times the pointer is referenced from any ASCab. For example, the reference count will be bumped up whenever the pointer is copied via ASCabCopy() or added to another ASCab via ASCabPutPointer(), and will destroy the data associated with the pointer when the reference count goes to 0. The data is destroyed by calling the destroyProc. Detaching a pointer removes one reference to the pointer without ever destroying the information to which it points. ASCabDetachPointer() returns a separate value indicating whether the pointer can safely be destroyed by the client or is still referred to by other key/value pairs inside any ASCab objects (for example, whether the reference count went to zero when the pointer was detached from the ASCab).
Any of the ASCab API's can take a compound name: a string consisting of multiple keys separated by the colon (:) character. For example, "Grandparent:Parent:Child:Key" can be such a compound name. The implementation will burrow down through such a compound string until it reaches the most deeply nested cabinet. Also, any of the Put routines can take a NULL key name. If the key name is NULL, the routine creates a new numeric key name. If the cabinet is empty, the first generated key name will be "0" and subsequent names will increase in ascending order. This is useful when treating an ASCab as a bag of unnamed items, or when adding an ordered list of items to an empty ASCab.
typedef struct _t_ASCabinet *ASCab;
keyCab is the ASCab that provides the keys determining how theCab is to be changed. During an ASCabMunge() operation, the key cab will not be altered.
For value options see ASMungeOptions.
typedef ASEnum16 ASCabMungeAction;
typedef ASEnum16 ASCabValueType;
typedef const struct _t_ASCabinet *ASConstCab;
ASBool ASCabEnumProc(ASCab theCab, const char *theKey, ASCabValueType itsType, void *clientData);
theCab | The cabinet being enumerated.
|
theKey | The key name of an entry in the cabinet.
|
itsType | The type of the value associated with
theKey. |
clientData | User-supplied data passed into ASCabEnum.
|
void ASCabPointerDestroyProc(void *ptr);
ptr | IN/OUT The value stored in an ASCab.
|
theCab during the enumeration. ASBool ASConstCabEnumProc(ASConstCab theCab, const char *theKey, ASCabValueType itsType, void *clientData);
theCab | The cabinet being enumerated.
|
theKey | The key name of an entry in the cabinet.
|
itsType | The type of the value associated with
theKey. |
clientData | User-supplied data passed into ASCabEnum.
|
A data structure representing a cabinet entry. The first entry in each descriptor specifies the name of the key, the second field contains the type, and the following fields contain the values. The entry list must end with a descriptor containing NULL for the key name. It can be used as shown below to construct an ASCab:
ASCabEntryRec cabData[] = {{"key1", kASValueInteger, 1}, {"key2", kASValueInteger,-1}, {"key3", kASValueBool, false}, {NULL}};
ASCab CreateDefaultCab() { return ASCabFromEntryList (cabData); }
This example uses just three values for each record. However, more may be required, such as a double:
{"keyDouble", kASValueDouble, 0, NULL, double}
For a string, the following code could be used:
{"keyString", kASValueString, 0, (void *)string}
| |||||||||||||||||||
const char *keyName; | The name of the key.
| ||||||||||||||||||
The supported ASCabValueTypes are:
No other types are supported (specifically kASValueCabinet and kASValuePointer). You can build nested cabinets using the | |||||||||||||||||||
See above.
| |||||||||||||||||||
const void *ptrVal; | See above.
| ||||||||||||||||||
double doubleVal; | See above.
| ||||||||||||||||||
|
srcCab a copy of the key/value pair will be placed into dstCab, possibly overwriting any identically named key/value pair in dstCab. If the value being copied is a pointer with an associated destroyProc, the pointer and its type string, but not the data it points to, will be copied and an internal reference count will be incremented. void ASCabCopy(ASConstCab srcCab, ASCab dstCab);
srcCab | The source cabinet.
|
dstCab | The destination cabinet.
|
void ASCabDestroy(ASCab theCab);
theCab | The cabinet.
|
theCab, removes their corresponding keys, and destroys them. void ASCabDestroyEmpties(ASCab theCab, ASBool recurse);
theCab | The cabinet.
|
recurse |
Retrieves the binary object stored under theKey in theCab and removes the key from theCab.
The client assumes ownership of the object and is responsible for deallocating any resources associated with it.
void *ASCabDetachBinary(ASCab theCab, const char *theKey, ASTArraySize *numBytes);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
numBytes |
NULL if theKey is not present in theCab or if the value stored under theKey is not of type kASTypeBinary. ASCab ASCabDetachCab(ASCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
NULL if theKey is not present in theCab, or if the value stored under theKey is not of type kASValueCabinet. Retrieves the ASPathName stored under theKey in theCab and removes the key from theCab.
Both fileSys and pathName will be NULL if theKey was not found, there was no valid ASPathName stored under the key, or if the ASPathName does not point to an existing file.
It is the client's responsibility to release the memory associated with the ASPathName using ASFileSysReleasePath().
void ASCabDetachPathName(ASCab theCab, const char *keyName, ASFileSys *fileSys, ASPathName *pathName);
theCab | IN/OUT The cabinet.
|
keyName | IN/OUT The key name.
|
fileSys | IN/OUT (Filled by the method) The ASFileSys that pathName was opened through.
|
pathName | IN/OUT (Filled by the method) The path name.
|
Any
| exceptions raised by ASFileSysPathFromDIPath.
|
theKey in theCab and removes the key from theCab. If noRefs is set to true, the client assumes ownership of the data referenced by the pointer and is responsible for deallocating any resources associated with it. void *ASCabDetachPointerRaw(ASCab theCab, const char *theKey, const char *expectedType, ASBool *noRefs);
theCab | The cabinet.
|
theKey | The key name.
|
expectedType | The data type referenced by the pointer. Since ASCabGetPointer() is actually a macro, you should pass the type as a literal name, not a string. For example, use
PDDoc instead of "PDDoc". Pointers are always typed, in that they always have associated with them a string indicating the type to which they point. |
noRefs |
theKey. It will be NULL if theKey is not present in theCab, the value stored under theKey is not of type kASValuePointer, or the type of the pointer does not match expectedType. Retrieves the string stored under theKey in theCab and removes the key from theCab.
The client assumes ownership of the string and is responsible for deallocating any resources associated with it.
char *ASCabDetachString(ASCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey. Will be NULL if theKey is not present in theCab, or if the value stored under theKey is not of type kASValueString. Retrieves the ASText object stored under theKey in theCab and removes the key from theCab.
The client assumes ownership of the ASText object and is responsible for deallocating it using ASTextDestroy().
ASText ASCabDetachText(ASCab theCab, const char *theKey);
theCab | The cabinet.
|
theKey | The key name.
|
theKey. It will be NULL if theKey is not present in theCab, or if the value stored under theKey is not of type kASValueText. ASCab ASCabDup(ASConstCab srcCab);
srcCab | The source cabinet.
|
Enumerates all the keys in the cabinet.
Keys consisting solely of digits are enumerated first, in numeric order (assuming they are not padded with zeros at the front, which will confuse matters). Non-numeric keys are then enumerated in strcmp order.
It is safe to add, delete, and modify items in theCab during the enumeration. Items that are added during the enumeration will not be enumerated. Modified items that have been enumerated already will not be enumerated again. Deleted items that have not yet been enumerated will not be enumerated.
Note: This will RERAISE any exceptions thrown by enumProc.
void ASCabEnum(ASCab theCab, ASCabEnumProc enumProc, void *clientData);
theCab | The cabinet.
|
enumProc | A user-supplied callback that is called for each entry found in
theCab. |
clientData | A pointer to user-supplied data to pass to
enumProc each time it is called. |
ASBool ASCabEqual(ASConstCab cab1, ASConstCab cab2);
cab1 | The first cabinet.
|
cab2 | The second cabinet.
|
NULL for the key name. See ASExtraExpT.h for more info. ASCab ASCabFromEntryList(const ASCabEntryRec *entryList);
entryList | A constant array of ASCabDescriptor records (see ASCabEntryRec). Passing
NULL generates an empty ASCab. |
ASAtom ASCabGetAtom(ASConstCab theCab, const char *theKey, ASAtom defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
theKey if the key is found and the value stored under it is of type kASValueAtom; otherwise defValue is returned. theKey in theCab. const void *ASCabGetBinary(ASConstCab theCab, const char *theKey, ASTArraySize *numBytes);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
numBytes |
theKey if the key is found and the value stored under it is of type kASValueBinary; otherwise NULL is returned. This object is owned by the ASCab and should not be destroyed by the caller. Returns a copy of the binary object stored under theKey in theCab.
It is the client's responsibility to release the memory associated with the object using ASfree().
void *ASCabGetBinaryCopy(ASConstCab theCab, const char *theKey, ASTArraySize *numBytes);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
numBytes |
theKey if the key is found and the value stored under it is of type kASValueBinary; otherwise NULL is returned. ASBool ASCabGetBool(ASConstCab theCab, const char *theKey, ASBool defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
theKey if the key is found and the value stored under it is of type kASValueBool; otherwise defValue is returned. ASCab ASCabGetCab(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey if the key is found and the value stored under it is of type kASValueCabinet; otherwise NULL is returned. This object is owned by theCab and should not be destroyed by the client. double value stored under theKey in theCab. If the value stored under theKey is of type kASValueInteger, this value will be cast to a double and returned to the client. double ASCabGetDouble(ASConstCab theCab, const char *theKey, double defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
double value stored under theKey if the key is found and the value stored under it is of type kASValueDouble or kASValueInteger; otherwise defValue is returned. ASInt32 ASCabGetInt(ASConstCab theCab, const char *theKey, ASInt32 defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
theKey if the key is found and the value stored under it is of type kASValueInteger; otherwise defValue is returned. ASInt64 ASCabGetInt64(ASConstCab theCab, const char *theKey, ASInt64 defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
theKey if the key is found and the value stored under it is of type kASValueInt64; otherwise defValue is returned. Returns a copy of ASPathName stored under theKey in theCab.
It is the client's responsibility to release the ASPathName using ASFileSysReleasePath().
Both fileSys and pathName will be NULL if theKey was not found, there was no valid ASPathName stored under the key, or if pathName does not point to an existing file.
void ASCabGetPathNameCopy(ASConstCab theCab, const char *keyName, ASFileSys *fileSys, ASPathName *pathName);
theCab | IN/OUT The cabinet.
|
keyName | IN/OUT The key name.
|
fileSys | IN/OUT (Filled by the method) The ASFileSys that
pathName was opened through. |
pathName | IN/OUT (Filled by the method) The path name.
|
Any
| exception raised by ASFileSysPathFromDIPath.
|
theKey in theCab. When the reference count of the pointer falls to zero, the callback is called to free the resources associated with the object it references. ASCabPointerDestroyProc ASCabGetPointerDestroyProc(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
NULL is returned. theKey in theCab. void *ASCabGetPointerRaw(ASConstCab theCab, const char *theKey, const char *expectedType);
theCab | The cabinet.
|
theKey | The key name.
|
expectedType | The data type referenced by the pointer. Since ASCabGetPointer() is actually a macro, you should pass the type as a literal name, not a string. For example, use
PDDoc instead of "PDDoc". Pointers are always typed, in that they always have associated with them a string indicating the type to which they point. |
theKey if the key is found, the value stored under theKey is of type kASValuePointer, and the type of the pointer matches expectedType; otherwise NULL is returned. The object referenced by this pointer is owned by theCab and should not be destroyed by the client. theKey in theCab. const char *ASCabGetPointerType(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
NULL is returned. theKey in theCab. const char *ASCabGetString(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey if the key is found and the value stored under it is of type kASValueString; otherwise NULL is returned. The object referenced by this pointer is owned by theCab and should not be destroyed by the client. Returns a copy of the string stored under theKey in theCab.
It is the client's responsibility to release the memory allocated for the string using ASfree().
char *ASCabGetStringCopy(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey if the key is found and the value stored under it is of type kASValueString; otherwise NULL is returned. ASText ASCabGetText(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey if the key is found and the value stored under it is of type kASValueText; otherwise NULL is returned. This object is owned by theCab and should not be destroyed by the client. theKey in theCab. ASCabValueType ASCabGetType(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theKey, or kASValueUnknown if the key is not found. ASUns32 ASCabGetUns(ASConstCab theCab, const char *theKey, ASUns32 defValue);
theCab | The cabinet.
|
theKey | The key name.
|
defValue | The default value.
|
theKey if the key is found and the value stored under it is of type kASValueUns; otherwise defValue is returned. ASUns64 ASCabGetUns64(ASConstCab theCab, const char *theKey, ASUns64 defValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
defValue | IN/OUT The default value.
|
theKey if the key is found and the value stored under it is of type kASValueUns64; otherwise defValue is returned. ASBool ASCabKnown(ASConstCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
theCab and destroys all values they point to. void ASCabMakeEmpty(ASCab theCab);
theCab | IN/OUT The cabinet.
|
theCab based on the keys in keyCab and the munge action. Note that keyCab is never altered, but theCab is. void ASCabMunge(ASCab theCab, ASConstCab keyCab, ASCabMungeAction action);
theCab | IN/OUT The cabinet to be modified.
|
keyCab | IN/OUT The cabinet used to modify
theCab. |
action | IN/OUT The type of action to be taken.
|
ASCab ASCabNew(void);
theCab. ASTArraySize ASCabNumEntries(ASConstCab theCab);
theCab | The cabinet.
|
void ASCabPutAtom(ASCab theCab, const char *theKey, ASAtom atomValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
atomValue | IN/OUT The value to be stored.
|
void ASCabPutBinary(ASCab theCab, const char *theKey, void *theBlob, ASTArraySize blobSize);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theBlob | |
blobSize | IN/OUT The size of the binary object.
|
void ASCabPutBool(ASCab theCab, const char *theKey, ASBool theBool);
theCab | IN/OUT The cabinet.
|
theKey | |
theBool |
Stores an ASCab in theCab under theKey. If the cabinet is already a value for some other ASCab, ASCabPutCab() will raise an exception, since any cabinet can be contained by at most one other cabinet.
theCab assumes ownership of the cabinet, so the client must not destroy it.
void ASCabPutCab(ASCab theCab, const char *keyName, ASCab putCab);
theCab | IN/OUT The cabinet.
|
keyName | IN/OUT (May be
NULL) The key name. |
putCab |
double value in theCab under theKey. void ASCabPutDouble(ASCab theCab, const char *theKey, double floatValue);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
floatValue | IN/OUT The value to be stored.
|
void ASCabPutInt(ASCab theCab, const char *theKey, ASInt32 theInt);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theInt | IN/OUT The value to be stored.
|
void ASCabPutInt64(ASCab theCab, const char *theKey, ASInt64 theInt);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theInt | IN/OUT The value to be stored.
|
theCab under theKey. NULL cabinet entries are used as placeholders or to removed other cabinet entries during an ASCabMunge operation. void ASCabPutNull(ASCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
Stores an ASPathName in theCab under theKey.
theCab assumes ownership of the ASPathName, so the client need not call ASFileSysReleasePath().
void ASCabPutPathName(ASCab theCab, const char *keyName, ASFileSys fileSys, ASPathName pathName);
theCab | IN/OUT The cabinet.
|
keyName | IN/OUT (May be
NULL) The key name. |
fileSys | IN/OUT The ASFileSys from which the path was obtained.
|
pathName | IN/OUT (May be
NULL) The ASPathName to be stored. If NULL, the value (if any) stored under theKey in theCab is destroyed and theKey is removed from theCab. |
void ASCabPutPointerRaw(ASCab theCab, const char *theKey, const char *theType, void *thePtr, ASCabPointerDestroyProc destroy);
theCab | The cabinet.
|
theKey | (May be
NULL) The key name. |
theType | The data type referenced by the pointer. Since ASCabGetPointer() is actually a macro, you should pass the type as a literal name, not a string. For example, use
PDDoc instead of "PDDoc". Pointers are always typed, in that they always have associated with them a string indicating the type to which they point. |
thePtr | The value to be stored.
|
destroy | (May be
NULL) A user-supplied callback which is called when the reference count associated with thePtr is zero. |
void ASCabPutString(ASCab theCab, const char *theKey, const char *theStr);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theStr |
Stores an ASText object in theCab under theKey.
theCab assumes ownership of the object, so the client should not attempt to free the memory associated with it.
void ASCabPutText(ASCab theCab, const char *theKey, ASText theText);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theText |
void ASCabPutUns(ASCab theCab, const char *theKey, ASUns32 theUns);
theCab | The cabinet.
|
theKey | The key name.
|
theUns | The value to be stored.
|
void ASCabPutUns64(ASCab theCab, const char *theKey, ASUns64 theInt);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT (May be
NULL) The key name. |
theInt | IN/OUT The value to be stored.
|
ASCab ASCabReadFromStream(ASStm stm);
stm |
theKey entry from theCab, destroying the associated value. void ASCabRemove(ASCab theCab, const char *theKey);
theCab | IN/OUT The cabinet.
|
theKey | IN/OUT The key name.
|
Renames a key within theCab while preserving the value associated with it. If there is already a key equal to newKeyName in theCab, its value will be destroyed and replaced with the value of oldKeyName.
Any attempt to move the item from one sub-cabinet to another will cause ASCabRename() to raise an exception. For example, ASCabRename(theCab, "SubCab1:Key1", "SubCab2:Key1") will raise an exception. If this routine raises an exception, theCab will be untouched.
void ASCabRename(ASCab theCab, const char *oldKeyName, const char *newKeyName);
theCab | The cabinet.
|
oldKeyName | The key name to be changed.
|
newKeyName | The new name.
|
true only if they are equal (meaning that they have the same type and value). Cabinets are compared using ASCabEqual(). ASText values are compared by using ASTextCmp() and testing for a return value of 0 (zero). Strings and binary values must have the same lengths and byte-for-byte contents. Booleans, atoms, doubles, and integers must have equal values. Pointer values must point to the same location in memory but may have different destroyProcs and type strings. ASBool ASCabValueEqual(ASConstCab cab1, const char *keyName1, ASConstCab cab2, const char *keyName2);
cab1 | IN/OUT The first cabinet.
|
keyName1 | IN/OUT The key name.
|
cab2 | IN/OUT The second cabinet.
|
keyName2 | IN/OUT The key name.
|
theCab out to a stream. The caller retains ownership of the cabinet. The stream will not be closed or flushed. void ASCabWriteToStream(ASConstCab theCab, ASStm theStm);
theCab | IN/OUT The cabinet.
|
theStm | IN/OUT Must be a stream opened through ASFileStmWrOpen() or ASProcStmWrOpen().
|
Enumerates all the keys in the constant cabinet.
Keys consisting solely of digits are enumerated first, in numeric order (assuming they are not padded with zeros at the front, which will confuse matters). Non-numeric keys are then enumerated in strcmp order.
The callback procedure must not add, delete, or modify items in theCab during the enumeration.
It will RERAISE any exceptions thrown by enumProc.
void ASConstCabEnum(ASConstCab theCab, ASConstCabEnumProc enumProc, void *clientData);
theCab | The cabinet.
|
enumProc | User-supplied callback that is called for each entry found in
theCab. This callback cannot modify the ASConstCab object. |
clientData | A pointer to user-supplied data to pass to
enumProc each time it is called. |