Important: The information in this document is obsolete and should not be used for new development.
Flattening and Unflattening a Collection
The Collection Manager provides theFlattenCollection
function for converting the information in a collection object into a flattened stream of bytes. With theFlattenCollection
function, you provide a callback function that operates on the stream of bytes--you can use this callback function to write the stream out to disk, store the stream in a Macintosh Memory Manager handle, and so on.The
FlattenCollection
function takes three parameters:
When you call the
- a reference to the collection to flatten
- a pointer to the callback function that you provide to handle the returned stream of bytes
- a 32-bit reference constant that the Collection Manager passes back to your callback function
FlattenCollection
function, the Collection Manager begins converting the collection into a stream of bytes. It repeatedly calls your callback function, each time sending it more of the flattened collection, until it has converted the entire collection.Your callback function determines what happens to the flattened collection. This function must take three parameters: a
long
value that represents the size of the current block of data, a pointer to the current block of data, and a reference constant that you can use as a pointer to other information.Listing 5-19 shows an example callback function. This function appends the block of data provided by the Collection Manager in the
theData
parameter to the end of a block of data referenced by a Macintosh Memory Manager handle. The handle and the current size of the block of data referenced by the handle are stored in aTFlattenBlock
structure. (The sample code in Listing 5-20 passes a pointer to this structure as the reference constant when calling theFlattenCollection
function, which passes the pointer back to your callback function.)Listing 5-19 Flattening procedure
typedef struct { long position; Handle dataHandle; } TFlattenBlock; OSErr FlattenProc(long theSize, Ptr theData, TFlattenBlock *flattenBlock) { register OSErr anErr = noErr; SetHandleSize(flattenBlock->dataHandle, flattenBlock->position + theSize); anErr = MemError(); if (anErr == noErr) { BlockMove(data, *flattenBlock->dataHandle + flattenBlock->position, theSize); flattenBlock->position += theSize; } } return anErr; }Listing 5-20 shows how you can use this callback function. The sample function in Listing 5-20 uses theFlattenCollection
function to flatten a collection into a block of memory referenced by a Macintosh Memory Manager handle.Listing 5-20 The
FlattenCollectionToHdl
function
/* possible implementation of FlattenCollectionToHdl */ OSErr FlattenCollectionToHdl(Collection anyCollection, Handle flattenedCollection) { register OSErr anErr; TFlattenBlock flattenBlock; flattenBlock.position = 0; flattenBlock.dataHandle = flattenedCollection; if (!(anErr = MemError())) { anErr = FlattenCollection(anyCollection, FlattenProc, &flattenBlock); if (anErr) flattenBlock.dataHandle = nil; } return anErr; }This function creates aTFlattenBlock
structure, initializes theposition
field to 0, and initializes thedataHandle
field to a newly allocated Macintosh Memory Manager handle. The function then calls theFlattenCollection
function, specifying the collection to flatten, the callback function specified in Listing 5-19, and a pointer to theTFlattenBlock
structure. In response, the Collection Manager flattens the specified collection one piece at a time, repeatedly calling the callback function with new blocks of the flattened collection. The Collection Manager provides a pointer to theTFlattenBlock
structure when calling the callback function. The callback function uses this information to copy each new block of flattened collection data onto the end of the Macintosh Memory Manager handle.Listing 5-21 shows the reverse process--using the
UnflattenCollection
function to convert a flattened collection from a Macintosh Memory Manager handle into a collection object.Listing 5-21 A possible implementation of the
UnflattenCollectionFromHdl
function
void UnflattenProc(long theSize, Ptr theData, TFlattenBlock *flattenBlock) { BlockMove(*flattenBlock->dataHandle + flattenBlock->position, theData, theSize) flattenBlock->position += theSize; } OSErr UnflattenCollectionFromHdl(Collection anyCollection, Handle flattenedCollection) { register OSErr anErr; TFlattenBlock flattenBlock; flattenBlock.position = 0; flattenBlock.dataHandle = flattenedCollection; anErr = UnflattenCollection(anyCollection, UnflattenProc, &flattenBlock); return anErr; }Listing 5-21 shows a possible implementation of theUnflattenCollectionFromHdl
function. The Collection Manager provides both theFlattenCollectionToHdl
andUnflattenCollectionFromHdl
functions for you--you do not have to define these yourself. For more information about the flattening and unflattening functions, see "Flattening and Unflattening a Collection" beginning on page 5-88.