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 theFlattenCollectionfunction for converting the information in a collection object into a flattened stream of bytes. With theFlattenCollectionfunction, 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
FlattenCollectionfunction 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
FlattenCollectionfunction, 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
longvalue 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
theDataparameter 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 aTFlattenBlockstructure. (The sample code in Listing 5-20 passes a pointer to this structure as the reference constant when calling theFlattenCollectionfunction, 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 theFlattenCollectionfunction to flatten a collection into a block of memory referenced by a Macintosh Memory Manager handle.Listing 5-20 The
FlattenCollectionToHdlfunction
/* 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 aTFlattenBlockstructure, initializes thepositionfield to 0, and initializes thedataHandlefield to a newly allocated Macintosh Memory Manager handle. The function then calls theFlattenCollectionfunction, specifying the collection to flatten, the callback function specified in Listing 5-19, and a pointer to theTFlattenBlockstructure. 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 theTFlattenBlockstructure 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
UnflattenCollectionfunction to convert a flattened collection from a Macintosh Memory Manager handle into a collection object.Listing 5-21 A possible implementation of the
UnflattenCollectionFromHdlfunction
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 theUnflattenCollectionFromHdlfunction. The Collection Manager provides both theFlattenCollectionToHdlandUnflattenCollectionFromHdlfunctions 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.