Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Combines two files with byte boundaries.
- License: MIT.
- */
- #include <limits.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- size_t copyfilev( FILE *outf, FILE *inf, unsigned char *bufo, const size_t bufs )
- {
- size_t actr = 0, actw = 0, totr = 0;
- do
- {
- actr = fread( bufo, 1, bufs, inf );
- actw = fwrite( bufo, 1, actr, outf );
- actr &= actw;
- totr += actr;
- } while ( actr == bufs );
- return(totr);
- }
- int combin( FILE *arqo, FILE *arqi[2], unsigned char *bufm, const size_t readf[2], const size_t readl, const size_t bufs )
- {
- int reti = 0;
- size_t bufr = bufs, buftr = 0, memloop = 1, mempos = 0, teste = 0, ui = 0;
- unsigned char uci = 0;
- /* Cap the buffer. */
- memloop = bufs / readl;
- bufr = memloop * readl;
- for ( buftr = bufr; buftr == bufr; )
- {
- buftr = 0;
- /* Fill buffer. */
- for ( mempos = 0, ui = 0; ui < memloop; ui++ )
- {
- for ( uci = 0; uci < 2; uci++ )
- {
- teste = fread( &bufm[mempos], 1, readf[uci], arqi[uci] );
- buftr += teste;
- if ( teste != readf[uci] )
- {
- /* Check for bad combination. */
- if ( teste > 0 )
- {
- reti = 1;
- }
- break;
- }
- mempos += teste;
- }
- if ( uci != 2 )
- {
- break;
- }
- }
- teste = fwrite( bufm, 1, buftr, arqo );
- // buftr &= teste;
- if ( teste != buftr )
- {
- reti = 1;
- break;
- }
- }
- #ifdef __DEBUG__
- printf( "Bufr: %lu\nBuftr: %lu\nMemloop: %lu\nMempos: %lu\nTeste loop 1: %lu\nUci: %u\n", bufr, buftr, memloop, mempos, teste, uci );
- #endif
- uci ^= 1;
- teste = copyfilev( arqo, arqi[uci], bufm, bufs );
- /* Check for bad combination, take two. */
- if ( teste > 0 )
- {
- reti = 1;
- }
- #ifdef __DEBUG__
- printf( "Final teste: %lu\n", teste );
- #endif
- return(reti);
- }
- int main( int argc, char **argv )
- {
- FILE *arqi[2] = { 0, 0 };
- FILE *arqo = 0;
- char *errc = '\0', *file1n = '\0', *file2n = '\0', *fileon = '\0';
- int i = 0;
- size_t readf[2] = { 524288, 524288 };
- size_t bufs = 1048576, readl = 1048576, teste = 0;
- unsigned char *bufm = 0;
- unsigned char uci = 0;
- for ( ; i != -1; )
- {
- i = getopt( argc, argv, "1:2:ho:r:" );
- switch ( i )
- {
- /* Detects overflow before it is too late. */
- case '1':
- readf[0] = strtoul( optarg, &errc, 10 );
- teste = ULONG_MAX - readf[0];
- if ( ( errc[0] != '\0' ) || ( teste < readf[1] ) )
- {
- fprintf( stderr, "Invalid value combination.\n" );
- return(1);
- }
- break;
- case '2':
- readf[1] = strtoul( optarg, &errc, 10 );
- teste = ULONG_MAX - readf[1];
- if ( ( errc[0] != '\0' ) || ( teste < readf[0] ) )
- {
- fprintf( stderr, "Invalid value combination.\n" );
- return(1);
- }
- break;
- case 'h':
- printf( "%s -1 input1_reads -2 input2_reads -r reading_size -o output -- file1 file2 [output]\n", argv[0] );
- return(0);
- case 'o':
- fileon = optarg;
- break;
- case 'r':
- bufs = strtoul( optarg, &errc, 10 );
- if ( errc[0] != '\0' )
- {
- fprintf( stderr, "Wrong reading buffer value!\n" );
- return(1);
- }
- break;
- case '?':
- if ( file1n == 0 )
- {
- file1n = argv[optind - 1];
- }
- else if ( file2n == 0 )
- {
- file2n = argv[optind - 1];
- }
- else if ( fileon == 0 )
- {
- fileon = argv[optind - 1];
- }
- else
- {
- fprintf( stderr, "Unknown option \"%c\".\n", optopt );
- return(1);
- }
- break;
- default:
- i = -1;
- break;
- }
- }
- for ( i = optind; i < argc; i++ )
- {
- if ( file1n == 0 )
- {
- file1n = argv[i];
- }
- else if ( file2n == 0 )
- {
- file2n = argv[i];
- }
- else if ( fileon == 0 )
- {
- fileon = argv[i];
- }
- else
- {
- break;
- }
- }
- readl = readf[0] + readf[1];
- if ( bufs < readl )
- {
- fprintf( stderr, "Reading buffer size must hold at least one reading from each file!\n" );
- return(1);
- }
- arqi[0] = fopen( file1n, "rb" );
- if ( arqi[0] == 0 )
- {
- fprintf( stderr, "Couldn't open \"%s\"!\n", file1n );
- return(1);
- }
- arqi[1] = fopen( file2n, "rb" );
- if ( arqi[1] == 0 )
- {
- fprintf( stderr, "Couldn't open \"%s\"!\n", file2n );
- return(1);
- }
- if ( fileon != 0 )
- {
- arqo = fopen( fileon, "wb" );
- if ( arqo == 0 )
- {
- fprintf( stderr, "Couldn't open \"%s\"!\n", fileon );
- return(1);
- }
- }
- else
- {
- arqo = stdout;
- }
- bufm = (unsigned char *)malloc( sizeof(unsigned char) * bufs );
- if ( bufm == 0 )
- {
- fprintf( stderr, "Not enough memory for reading buffer!\n" );
- return(2);
- }
- /**/
- i = combin( arqo, arqi, bufm, readf, readl, bufs ) * 3;
- free(bufm);
- for ( uci = 0; uci < 2; uci++ )
- {
- fclose(arqi[uci]);
- }
- if ( fileon != 0 )
- {
- fclose(arqo);
- }
- return(i);
- }
Add Comment
Please, Sign In to add comment