/* * Writer.h * Author: Hannah C. Tang (hctang@cs) * * Specification of public functions for Writer struct * (the code gen module) * * $Id: Writer.c,v 1.3 2001/12/19 06:56:42 cse466_t Exp $ * */ #include #include #include "Writer.h" #include "common.h" /* * PRIVATE: * * Writer struct, various constants, method for resizing internal array */ struct Writer { struct Sequence *pBuffer; Bool writingModeSequences; Bool writingProgSequences; size_t bufferSize; size_t bufferCapacity; unsigned int numSequences; }; static const int INITIAL_NUM_SEQ = 16; static void Writer_resizeBuffer( struct Writer *pW ); struct Writer* Writer_malloc( void ) { struct Writer *pW = ( struct Writer* ) malloc( sizeof( struct Writer ) ); if( pW == NULL ) { fprintf( stderr, "Out of memory allocating a Writer!\n" ); exit( 0 ); } pW->pBuffer = ( struct Sequence* ) malloc( sizeof( struct Sequence ) * INITIAL_NUM_SEQ ); pW->writingModeSequences = Bool_false; pW->writingProgSequences = Bool_false; pW->bufferSize = 0; pW->bufferCapacity = INITIAL_NUM_SEQ * sizeof( struct Sequence ); pW->numSequences = 0; return pW; } void Writer_free( struct Writer *pW ) { if( pW != NULL ) { if( pW->pBuffer != NULL ) { free( pW->pBuffer ); } free( pW ); } } Bool Writer_appendSequence( struct Writer *pW, const struct Sequence *pS ) { unsigned int destAddr; if( pW->writingModeSequences ) { fprintf( stderr, "Warning: writing program sequence in buffer" " which already contains mode sequences\n" ); pW->writingModeSequences = Bool_false; } pW->writingProgSequences = Bool_true; /* Resize the buffer if necessary */ while( pW->bufferSize >= pW->bufferCapacity ) { Writer_resizeBuffer( pW ); } destAddr = ( unsigned int )pW->pBuffer + ( unsigned int )pW->bufferSize; /* Copy the sequence to the end of the writer's current buffer */ memcpy( ( void* )destAddr, pS, sizeof( struct Sequence ) ); pW->bufferSize += sizeof( struct Sequence ); pW->numSequences++; return Bool_true; } Bool Writer_appendSequencesBetween( struct Writer *pW, unsigned int start, unsigned int end, unsigned int numTimes ) { int i = 0; struct Sequence *pCopyFrom; unsigned int numSequences = end - start + 1; unsigned int destAddr; size_t sizeof_copyFrom = sizeof( struct Sequence ) * numSequences; if( pW->writingModeSequences ) { fprintf( stderr, "Warning: writing program sequence in buffer" " which already contains mode sequences\n" ); pW->writingModeSequences = Bool_false; } pW->writingProgSequences = Bool_true; /* Bounds checking */ if( start < 0 || end < start || start * sizeof( struct Sequence ) > pW->bufferSize || end * sizeof( struct Sequence ) > pW->bufferSize ) { /* 'start' or 'end' is past the valid part of buffer */ fprintf( stderr, "Starting Sequence %d or ending Sequence %d" " out of bounds, exiting.\n", start, end ); exit( 0 ); } /* Resize the buffer as many times as is necessary */ while( ( numSequences * numTimes * sizeof( struct Sequence ) + pW->bufferSize ) >= pW->bufferCapacity ) { Writer_resizeBuffer( pW ); } pCopyFrom = pW->pBuffer + start; /* Copy the specified sequences numTimes */ for( ; i < numTimes; i++ ) { /* Copy the specified sequences */ destAddr = ( unsigned int )pW->pBuffer + ( unsigned int )pW->bufferSize; memcpy( ( void* )destAddr, pCopyFrom, sizeof_copyFrom ); pW->bufferSize += numSequences * sizeof( struct Sequence ); } pW->numSequences += numSequences * numTimes; return Bool_true; } Bool Writer_appendModeSequence( struct Writer *pW, unsigned int modeSequence ) { unsigned int destAddr; if( pW->writingProgSequences ) { fprintf( stderr, "Warning: writing mode sequence in buffer" " which already contains program sequences\n" ); pW->writingProgSequences = Bool_false; } pW->writingModeSequences = Bool_true; /* Resize the buffer if necessary */ while( pW->bufferSize >= pW->bufferCapacity ) { Writer_resizeBuffer( pW ); } destAddr = ( unsigned int )pW->pBuffer + ( unsigned int )pW->bufferSize; /* Copy the sequence to the end of the writer's current buffer */ memcpy( ( void* )destAddr, &modeSequence, sizeof( unsigned int ) ); pW->bufferSize += sizeof( unsigned int ); pW->numSequences++; return Bool_true; } /* Clear the Writer's current buffer */ void Writer_clearBuffer( struct Writer *pW ) { pW->writingModeSequences = Bool_false; pW->writingProgSequences = Bool_false; pW->bufferSize = 0; pW->numSequences = 0; } unsigned int Writer_getNumSequences( const struct Writer *pW ) { return pW->numSequences; } size_t Writer_getBufferSize( const struct Writer *pW ) { return pW->bufferSize; } struct Sequence* Writer_getBuffer( struct Writer* pW, size_t *bufferSize ) { *bufferSize = Writer_getBufferSize( pW ); return pW->pBuffer; } static void Writer_resizeBuffer( struct Writer *pW ) { /* Double the capacity of the current buffer */ unsigned int origCapacity = pW->bufferCapacity; unsigned int newCapacity = origCapacity * 2; pW->pBuffer = realloc( pW->pBuffer, newCapacity ); pW->bufferCapacity = newCapacity; }