
#include "bitstream.h"

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void)
{
    // fill a file with 0 through 123 bytes of stuff
    // each time open it up and test its contents
    // with readings that range from 1 through 32 bits
    srandom( time(NULL) );
    printf( "begin.\n" );
  
    int fsize;
    for (fsize=0; fsize<123; fsize++) {
        // fill the file with the set number of bytes
        FILE *fi = fopen( "tmpfile", "w" );
        int i;
        for (i=0; i<fsize; i++) {
            long rand = random();
            fwrite( &rand, 1, 1, fi );
        }
        fclose( fi );
        printf( "done writing file of size %3d\n", fsize );

        // read back from file, filling contents into buf1
        fi = fopen( "tmpfile", "r" );
        char buf1[8*fsize+1];
        for (i=0; i<fsize; i++) {
            uint8_t tmp;
            fread( &tmp, 1, 1, fi );
            int j;
            printf( "got %3d/%3d from file %02x\n", i, fsize, tmp );
            for (j=0; j<8; j++) {
                int x = (tmp << j) & 0x80;
                buf1[i*8+j] = x ? '1' : '0';
                printf( "store buf1[%4d] = %c\n", (i*8+j), (x ? '1':'0') );
            }
        }
        fclose( fi );
        printf( "done reading file of size %3d into buf1\n", fsize );

        // read back from file using bitstream, and compare
        // also tests showbits
        int rsize;
        char buf2[8*fsize+1];
        for (rsize = 1; rsize<=32; rsize++) {
            printf( "testing stride %2d\n", rsize );
            int pos = 0;
            bitstream_t *bs = bs_open( "tmpfile" );
            uint32_t result, sresult;
            while ( 1 ) {
                uint8_t snum = bs_showbits( bs, rsize, &sresult );
                uint8_t num = bs_getbits( bs, rsize, &result );

                if ( snum != num || sresult != result ) {
                    printf( "showbits failed to be same as getbits\n" );
                    printf( "showbits: " );
                    bs_printbits( snum );
                    printf( "\n" );
                    printf( "getbits : " );
                    bs_printbits( num );
                    printf( "\n" );
                    exit(1);
                }

                printf( "got %2d bits from file ", num);
                bs_printbits( result );
                printf( "\n" );
                int i;
                for (i=0; i<num; ++i ) {
                    int x = (result << i) & (0x1 << num-1);
                    buf2[pos+i] = x ? '1' : '0';
                }
                pos += num;
                if ( num < rsize )
                    break;
            }

            bs_close( bs );

            // do the comparison
            int res = strncmp( buf1, buf2, fsize*8 );
            printf( "comparison of fsize %3d at stride %2d : %d\n", fsize, rsize, res );
            if ( 0 != res ) {
                printf( "buf1 = " );
                int i;
                for (i=0; i<fsize*8; i++)
                    printf( "%c", buf1[i]);
                printf( "\n" );
                printf( "buf2 = " );
                for (i=0; i<fsize*8; i++)
                    printf( "%c", buf2[i]);
                printf( "\n\n");
                exit(1);
            }
        }
        
        // test random size readings, 20 times
        char buf3[8*fsize+1];
        int j;
        for (j=0; j<20; j++) {
            int pos = 0;
            bitstream_t *bs = bs_open( "tmpfile" );

            while( 1 ) {
                uint32_t result, sresult;
                uint32_t rsize = random() % 8 + 1;
                uint8_t snum = bs_showbits( bs, rsize, &sresult );
                uint8_t num = bs_getbits( bs, rsize, &result );

                if ( snum != num || sresult != result ) {
                    printf( "showbits failed to be same as getbits\n" );
                    printf( "showbits: " );
                    bs_printbits( snum );
                    printf( "\n" );
                    printf( "getbits : " );
                    bs_printbits( num );
                    printf( "\n" );
                    exit(1);
                }

                printf( "got %2d bits from file ", num);
                bs_printbits( result );
                printf( "\n" );
                int i;
                for (i=0; i<num; ++i ) {
                    int x = (result << i) & (0x1 << num-1);
                    buf3[pos+i] = x ? '1' : '0';
                }
                pos += num;
                if ( num < rsize )
                    break;
            }
            bs_close( bs );


            // do the comparison
            int res = strncmp( buf1, buf3, fsize*8 );
            printf( "comparison of fsize %3d for random (%2d/20) readings : %d\n", fsize, j+1, res );
            if ( 0 != res ) {
                printf( "buf1 = " );
                int i;
                for (i=0; i<fsize*8; i++)
                    printf( "%c", buf1[i]);
                printf( "\n" );
                printf( "buf3 = " );
                for (i=0; i<fsize*8; i++)
                    printf( "%c", buf2[i]);
                printf( "\n\n");
                exit(1);
            }
        }
    }

    unlink("tmpfile");
}
                




        
