Listing 2 Implementation of class filefilter

#include "ffilter.hpp"

int FileFilter::count = 0;

FileFilter::FileFilter( const char *file2read,
                    const char *file2write,
                    data_block* (*filter_func)
                           ( data_block *inblock ) )
{
  long file_size;

    filter = filter_func;

    if( !file2read | | !file2write | | !filter )
       filter_valid = 0;
    else {
       rfile = fopen( file2read, "rb" );
       wfile = fopen( file2write, "wb" );
       if( rfile && wfile && create_sem() && create_queue() ) {
          fseek( rfile, 0L, SEEK_END );
          file_size = ftell( rfile );
          fseek( rfile, 0L, SEEK_SET );
          blocks2read = file_size/INBUF_SIZE;
          if( file_size % INBUF_SIZE )
             ++blocks2read;
          blocks2write = blocks2read;
          filter_valid = 1;
          _beginthread( read_thread, 4096, (void *)this );
          _beginthread( write_thread, 4096, (void *)this );
       }
       else
             filter_valid = 0;
    }
}

FileFilter::~FileFilter()
{
    if( rfile )
       fclose( rfile );

    if( wfile )
       fclose( wfile );

    rfile = wfile = 0;
    filter_valid = 0;
}

void read_thread( void *filterptr )
{
    data_block *db, *db2;
    FileFilter *ff = (FileFilter *)filterptr;

    while( ff->blocks2read---- ) {

       db = new data_block;
       db->block = new char[ INBUF_SIZE ];
       db->data_size = fread( db->block, 1, INBUF_SIZE, ff->rfile );
       if( db->data_size ) {
           db2 = ff->filter( db );
             delete db->block;
             delete db;
             db = db2;
             if( !ff->put_queue( db )) {
                printf("\nCould not Put to Data Queue!\n");
                exit( 1 );
             }
       }
    }
}

void write_thread( void *filterptr )
{
    data_block *db;
    FileFilter *ff = (FileFilter *)filterptr;
    int n, s;
    APIRET rc;

    while( ff->blocks2write-- ) {
       if( !( db = ff->get_queue()) ) {
          printf("\n\tBIG Error! : Queue is EMPTY!\N");
          exit( 1 );
       }

       s = db->data_size;
       n = fwrite( db->block, 1, s, ff->wfile );
       delete db->block;
       delete db;
       if( n != s ) {
          printf("\n\tWrite Block Write Error : Terminating!\n");
          exit( 1 );
       }
    }
    rc = DosPostEventSem( ff->done_sem );
    ff->filter_error = (ULONG)rc;
}

int FileFilter::create_queue()
{
    APIRET rc;
    char n[ 16 ];

    strcpy( qname, "\\QUEUES\\Q");
    sprintf( n, "%ld", count );
    strcat( qname, n );

    rc = DosCreateQueue( &qhandle, QUE_FIFO |
                     QUE_CONVERT_ADDRESS, qname );

    if( !rc ) ++count;
    return !rc;
}
int FileFilter::put_queue( data_block *data )
{
  ULONG  Request = 0;
  ULONG  DataLength;
  PVOID  DataBuffer;
  ULONG  ElemPriority = 0;
  APIRET rc;                    // OS/2 QUEUE API stuff

  data_block *d;        // data structure from ffilter.hpp

    if( !data )
       return 0;

    DataLength = data->data_size;
    DataBuffer = data->block;

    rc = DosWriteQueue(qhandle, Request, DataLength,
             DataBuffer, ElemPriority);

    delete data;
    return ( rc ) ? 0 : 1;
}

data_block* FileFilter::get_queue()
{
  REQUESTDATA   Request;        // OS/2 QUEUE API stuff
  ULONG         DataLength;
  PVOID         DataAddress;
  ULONG         ElementCode = 0;
  BOOL32        NoWait = 0;
  BYTE          ElemPriority = 0;
  HEV           SemHandle = 0;
  APIRET        rc;

  data_block *data = 0; // data structure from ffilter.hpp

    rc = DosReadQueue(qhandle, &Request, &DataLength, &DataAddress,
             ElementCode, NoWait, &ElemPriority, SemHandle);

    if( rc )
       return 0;

    data = new data_block;
    if( data ) {

       data->data_size = DataLength;
       data->block = (char *)DataAddress;
    }

    return data;
}

int FileFilter::create_sem()
{
  ULONG attr = 0;
  BOOL32 state = 0;
  APIRET rc;

    max_sem_wait = 60000UL;
    rc = DosCreateEventSem( 0, &done_sem, attr, state );
    return ( rc ) ? 0 : 1;
}

APIRET FileFilter::wait4completion( ULONG max_wait )
{
    return DosWaitEventSem( done_sem, max_wait );
}

// End of File