Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Environment and Utilities /
Chapter 5 - Collection Manager / Using the Collection Manager


Flattening and Unflattening a Collection

The Collection Manager provides the FlattenCollection function for converting the information in a collection object into a flattened stream of bytes. With the FlattenCollection 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 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 a TFlattenBlock structure. (The sample code in Listing 5-20 passes a pointer to this structure as the reference constant when calling the FlattenCollection 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 the FlattenCollection 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 a TFlattenBlock structure, initializes the position field to 0, and initializes the dataHandle field to a newly allocated Macintosh Memory Manager handle. The function then calls the FlattenCollection function, specifying the collection to flatten, the callback function specified in Listing 5-19, and a pointer to the TFlattenBlock 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 the TFlattenBlock 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 the UnflattenCollectionFromHdl function. The Collection Manager provides both the FlattenCollectionToHdl and UnflattenCollectionFromHdl 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.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996