#define _POSIX_C_SOURCE 200809L /* Podprogram ‹count_distinct› spočítá počet různých bajtů * na vstupu (zadaném popisovačem ‹fd›). Tento počet v případě * úspěchu vrátí, jinak vrátí hodnotu -1. */ int count_distinct( int fd ); /* ┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄┄┄┄ následují testy ┄┄┄┄┄┄┄┄┄┄ %< ┄┄┄┄┄┄┄ */ #include /* assert */ #include /* NONPOSIX: err */ #include /* errno */ #include /* open */ #include /* write, read, close, unlink */ static void close_or_warn( int fd, const char *name ) { if ( close( fd ) == -1 ) warn( "closing %s", name ); } static void unlink_if_exists( const char *name ) { if ( unlink( name ) == -1 && errno != ENOENT ) err( 2, "unlinking '%s'", name ); } static void mk_tmp( const char *name, const char *str, int len ) { unlink_if_exists( name ); int fd = open( name, O_CREAT | O_TRUNC | O_WRONLY, 0666 ); if ( fd == -1 ) err( 2, "creating %s", name ); if ( write( fd, str, len ) == -1 ) err( 2, "writing %s", name ); close_or_warn( fd, name ); } static int open_or_die( const char *name ) { int fd = open( name, O_RDONLY ); if ( fd == -1 ) err( 2, "opening %s", name ); return fd; } int mk_tmp_and_open_or_die( const char *str, int len ) { const char *name = "./zt.r2_test_in"; mk_tmp( name, str, len ); return open_or_die( name ); } int main( void ) { int fd; const char *tmp_file = "./zt.r2_test_in"; fd = mk_tmp_and_open_or_die( "ahoj", 4 ); assert( count_distinct( fd ) == 4 ); close_or_warn( fd, tmp_file ); fd = mk_tmp_and_open_or_die( "hello world", 11 ); assert( count_distinct( fd ) == 8 ); close_or_warn( fd, tmp_file ); fd = mk_tmp_and_open_or_die( "\xff\x1\x2\x3\xfe\x4\x1\xff\xfe", 9 ); assert( count_distinct( fd ) == 6 ); close_or_warn( fd, tmp_file ); unsigned char data[] = { 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xbf, 0xfb, 0x10, 0x01, 0xab, 0xba, 0xcd, 0xdc, 0xee }; fd = mk_tmp_and_open_or_die( ( char * ) data, sizeof( data ) ); assert( count_distinct( fd ) == 9 ); close_or_warn( fd, tmp_file ); unlink_if_exists( tmp_file ); return 0; }