Important: The information in this document is obsolete and should not be used for new development.
Recipes--Streams
The recipe and sample code in this section demonstrate how to use a handle stream.Recipe--Using a Handle Stream to Write Text to a Handle
The Calc sample application implements a spreadsheet view with rows and columns of cells. Calc supports publish and subscribe, and a user can select a group of cells and publish the data they contain. When a user publishes cell data, the Calc document object calls a method of the spreadsheet view (TCellsView::DesignatorAsTEXT
) to write the text from the designated cells to a handle.The
DesignatorAsTEXT
method provides a good example of using a stream to write data to a handle. The calling method passes a designator that identifies a group of one or more cells. TheDesignatorAsTEXT
method extracts text from the cells, uses a handle stream to write the text to a handle, and returns the handle. The calling method can use the handle (and its stored text) as required, but must be sure to free the handle when it has finished with it.To use a handle stream to write text data to a handle, you perform these steps:
The sample code shown in this recipe is from the Calc application.
- Create a handle.
- Create a handle stream and initialize it with the handle you created.
- Call methods of the stream to write your text data to the stream.
- Free the handle stream.
Create a Handle
Creating a handle is a standard Macintosh operation. TheDesignatorAsTEXT
method creates a handle with an arbitrary initial size of 100. A handle stream will increase the size of its handle as necessary.
Handle textHandle; textHandle = NewPermHandle(100);Create and Initialize a Handle Stream
When you initialize a handle stream, you pass it two items: a reference to a handle and a value that indicates the size by which the handle should be grown. When more space is needed, the handle stream will increase its handle size by the amount needed or by the specified growth size, whichever is larger.
THandleStream * aHandleStream; aHandleStream = new THandleStream; aHandleStream->IHandleStream(textHandle, 10);Write Text Data to the Handle Stream
TheDesignatorAsTEXT
method performs some additional operations to determine which cells should be examined and to set up an iterator to iterate over those cells. It then executes a loop to write the text from each cell to the handle stream. The complete code forDesignatorAsTEXT
is shown on the following page.
Handle TCellsView::DesignatorAsTEXT(TDesignator* aDesignator) { CRect bounds; Handle textHandle; THandleStream * aHandleStream; CStr255 theString; RgnHandle aRgn; textHandle = NewPermHandle(100); aHandleStream = new THandleStream; aHandleStream->IHandleStream(textHandle, 10); aRgn = ((TRegionDesignator *)(aDesignator))->fDesignation; bounds = (*aRgn)->rgnBBox; bounds.bottom--; bounds.right--; CCellIterator iter(this, bounds[topLeft], bounds[botRight], kIterateForward, kIterateForward, CCellIterator::kIterateRowMajor); for (GridCell aCell = iter.FirstCell(); iter.More(); aCell = iter.NextCell()) { SignedByte aChar; // Write out the cell's contents if the cell is included and it exists. if (PtInRgn(aCell, aRgn) && fCalcDocument->CellExists(aCell.v, aCell.h)) { fCalcDocument->GetCell(aCell.v, aCell.h)->GetValueAsString(theString); // Use WriteBytes instead of WriteString to avoid writing length byte. aHandleStream->WriteBytes(&theString[1], theString.Length()); } // Write out the delimiter: tab or carriage return. if (aCell.h == bounds.right) aChar = 0x0D; else aChar = 0x09; aHandleStream->WriteBytes(&aChar, sizeof(SignedByte)); } aHandleStream->Free(); return textHandle; } // TCellsView::DesignatorAsTEXT\Free the Handle Stream
TheDesignatorAsTEXT
method frees the handle stream, which frees the stream object itself but not its handle, then returns the handle.
aHandleStream->Free(); return textHandle;The calling routine is responsible for freeing the handle when it has finished with it.Using the Handle Data
Once you have written data to a handle, you can use the handle just as you would any other handle variable. For example, you can use a file stream to write the handle to a document; you can also use a file stream to read the handle back from the document.The Calc application uses this approach to read and write cell data. For writing, it writes cell data to a handle (with the
DesignatorAsTEXT
method shown above), then uses a file stream to write the data to a document. For reading the data, it uses theDoReadTEXT
method to read the handle from a file stream and then extract the data from the handle.