Figure 2: Implementation of class CReport

CReport::CReport(void _vTitlePrint(ostream &, void *, int), 
    int _iTitleLines, void _vFooterPrint(ostream &, void *, int),
    int _iFooterLines, ostream *_RepStream, int _iLinesPerPage)
{
    vTitlePrint = _vTitlePrint;
    vFooterPrint =_vFooterPrint;
    iTitleLines = _iTitleLines;
    iFooterLines = _iFooterLines;
    iLinesPerPage = _iLinesPerPage;
    iLinesLeft = _iLinesPerPage;
    RepStream = _RepStream;
    iPageCount = -1;
}

void CReport::vPrintLine(void _vLinePrint(ostream &, void *),
    int _iLines, void *_vTitleData, void *_vData, 
    void *_vFooterData)
{
    vTitleData = _vTitleData;
    vFooterData = _vFooterData;

    // If this is the top of the page, print the title
    if (iPageCount == -1)
    {
        iPageCount = 1;
        vTitlePrint(*RepStream, vTitleData, iPageCount);
        iLinesLeft -= iTitleLines;
    }

    // If there is not space for the needed lines and the
    // footer, go to the next page
    if (iLinesLeft - _iLines <= iFooterLines)
    {
        // Make sure the footer is at the bottom of the page
        if ((iLinesLeft - iFooterLines - 1) > 0) 
            vPrintBlankLines(iLinesLeft - iFooterLines - 1);
        if (iLinesLeft > 0)
            vFooterPrint(*RepStream, vFooterData, iPageCount);
        *RepStream  << flush;
        iPageCount++;
        // Print the title
        vTitlePrint(*RepStream, vTitleData, iPageCount);
        iLinesLeft = iLinesPerPage - iTitleLines;
    }

    // Print the data
    _vLinePrint(*RepStream, _vData);
    iLinesLeft -= _iLines;
}

void CReport::vNewPage()
{
    vPrintBlankLines(iLinesLeft);
    iPageCount++;
    vTitlePrint(*RepStream, vTitleData, iPageCount);
    iLinesLeft = iLinesPerPage - iTitleLines;
}

// not shown: vPrintBlankLines(int _iLines) and
// vPrintFooter()
// ...

void CReport::vPrintFooter(void *_vTitleData, void *_vFooterData)
{
  char form_feed[2];
  int empty = 0;

  form_feed[0] = 12;
  form_feed[1] = 0;

  if (iLinesPerPage == iLinesLeft)
  {
     empty = 1;
     iPageCount = 1;
     vTitlePrint(*RepStream, _vTitleData, iPageCount);
     iLinesLeft -= iTitleLines;

     *RepStream << endl << endl << endl 
                << "   NO DATA AVAILABLE" << endl;
     iLinesLeft -= 4;
  }
  // Make sure the footer is at the bootom of the page
  if (iLinesLeft <= iFooterLines)
     *RepStream << flush;
  else if ((iLinesLeft - iFooterLines -1) > 0)
    vPrintBlankLines(iLinesLeft - iFooterLines);

  vFooterPrint(*RepStream, _vFooterData, iPageCount);
  iLinesLeft = 0;
}