void test_verybasic() { qio_file_t *f = NULL; qio_channel_t *writing = NULL; qio_channel_t *reading = NULL; err_t err; char buf[4] = {0}; //open the tmp file, create a write channel, write our data, and release the channel err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_amt(true, writing, "\xDE\xAD\xBE\xEF", 4); assert(!err); qio_channel_release(writing); //open a read channel to the tmp file, and read back the data. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_read_amt(true, reading, buf, 4); assert(!err); qio_channel_release(reading); ///check that what we wrote is what we read back if(memcmp(buf, "\xDE\xAD\xBE\xEF", 4) != 0){ assert(0);} //close the file qio_file_release(f); f = NULL; printf("PASS: test_verybasic\n"); }
void write_65k_test() { const char *out = NULL; char *p = NULL; err_t err; qio_file_t *f = NULL; qio_channel_t *reading = NULL; qio_channel_t *writing = NULL; qio_style_t style = qio_style_default(); int buflen = 65535; ssize_t out_len = 0; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); style.binary = 1; style.byteorder = QIO_BIG; style.str_style = -2; err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, &style); assert(!err); p = (char *)calloc(1, buflen); if(!p){ assert(0); } memset(p, 'A', buflen); err = qio_channel_write_string(true, style.byteorder, style.str_style, writing, p, buflen); assert(!err); qio_channel_release(writing); assert(!err); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); while(1){ err = qio_channel_read_string(true, style.byteorder, style.str_style, reading, &out, &out_len, -1); if(out){ if(memcmp(out, p, buflen)!=0){ assert(0); } free((void*) out); out=NULL; } if(err>0){ break; } } qio_channel_release(reading); printf("PASS: wrote 65k to file, read it back ok.\n"); qio_file_release(f); f = NULL; free(p); }
void do_test_utf8(int wchar, char* utf8) { err_t err; qio_file_t *f = NULL; qio_channel_t *reading = NULL; qio_channel_t *writing = NULL; int32_t got_wchar; int i; int len; len = strlen(utf8); if( len == 0 && wchar == 0 ) len = 1; // read 1-byte null //printf("Testing character %x len %i \n", wchar, len); err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_char(true, writing, wchar); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < len; i++ ) { got_wchar = qio_channel_read_byte(true, reading); //printf("Read byte %x\n", got_wchar); assert(got_wchar == (unsigned char) utf8[i]); } assert( -EEOF == qio_channel_read_byte(true, reading) ); qio_channel_release(reading); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_read_char(true, reading, &got_wchar); assert(!err); assert(got_wchar == wchar); qio_channel_release(reading); qio_file_release(f); f = NULL; }
void max_width_test() { const char *out = NULL; ssize_t out_len = 0; err_t err; qio_file_t *f = NULL; qio_channel_t *reading = NULL; qio_channel_t *writing = NULL; qio_style_t style = qio_style_default(); err = qio_file_open_tmp(&f, 0, NULL); assert(!err); style.binary = 0; style.string_format = 1; style.max_width_columns = 5; err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, &style); assert(!err); err = qio_channel_print_string(true, writing, "helloworld", 10); assert(!err); qio_channel_release(writing); assert(!err); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_scan_string(true, reading, &out, &out_len, -1); assert(!err); qio_channel_release(reading); assert(!err); if(strlen(out) != 5){ printf("FAIL: min_width expecting 11 chars for '%s'\n", out); assert(0); } free((void*) out); qio_file_release(f); f = NULL; }
void check_bits(int offset, int padding) { qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; // bitpats is in pairs of data, num bits uint64_t bitpats[] = {1,1, 0,1, 1,1, 1,1, // 1011 -> b 0,1, 0,1, 1,1, 0,1, // 0010 -> 2 2,2, 3,2, // 1011 -> b 2,2, 0,2, // 1000 -> 8 0xffffffffffffffffull,64, // ffff ffff ffff ffff 0,6, 0x3f,6, // 0000 0011 1111 -> 03f 0,1, 0xff,8, 0,1, 0x7f,7, 3,3,// 0111 1111 1011 1111 1011 ->7fbfb 0,3, 1,2, 0,3, // 0000 1000 -> 08 1,1, 0x8100ff00ff20ff81ull,64, 0,7, // 1100 0000 1000 0000 0111 1111 1000 0000 0111 1111 1001 0000 0111 1111 1100 0000 1000 0000 -> c0807f807f907fc080 1,2 }; uint8_t expect[] = {0xb2, 0xb8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xf7, 0xfb, 0xfb, 0x08, 0xc0, 0x80, 0x7f, 0x80, 0x7f, 0x90, 0x7f, 0xc0, 0x80, 0x40, 0xff, 0x40, 0xff, 0x40}; qioerr err; int i; if( verbose ) printf("\nBIT IO TEST AT OFFSET %i PADDING %i\n\n", offset, padding); err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, 0, 0, 1, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < offset; i++ ) { err = qio_channel_write_byte(true, writing, 0xc1); assert(!err); } // Write stuff to the file. for( i = 0; i < sizeof(bitpats)/(2*sizeof(uint64_t)); i++ ) { if( verbose ) printf("Writing %i bits of %llx\n", (int) bitpats[2*i + 1], (long long int) bitpats[2*i]); err = qio_channel_write_bits(true, writing, bitpats[2*i], bitpats[2*i + 1]); assert(!err); } if( verbose ) printf("Writing byte 0xff at the end\n"); err = qio_channel_write_byte(true, writing, 0xff); assert(!err); if( verbose ) printf("Writing bits 010 at the end\n"); err = qio_channel_write_bits(true, writing, 2, 3); assert(!err); if( verbose ) printf("Writing byte 0xff at the end\n"); err = qio_channel_write_byte(true, writing, 0xff); assert(!err); if( verbose ) printf("Writing bits 010 at the end\n"); err = qio_channel_write_bits(true, writing, 2, 3); assert(!err); for( i = 0; i < padding; i++ ) { err = qio_channel_write_byte(true, writing, 0xc1); assert(!err); } qio_channel_release(writing); // Read the data a byte at a time. err = qio_channel_create(&reading, f, 0, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < offset; i++ ) { uint8_t got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert(got == 0xc1); } // Read stuff from the file. for( i = 0; i < sizeof(expect); i++ ) { uint8_t got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); if( verbose ) printf("Reading byte expecting %x got %x\n", (int) expect[i], (int) got); assert( got == expect[i] ); } for( i = 0; i < padding; i++ ) { uint8_t got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert(got == 0xc1); } qio_channel_release(reading); // Read the data with the binary reader. err = qio_channel_create(&reading, f, 0, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < offset; i++ ) { uint8_t got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert(got == 0xc1); } // Read stuff from the file. for( i = 0; i < sizeof(bitpats)/(2*sizeof(uint64_t)); i++ ) { uint64_t got = 0; err = qio_channel_read_bits(true, reading, &got, bitpats[2*i + 1]); assert(!err); if( verbose ) printf("Reading %i bits expecting %llx got %llx\n", (int) bitpats[2*i + 1], (long long int) bitpats[2*i], (long long int) got); assert( got == bitpats[2*i] ); } { uint8_t got = 0; uint64_t b = 0; got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert( got == 0xff ); b = 0; err = qio_channel_read_bits(true, reading, &b, 3); assert(!err); assert( b == 2 ); got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert( got == 0xff ); b = 0; err = qio_channel_read_bits(true, reading, &b, 3); assert(!err); assert( b == 2 ); } for( i = 0; i < padding; i++ ) { uint8_t got = 0; err = qio_channel_read_amt(true, reading, &got, 1); assert(!err); assert(got == 0xc1); } qio_channel_release(reading); // Close the file. qio_file_release(f); }
void check_mark(char* writepattern, char* readpattern) { qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; int64_t offset; int32_t got; err_t err; int i; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, 0, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 0); for( i = 0; writepattern[i]; i++ ) { switch (writepattern[i]) { case 'M': err = qio_channel_mark(true, writing); break; case 'R': err = qio_channel_revert(true, writing); break; case 'C': err = qio_channel_commit(true, writing); break; case 'A': err = qio_channel_advance(true, writing, 1); break; default: err = qio_channel_write_byte(true, writing, writepattern[i]); } assert(!err); } qio_channel_release(writing); // Read the data a byte at a time. err = qio_channel_create(&reading, f, 0, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( i = 0; readpattern[i]; i++ ) { switch (readpattern[i]) { case 'M': err = qio_channel_mark(true, reading); break; case 'R': err = qio_channel_revert(true, reading); break; case 'C': err = qio_channel_commit(true, reading); break; case 'A': err = qio_channel_advance(true, reading, 1); break; default: got = qio_channel_read_byte(true, reading); if( got >= 0 ) assert(got == readpattern[i]); else err = -got; } assert(!err); } got = qio_channel_read_byte(true, reading); assert( got == - EEOF ); qio_channel_release(reading); // Close the file. qio_file_release(f); }
void check_mark_easy(void) { qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; int64_t offset; err_t err; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, 0, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 0); err = qio_channel_write_byte(true, writing, 'a'); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 1); err = qio_channel_mark(true, writing); assert(!err); err = qio_channel_write_byte(true, writing, 'b'); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 2); err = qio_channel_revert(true, writing); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 1); err = qio_channel_mark(true, writing); assert(!err); err = qio_channel_write_byte(true, writing, 'c'); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert(offset == 2); err = qio_channel_commit(true, writing); assert(!err); assert(offset == 2); qio_channel_release(writing); // Read the data a byte at a time. err = qio_channel_create(&reading, f, 0, 1, 0, 0, INT64_MAX, NULL); assert(!err); assert('a' == qio_channel_read_byte(true, reading)); assert('c' == qio_channel_read_byte(true, reading)); assert(-EEOF == qio_channel_read_byte(true, reading)); qio_channel_release(reading); // Close the file. qio_file_release(f); }
// unbounded_channels <= 0 means no, > 0 means yes // -1 means advance. void check_channel(char threadsafe, qio_chtype_t type, int64_t start, int64_t len, int64_t chunksz, qio_hint_t file_hints, qio_hint_t ch_hints, char unbounded_channels, char reopen) { qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; int64_t offset; int64_t usesz; int64_t end = start + len; int err; unsigned char* chunk; unsigned char* got_chunk; int64_t k; ssize_t amt_written; ssize_t amt_read; char* chhints; char* fhints; FILE* writefp = NULL; FILE* readfp = NULL; int memory; int64_t ch_end = end; char filename[128]; int fd = -1; strcpy(filename,"/tmp/qio_testXXXXXX"); if( unbounded_channels > 0 ) ch_end = INT64_MAX; ch_hints = (ch_hints & ~ QIO_CHTYPEMASK) | type; memory = 0; if( (file_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY || (ch_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY ) { memory = 1; } if( memory ) { file_hints = (file_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY; ch_hints = (ch_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY; } if( memory && type == QIO_CH_ALWAYS_UNBUFFERED ) return; if( memory && reopen ) return; if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_FREADFWRITE ) { if( (file_hints & QIO_METHODMASK) != QIO_METHOD_FREADFWRITE ) return; } if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_MMAP ) { if( (file_hints & QIO_METHODMASK) != QIO_METHOD_MMAP ) return; } fhints = qio_hints_to_string(file_hints); chhints = qio_hints_to_string(ch_hints); printf("check_channel(threadsafe=%i, type=%i, start=%lli, len=%lli, chunksz=%lli, file_hints=%s, ch_hints=%s, unbounded=%i, reopen=%i)\n", (int) threadsafe, (int) type, (long long int) start, (long long int) len, (long long int) chunksz, fhints, chhints, (int) unbounded_channels, (int) reopen ); free(fhints); free(chhints); chunk = malloc(chunksz); got_chunk = malloc(chunksz); assert(chunk); assert(got_chunk); if( memory ) { err = qio_file_open_mem_ext(&f, NULL, QIO_FDFLAG_READABLE|QIO_FDFLAG_WRITEABLE|QIO_FDFLAG_SEEKABLE, file_hints, NULL); assert(!err); } else { // Open a temporary file. if( reopen ) { fd = mkstemp(filename); close(fd); err = qio_file_open_access(&f, filename, "w", file_hints, NULL); assert(!err); } else { err = qio_file_open_tmp(&f, file_hints, NULL); assert(!err); } // Rewind the file if (f->fp ) { int got; got = fseek(f->fp, start, SEEK_SET); assert( got == 0 ); } else { off_t off; err = sys_lseek(f->fd, start, SEEK_SET, &off); assert(!err); } } // Create a "write to file" channel. err = qio_channel_create(&writing, f, ch_hints, 0, 1, start, ch_end, NULL); assert(!err); // Write stuff to the file. for( offset = start; offset < end; offset += usesz ) { usesz = chunksz; if( offset + usesz > end ) usesz = end - offset; // Fill chunk. fill_testdata(offset, usesz, chunk); // Write chunk. if( writefp ) { amt_written = fwrite(chunk, 1, usesz, writefp); } else { err = qio_channel_write(threadsafe, writing, chunk, usesz, &amt_written); assert(!err); } assert(amt_written == usesz); } // Attempt to write 1 more byte; we should get EEOF // if we've restricted the range of the channel. // Write chunk. if( unbounded_channels > 0) { // do nothing } else { if( writefp ) { int got; got = fflush(writefp); assert(got == 0); amt_written = fwrite(chunk, 1, 1, writefp); // fwrite might buffer on its own. if( amt_written != 0 ) { got = fflush(writefp); assert(got == EOF); } assert(errno == EEOF); } else { if( unbounded_channels < 0 ) { int times = -unbounded_channels; for( int z = 0; z < times; z++ ) { err = qio_channel_advance(threadsafe, writing, 1); assert( !err ); } } err = qio_channel_write(threadsafe, writing, chunk, 1, &amt_written); assert(amt_written == 0); assert( err == EEOF ); } } qio_channel_release(writing); // Reopen the file if we're doing reopen if( reopen ) { // Close the file. qio_file_release(f); err = qio_file_open_access(&f, filename, "r", file_hints, NULL); assert(!err); } // Check that the file is the right length. if( !memory ) { struct stat stats; err = sys_fstat(f->fd, &stats); assert(!err); assert(stats.st_size == end); } // That was fun. Now start at the beginning of the file // and read the data. // Rewind the file if( !memory ) { off_t off; sys_lseek(f->fd, start, SEEK_SET, &off); assert(!err); } // Read the data. //err = qio_channel_init_file(&reading, type, f, ch_hints, 1, 0, start, end); err = qio_channel_create(&reading, f, ch_hints, 1, 0, start, ch_end, NULL); assert(!err); // Read stuff from the file. for( offset = start; offset < end; offset += usesz ) { usesz = chunksz; if( offset + usesz > end ) usesz = end - offset; // Fill chunk. fill_testdata(offset, usesz, chunk); memset(got_chunk, 0xff, usesz); // Read chunk. if( readfp ) { amt_read = fread(got_chunk, 1, usesz, readfp); } else { err = qio_channel_read(threadsafe, reading, got_chunk, usesz, &amt_read); assert( err == EEOF || err == 0); } assert(amt_read == usesz); // Compare chunk. for( k = 0; k < usesz; k++ ) { assert(got_chunk[k] == chunk[k]); } } if( readfp ) { amt_read = fread(got_chunk, 1, 1, readfp); assert( amt_read == 0 ); assert( feof(readfp) ); } else { if( unbounded_channels < 0 ) { int times = -unbounded_channels; for( int z = 0; z < times; z++ ) { err = qio_channel_advance(threadsafe, reading, 1); assert( !err ); } err = qio_channel_advance(threadsafe, reading, -unbounded_channels); assert( !err ); } err = qio_channel_read(threadsafe, reading, got_chunk, 1, &amt_read); assert( err == EEOF ); } qio_channel_release(reading); //err = qio_channel_destroy(&reading); // Close the file. qio_file_release(f); if( reopen ) { unlink(filename); } free(chunk); free(got_chunk); }
void test_scanmatch() { err_t err; qio_file_t *f = NULL; qio_channel_t *reading = NULL; qio_channel_t *writing = NULL; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_char(true, writing, ' '); assert(!err); err = qio_channel_write_char(true, writing, 'm'); assert(!err); err = qio_channel_write_char(true, writing, 'a'); assert(!err); err = qio_channel_write_char(true, writing, 't'); assert(!err); err = qio_channel_write_char(true, writing, 'c'); assert(!err); err = qio_channel_write_char(true, writing, 'h'); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_scan_literal(true, reading, "test", 4, 1); assert(err == EFORMAT); err = qio_channel_scan_literal(true, reading, "match", 5, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, "match", 5, 1); assert(err == EEOF); qio_channel_release(reading); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_scan_literal(true, reading, " match", 5, 1); assert(err == 0); qio_channel_release(reading); qio_file_release(f); f = NULL; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_char(true, writing, 'a'); assert(!err); err = qio_channel_write_char(true, writing, ' '); assert(!err); err = qio_channel_write_char(true, writing, 'b'); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_scan_literal(true, reading, "ab", 2, 1); assert(err == EFORMAT); err = qio_channel_scan_literal(true, reading, "a", 1, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, " ", 1, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, "b", 1, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, "a", 1, 1); assert(err == EEOF); qio_channel_release(reading); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_scan_literal(true, reading, "ab", 2, 1); assert(err == EFORMAT); err = qio_channel_scan_literal(true, reading, "a ", 2, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, "b", 1, 1); assert(err == 0); err = qio_channel_scan_literal(true, reading, "a", 1, 1); assert(err == EEOF); qio_channel_release(reading); qio_file_release(f); f = NULL; }
/** * Test basic ascii functionality */ void basicstring_test() { const char *out = NULL; ssize_t out_len = 0; err_t err; int x,y=0; qio_file_t *f = NULL; qio_channel_t *reading = NULL; qio_channel_t *writing = NULL; #define NUM_STR_STYLES 12 qio_style_t styles[NUM_STR_STYLES]; string_test_t strings[] = { { "", 0 }, { "a", 1 }, { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 255}, }; int NUM_STRINGS = sizeof(strings)/sizeof(string_test_t); printf("Testing basic string writing/reading\n"); err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for(x=0;x<NUM_STR_STYLES;x++) { qio_style_init_default(&styles[x]); } // Set up the styles // 0 is default. styles[0].binary = 1; styles[0].str_style = -1; // binary styles. styles[1].binary = 1; styles[1].str_style = -1; styles[2].binary = 1; styles[2].str_style = -2; styles[3].binary = 1; styles[3].str_style = -4; styles[4].binary = 1; styles[4].str_style = -8; styles[5].binary = 1; styles[5].str_style = -10; styles[6].binary = 1; styles[6].str_style = -0x0100; // zero-terminated. styles[7].binary = 1; styles[7].str_style = -0x01ff; styles[8].binary = 1; styles[8].str_style = 0xffff; // updated below for STYLE 8! styles[9].string_format = QIO_STRING_FORMAT_BASIC; styles[9].string_start = '|'; styles[9].string_end = '+'; styles[10].string_format = QIO_STRING_FORMAT_CHPL; styles[11].string_format = QIO_STRING_FORMAT_JSON; for(x=0;x<NUM_STR_STYLES;x++){ qio_style_t* style = &styles[x]; for(y=0;y<NUM_STRINGS;y++){ string_test_t* string = &strings[y]; // make style 8 always use the string length! if( x == 8 ) style->str_style = string->length; err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, style); assert(!err); //printf("Writing string '%s' with style %i\n", string->string, x); if( style->binary ) err = qio_channel_write_string(true, style->byteorder, style->str_style, writing, string->string, string->length); else err = qio_channel_print_string(true, writing, string->string, string->length); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, style); assert(!err); //printf("Reading string '%s' with style %i\n", string->string, x); if( style->binary ) err = qio_channel_read_string(true, style->byteorder, style->str_style, reading, &out, &out_len, -1); else err = qio_channel_scan_string(true, reading, &out, &out_len, -1); assert(!err); qio_channel_release(reading); //printf("Got '%s' expect '%s'\n", out, string->string); if(memcmp(out, string->string, string->length) != 0){ printf("FAIL: style %d, string='%s'\n", x, string->string); free((void*) out); assert(0); } //printf("PASS: style %d\n", x); if(out){ free((void*) out); out=NULL; } } } qio_file_release(f); f = NULL; printf("PASS: basic string test\n"); #undef NUM_STR_STYLES #define NUM_STRINGS 1 }
void test_quoted_string_maxlength(void) { qio_style_t style = qio_style_default(); qio_channel_t *reading; qio_channel_t *writing; qio_file_t *f = NULL; err_t err; const char* inputs[8][16] = { { "", // original string "\"\"", // maxlen = 1 "\"\"", // maxlen = 2 "\"\"", // maxlen = 3 "\"\"", // maxlen = 4 "\"\"", // maxlen = 5 "\"\"", // maxlen = 6 "\"\"", // maxlen = 7 "\"\"", // maxlen = 8 "\"\"", // maxlen = 9 "\"\"", // maxlen = 10 "\"\"", // maxlen = 11 "\"\"", // maxlen = 12 "\"\"", // maxlen = 13 "\"\"", // maxlen = 14 NULL }, { "a", // original string "\"a\"", // maxlen = 1 "\"a\"", // maxlen = 2 "\"a\"", // maxlen = 3 "\"a\"", // maxlen = 4 "\"a\"", // maxlen = 5 "\"a\"", // maxlen = 6 "\"a\"", // maxlen = 7 "\"a\"", // maxlen = 8 "\"a\"", // maxlen = 9 "\"a\"", // maxlen = 10 "\"a\"", // maxlen = 11 "\"a\"", // maxlen = 12 "\"a\"", // maxlen = 13 "\"a\"", // maxlen = 14 NULL }, { "ab", // original string "\"ab\"", // maxlen = 1 "\"ab\"", // maxlen = 2 "\"ab\"", // maxlen = 3 "\"ab\"", // maxlen = 4 "\"ab\"", // maxlen = 5 "\"ab\"", // maxlen = 6 "\"ab\"", // maxlen = 7 "\"ab\"", // maxlen = 8 "\"ab\"", // maxlen = 9 "\"ab\"", // maxlen = 10 "\"ab\"", // maxlen = 11 "\"ab\"", // maxlen = 12 "\"ab\"", // maxlen = 13 "\"ab\"", // maxlen = 14 NULL }, { "abc", // original string "\"abc\"", // maxlen = 1 "\"abc\"", // maxlen = 2 "\"abc\"", // maxlen = 3 "\"abc\"", // maxlen = 4 "\"abc\"", // maxlen = 5 "\"abc\"", // maxlen = 6 "\"abc\"", // maxlen = 7 "\"abc\"", // maxlen = 8 "\"abc\"", // maxlen = 9 "\"abc\"", // maxlen = 10 "\"abc\"", // maxlen = 11 "\"abc\"", // maxlen = 12 "\"abc\"", // maxlen = 13 "\"abc\"", // maxlen = 14 NULL }, { "abcd", // original string "\"\"...", // maxlen = 1 "\"\"...", // maxlen = 2 "\"\"...", // maxlen = 3 "\"\"...", // maxlen = 4 "\"\"...", // maxlen = 5 "\"abcd\"", // maxlen = 6 "\"abcd\"", // maxlen = 7 "\"abcd\"", // maxlen = 8 "\"abcd\"", // maxlen = 9 "\"abcd\"", // maxlen = 10 "\"abcd\"", // maxlen = 11 "\"abcd\"", // maxlen = 12 "\"abcd\"", // maxlen = 13 "\"abcd\"", // maxlen = 14 NULL }, { "123456789", // original string "\"\"...", // maxlen = 1 "\"\"...", // maxlen = 2 "\"\"...", // maxlen = 3 "\"\"...", // maxlen = 4 "\"\"...", // maxlen = 5 "\"1\"...", // maxlen = 6 "\"12\"...", // maxlen = 7 "\"123\"...", // maxlen = 8 "\"1234\"...", // maxlen = 9 "\"12345\"...", // maxlen = 10 "\"123456789\"", // maxlen = 11 "\"123456789\"", // maxlen = 12 "\"123456789\"", // maxlen = 13 "\"123456789\"", // maxlen = 14 NULL }, { "\x01X\x01Y", // original string "\"\"...", // maxlen = 1 "\"\"...", // maxlen = 2 "\"\"...", // maxlen = 3 "\"\"...", // maxlen = 4 "\"\"...", // maxlen = 5 "\"\"...", // maxlen = 6 "\"\"...", // maxlen = 7 "\"\"...", // maxlen = 8 "\"\\x01\"...", // maxlen = 9 "\"\\x01X\"...", // maxlen = 10 "\"\\x01X\"...", // maxlen = 11 "\"\\x01X\\x01Y\"", // maxlen = 12 "\"\\x01X\\x01Y\"", // maxlen = 13 "\"\\x01X\\x01Y\"", // maxlen = 14 NULL }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, } }; char buf[50] = {0}; int i,j; style.binary=0; style.string_start = '"'; style.string_end = '"'; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; inputs[i][0]; i++ ) { const char* input = inputs[i][0]; ssize_t input_len = strlen(input); for( j = 1; inputs[i][j]; j++ ) { const char* expect = inputs[i][j]; ssize_t expect_len = strlen(expect); qio_truncate_info_t ti; const char* got = NULL; ssize_t truncate_len = (j<input_len)?(j):(input_len); style.string_format = QIO_STRING_FORMAT_CHPL; style.max_width_columns = j; ti.max_columns = style.max_width_columns; ti.max_chars = SSIZE_MAX; ti.max_bytes = SSIZE_MAX; // check that qio_quote_string gives correct string when // used in a no-quote mode if( i != 6 ) { // but not for test 6 since the control characters are weird. err = qio_quote_string(0, 0, QIO_STRING_FORMAT_WORD, input, input_len, &got, &ti); assert(!err); assert(ti.ret_columns == truncate_len); assert(ti.ret_chars == truncate_len); assert(truncate_len == strlen(got)); assert( 0 == memcmp(got, input, truncate_len) ); free((void*) got); } // Now, check that qio_quote_string returns the correct string. err = qio_quote_string(style.string_start, style.string_end, style.string_format, input, input_len, &got, &ti); assert(!err); assert(ti.ret_columns == strlen(inputs[i][1]) || ti.ret_columns <= j); assert(ti.ret_bytes == expect_len); assert(ti.ret_bytes == strlen(got)); assert( 0 == strcmp(got, expect) ); free((void*) got); // Now, check that the quoting works correctly when writing. err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, &style); assert(!err); err = qio_channel_print_string(true, writing, input, input_len); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, &style); assert(!err); err = qio_channel_read_amt(true, reading, buf, expect_len); assert(!err); qio_channel_release(reading); //printf("Got %s expect %s\n", buf, expect); assert( memcmp(buf, expect, expect_len) == 0 ); } } qio_file_release(f); printf("PASS: quoted max length\n"); }
void string_escape_tests() { qio_style_t style = qio_style_default(); qio_channel_t *reading; qio_channel_t *writing; qio_file_t *f = NULL; err_t err; const char* inputs[2][4] = { {"a \"\\b\x01", // original string "\"a \\\"\\\\b\x01\"", // simple encoding "\"a \\\"\\\\b\\x01\"", // chapel encoding "\"a \\\"\\\\b\\u0001\"", // JSON encoding }, { NULL, NULL, NULL, NULL } }; char buf[50] = {0}; int i,j; style.binary=0; style.string_start = '"'; style.string_end = '"'; err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; inputs[i][0]; i++ ) { const char* input = inputs[i][0]; ssize_t input_len = strlen(input); for( j = 1; j < 4; j++ ) { const char* expect = inputs[i][j]; ssize_t expect_len = strlen(expect); style.string_format = j; err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, &style); assert(!err); err = qio_channel_print_string(true, writing, input, input_len); assert(!err); qio_channel_release(writing); err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, &style); assert(!err); err = qio_channel_read_amt(true, reading, buf, expect_len); assert(!err); qio_channel_release(reading); //printf("Got %s expect %s\n", buf, expect); assert( memcmp(buf, expect, expect_len) == 0 ); // Check that we can read it in again. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, &style); assert(!err); { const char* got = NULL; ssize_t got_len = 0; err = qio_channel_scan_string(true, reading, &got, &got_len, -1); assert(!err); //printf("Read back %s expect %s\n", got, input); assert( got_len == input_len ); assert( memcmp(got, input, got_len) == 0 ); free((void*) got); } qio_channel_release(reading); } } qio_file_release(f); printf("PASS: simple escape\n"); }
void test_endian(void) { // We write (hex) 00 0102 03040506 0708091011121314 // as big endian and little endian, and then we check // that the data is what we expected. err_t err; qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; int64_t offset; int len = 15; uint8_t n0 = 0; uint16_t n1 = 0x0102; uint32_t n2 = 0x03040506; uint64_t n3 = 0x0708091011121314LL; const char* expect_le = "\x00\x02\x01\x06\x05\x04\x03" "\x14\x13\x12\x11\x10\x09\x08\x07"; const char* expect_be = "\x00\x01\x02\x03\x04\x05\x06" "\x07\x08\x09\x10\x11\x12\x13\x14"; char got[16]; int i; int b_order; const char* expect; printf("Testing endian functions\n"); err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; i < 2; i++ ) { if( i == 0 ) { b_order = QIO_BIG; expect = expect_be; } else { b_order = QIO_LITTLE; expect = expect_le; } // Create a "write to file" channel. err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_uint8(true, writing, n0); assert(!err); err = qio_channel_write_uint16(true, b_order, writing, n1); assert(!err); err = qio_channel_write_uint32(true, b_order, writing, n2); assert(!err); err = qio_channel_write_uint64(true, b_order, writing, n3); assert(!err); err = qio_channel_offset(true, writing, &offset); assert(!err); assert( offset == len ); qio_channel_release(writing); writing = NULL; // Create a "read from file" channel. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_read_amt(true, reading, got, len); assert(!err); // Check that we read back what we wrote. assert( 0 == memcmp(got, expect, len) ); qio_channel_release(reading); reading = NULL; } // Close the file. qio_file_release(f); f = NULL; }
void test_printscan_float(void) { err_t err; qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; #define NSTYLES 9 qio_style_t styles[NSTYLES]; const char* zero[] = { // writing 0 "0.0", // default style "0.000", // %f precision 3 "0.000e+00", // %e precision 3 "+0.00000", // showpoint, showplus "0x0p+0", // hex "0X0.000P+0", // hex, uppercase, showpoint, prec 3 "0", // %g, 4 significant digits "0.0000", // %f, showpoint, precision 4 "0.0000e+00", // %e, showpoint, precision 4 }; const char* one[] = { // writing 1 "1.0", // default style "1.000", // %f precision 3 "1.000e+00", // %e precision 3 "+1.00000", // showpoint, showplus "0x1p+0", // hex "0X1.000P+0", // hex, uppercase, showpoint, prec 3 "1", // %g, 4 significant digits "1.0000", // %f, showpoint, precision 4 "1.0000e+00", // %e, showpoint, precision 4 }; const char* plusinf[] = { // writing +infinity "inf", // default style "inf", // %f precision 3 "inf", // %e precision 3 "+inf", // showpoint, showplus "inf", // hex "INF", // hex, uppercase, showpoint, prec 3 "inf", // %g, 4 significant digits "inf", // %f, showpoint, precision 4 "inf", // %e, showpoint, precision 4 }; const char* minusinf[] = { // writing +infinity "-inf", // default style "-inf", // %f precision 3 "-inf", // %e precision 3 "-inf", // showpoint, showplus "-inf", // hex "-INF", // hex, uppercase, showpoint, prec 3 "-inf", // %g, 4 significant digits "-inf", // %f, showpoint, precision 4 "-inf", // %e, showpoint, precision 4 }; const char* nan[] = { // writing nan "nan", // default style "nan", // %f precision 3 "nan", // %e precision 3 "+nan", // showpoint, showplus "nan", // hex "NAN", // hex, uppercase, showpoint, prec 3 "nan", // %g, 4 significant digits "nan", // %f, showpoint, precision 4 "nan", // %e, showpoint, precision 4 }; const char* nnan[] = { // writing nan "nan", // default style "nan", // %f precision 3 "nan", // %e precision 3 "-nan", // showpoint, showplus "nan", // hex "NAN", // hex, uppercase, showpoint, prec 3 "nan", // %g, 4 significant digits "nan", // %f, showpoint, precision 4 "nan", // %e, showpoint, precision 4 }; const char* x[] = { // writing 1.125e+300 "1.125e+300", // default style "1124999999999999984717009863215819639889402246251651042717325796981054812448928754462634938945285169790751774504176833459124149130131831874871128930639759966162906545922666490056516990646142904182469580674455306426256469801266735686696548991733655898546719119989659797590624855449025294035374384873472.000", // %f precision 3 "1.125e+300", // %e precision 3 "+1.12500e+300", // showpoint, showplus "0x1.ae0c41900844fp+996", // hex "0X1.AE1P+996", // hex, uppercase, showpoint, prec 3 "1.125e+300", // %g, 4 significant digits "1124999999999999984717009863215819639889402246251651042717325796981054812448928754462634938945285169790751774504176833459124149130131831874871128930639759966162906545922666490056516990646142904182469580674455306426256469801266735686696548991733655898546719119989659797590624855449025294035374384873472.0000", // %f, showpoint, precision 4 "1.1250e+300", // %e, showpoint, precision 4 }; const char* y[] = { // writing 6.125e-300, "6.125e-300", // default style "0.000", // %f precision 3 "6.125e-300", // %e precision 3 "+6.12500e-300", // showpoint, showplus "0x1.0685051469a5p-994", // hex "0X1.068P-994", // hex, uppercase, showpoint, prec 3 "6.125e-300", // %g, 4 significant digits "0.0000", // %f, showpoint, precision 4 "6.1250e-300", // %e, showpoint, precision 4 }; const char* large[] = { // writing 1.7976931348623157e+308 "1.79769e+308", // default style "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000", // %f precision 3 "1.798e+308", // %e precision 3 "+1.79769e+308", // showpoint, showplus "0x1.fffffffffffffp+1023", // hex "0X2.000P+1023", // hex, uppercase, showpoint, prec 3 "1.798e+308", // %g, 4 significant digits "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000", // %f, showpoint, precision 4 "1.7977e+308", // %e, showpoint, precision 4 }; const char* small[] = { // writing 2.2250738585072014e-308 "2.22507e-308", // default style "0.000", // %f precision 3 "2.225e-308", // %e precision 3 "+2.22507e-308", // showpoint, showplus "0x1p-1022", // hex "0X1.000P-1022", // hex, uppercase, showpoint, prec 3 "2.225e-308", // %g, 4 significant digits "0.0000", // %f, showpoint, precision 4 "2.2251e-308", // %e, showpoint, precision 4 }; double mynan = NAN; // 0.0*(1.0/0.0); double posnan = copysign(mynan, 1.0); double negnan = copysign(mynan, -1.0); double nums[] = {0.0, 1.0, 1.0/0.0 /*+inf*/, -1.0/0.0 /*-inf*/, posnan, negnan, 1.125e+300, 6.125e-300, 1.7976931348623157e+308, 2.2250738585072014e-308 }; const char** expect_arr[] = { zero, one, plusinf, minusinf, nan, nnan, x,y,large,small, NULL }; char got[500]; char sep[4] = {0,0,0,0}; ssize_t amt_read; int i,j; //printf("Testing text float I/O\n"); for( i = 0; i < NSTYLES; i++ ) { qio_style_init_default(&styles[i]); styles[i].showpointzero = 0; } // Set up the styles // 0 is default. styles[0].showpointzero = 1; // 1 has %f, precision 3 styles[1].precision = 3; styles[1].realfmt = 1; // 2 has %e, precision 3 styles[2].precision = 3; styles[2].realfmt = 2; // 3 has showpoint, showplus styles[3].showpoint = 1; styles[3].showplus = 1; // 4 has base 16 styles[4].base = 16; // 5 has base 16, uppercase styles[5].base = 16; styles[5].uppercase = 1; styles[5].showpoint = 1; styles[5].precision = 3; // 6 %g, 4 significant digits styles[6].precision = 4; styles[6].realfmt = 0; // 7 has %f showpoint, precision 4 styles[7].showpoint = 1; styles[7].precision = 4; styles[7].realfmt = 1; // 7 has %e showpoint, precision 4 styles[8].showpoint = 1; styles[8].precision = 4; styles[8].realfmt = 2; // Open a temporary file. err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; expect_arr[i]; i++ ) { for( j = 0; j < NSTYLES; j++ ) { const char* expect = expect_arr[i][j]; double num = nums[i]; qio_style_t* style = &styles[j]; double got_num; //printf("Expect '%s' testing %e style %i\n", expect, num, j); memset(got, 0, sizeof(got)); // Create a "write to file" channel. err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, style); assert(!err); err = qio_channel_print_float(true, writing, &num, 8); assert(!err); // write a separator so we can use the same file.. err = qio_channel_write_amt(true, writing, sep, sizeof(sep)); assert(!err); qio_channel_release(writing); writing = NULL; // Create a "read from file" channel. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, style); assert(!err); err = qio_channel_read(true, reading, got, sizeof(got), &amt_read); assert(err == EEOF); //printf("Got '%s'\n", got); assert( 0 == strcmp(got, expect) ); qio_channel_release(reading); reading = NULL; // Try scanning our number. // Create a "read from file" channel. if( i < 7 ) { err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); got_num = 0; err = qio_channel_scan_float(true, reading, &got_num, 8); assert(!err); //printf("Got '%s' %e\n", got, got_num); //assert( got_num == num ); qio_channel_release(reading); reading = NULL; } } } // Close the file. qio_file_release(f); f = NULL; printf("PASS: text float I/O\n"); #undef NSTYLES }
void test_printscan_int(void) { err_t err; qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; #define NSTYLES 10 qio_style_t styles[NSTYLES]; const char* zero[] = { // writing 0 "0", // default style " 0", // min_width = 3, pad = ' ' "000", // min_width = 3, pad = 0 "0 ", // min_width = 3, pad = ' ', leftjustify "0", // hex "0x0", // hex, showbase " 0", // binary, min_width = 4 "0b0", // binary, showbase " 0b0", // binary, showbase, showplus=pad "+0X0" // hex, showbase, showplus=+, uppercase }; const char* one[] = { // writing 1 "1", // default style " 1", // min_width = 3, pad = ' ' "001", // min_width = 3, pad = 0 "1 ", // min_width = 3, pad = ' ', leftjustify "1", // hex "0x1", // hex, showbase " 1", // binary, min_width = 4 "0b1", // binary, showbase " 0b1", // binary, showbase, showplus=pad "+0X1" // hex, showbase, showplus=+, uppercase }; const char* hundred[] = { // writing 100 = 0x64 = 0b1100100 "100", // default style "100", // min_width = 3, pad = ' ' "100", // min_width = 3, pad = 0 "100", // min_width = 3, pad = ' ', leftjustify "64", // hex "0x64", // hex, showbase "1100100", // binary, min_width = 4 "0b1100100", // binary, showbase " 0b1100100", // binary, showbase, showplus=pad "+0X64" // hex, showbase, showplus=+, uppercase }; const char* big[] = { // writing 2^63-1 = 9223372036854775807 = 0x7FFFFFFFFFFFFFFF = 0b111111111111111111111111111111111111111111111111111111111111111 "9223372036854775807", // default style "9223372036854775807", // min_width = 3, pad = ' ' "9223372036854775807", // min_width = 3, pad = 0 "9223372036854775807", // min_width = 3, pad = ' ', leftjustify "7fffffffffffffff", // hex "0x7fffffffffffffff", // hex, showbase "111111111111111111111111111111111111111111111111111111111111111", // binary, min_width = 4 "0b111111111111111111111111111111111111111111111111111111111111111", // binary, showbase " 0b111111111111111111111111111111111111111111111111111111111111111", // binary, showbase, showplus=pad "+0X7FFFFFFFFFFFFFFF" // hex, showbase, showplus=+, uppercase }; const char* small[] = { // writing -2^63 = -9223372036854775808 = -0x8000000000000000 = -0b1000000000000000000000000000000000000000000000000000000000000000 "-9223372036854775808", // default style "-9223372036854775808", // min_width = 3, pad = ' ' "-9223372036854775808", // min_width = 3, pad = 0 "-9223372036854775808", // min_width = 3, pad = ' ', leftjustify "-8000000000000000", // hex "-0x8000000000000000", // hex, showbase "-1000000000000000000000000000000000000000000000000000000000000000", // binary, min_width = 4 "-0b1000000000000000000000000000000000000000000000000000000000000000", // binary, showbase "-0b1000000000000000000000000000000000000000000000000000000000000000", // binary, showbase, showplus=pad "-0X8000000000000000" // hex, showbase, showplus=+, uppercase }; int64_t nums[] = {0, 1, 100, INT64_MAX, INT64_MIN, 0}; const char** expect_arr[] = { zero, one, hundred, big, small, NULL}; char got[500]; char sep[4] = {0,0,0,0}; ssize_t amt_read; int i,j; printf("Testing text integer I/O\n"); for( i = 0; i < NSTYLES; i++ ) { qio_style_init_default(&styles[i]); } // Set up the styles // 0 is default. // 1 has minwidth 3, pad ' ' styles[1].min_width_columns = 3; styles[1].pad_char = ' '; // 2 has minwidth 3, pad 0 styles[2].min_width_columns = 3; styles[2].pad_char = '0'; // 3 has minwidth 3, pad ' ', leftjustify styles[3].min_width_columns = 3; styles[3].pad_char = ' '; styles[3].leftjustify = 1; // 4 has defaults, hex styles[4].base = 16; styles[4].prefix_base = 0; // 5 has defaults, hex, showbase styles[5].base = 16; styles[5].prefix_base = 1; // 6 has defaults, binary, min_width=4 styles[6].base = 2; styles[6].min_width_columns = 4; styles[6].prefix_base = 0; // 7 has defaults, binary, showbase styles[7].base = 2; styles[7].prefix_base = 1; // 8 has showbase, showplus = pad, binary styles[8].base = 2; styles[8].prefix_base = 1; styles[8].showplus = 2; // 9 has showbase, showplus, hex, uppercase styles[9].base = 16; styles[9].prefix_base = 1; styles[9].showplus = 1; styles[9].uppercase = 1; // Open a temporary file. err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; expect_arr[i]; i++ ) { for( j = 0; j < NSTYLES; j++ ) { const char* expect = expect_arr[i][j]; int64_t num = nums[i]; qio_style_t* style = &styles[j]; int64_t got_num; //printf("Expect '%s' testing 0x%" PRIx64 " style %i\n", expect, num, j); memset(got, 0, sizeof(got)); // Create a "write to file" channel. err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, style); assert(!err); err = qio_channel_print_int(true, writing, &num, 8, true); assert(!err); // write a separator so we can use the same file.. err = qio_channel_write_amt(true, writing, sep, sizeof(sep)); assert(!err); qio_channel_release(writing); writing = NULL; // Create a "read from file" channel. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_read(true, reading, got, sizeof(got), &amt_read); assert(err == EEOF); //printf("Got '%s' expect '%s'\n", got, expect); // assert( 0 == strcmp(got, expect) ); qio_channel_release(reading); reading = NULL; // Try scanning our number. // Create a "read from file" channel. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, style); assert(!err); got_num = 0; err = qio_channel_scan_int(true, reading, &got_num, 8, 1); assert(!err); //printf("Got '%s' 0x%" PRIx64 "\n", got, got_num); assert( got_num == num ); qio_channel_release(reading); reading = NULL; } } // Close the file. qio_file_release(f); f = NULL; #undef NSTYLES }
void check_write_read_pat(int width, int num, int pat, qio_chtype_t type, qio_hint_t file_hints, qio_hint_t ch_hints, char reopen) { qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; qioerr err; int memory; char* chhints; char* fhints; char filename[128]; int fd = -1; uint64_t one = 1; uint64_t mask = (one << width) - 1; if( width == 64 ) mask = -1; strcpy(filename,"/tmp/qio_bits_testXXXXXX"); ch_hints = (ch_hints & ~ QIO_CHTYPEMASK) | type; memory = 0; if( (file_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY || (ch_hints & QIO_METHODMASK) == QIO_METHOD_MEMORY ) { memory = 1; } if( memory ) { file_hints = (file_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY; ch_hints = (ch_hints & ~ QIO_METHODMASK ) | QIO_METHOD_MEMORY; } if( memory && type == QIO_CH_ALWAYS_UNBUFFERED ) return; if( memory && reopen ) return; if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_FREADFWRITE ) { if( (file_hints & QIO_METHODMASK) != QIO_METHOD_FREADFWRITE ) return; } if( (ch_hints & QIO_METHODMASK) == QIO_METHOD_MMAP ) { if( (file_hints & QIO_METHODMASK) != QIO_METHOD_MMAP ) return; } fhints = qio_hints_to_string(file_hints); chhints = qio_hints_to_string(ch_hints); if( verbose ) printf("check_write_read_pat(width=%i, num=%i, pat=%i, type=%i, file_hints=%s %i, ch_hints=%s %i, reopen=%i)\n", width, num, pat, type, fhints, (int) file_hints, chhints, (int) ch_hints, (int) reopen); qio_free(fhints); qio_free(chhints); if( memory ) { err = qio_file_open_mem_ext(&f, NULL, QIO_FDFLAG_READABLE|QIO_FDFLAG_WRITEABLE|QIO_FDFLAG_SEEKABLE, file_hints, NULL); assert(!err); } else { if( reopen ) { fd = mkstemp(filename); close(fd); err = qio_file_open_access(&f, filename, "w", file_hints, NULL); assert(!err); } else { err = qio_file_open_tmp(&f, 0, NULL); assert(!err); } } err = qio_channel_create(&writing, f, ch_hints, 0, 1, 0, INT64_MAX, NULL); assert(!err); for( int i = 0; i < num; i++ ) { uint64_t x; if( pat == 0 ) { if( i & 1 ) x = mask; else x = 0; } else { x = ((uint64_t) i) & mask; } { // check offset int64_t off = qio_channel_offset_unlocked(writing); assert( off == (width * i + 7) / 8 ); } err = qio_channel_write_bits(false, writing, x, width); assert(!err); } qio_channel_release(writing); // Reopen the file if we're doing reopen if( reopen ) { // Close the file. qio_file_release(f); err = qio_file_open_access(&f, filename, "r", file_hints, NULL); assert(!err); } // Rewind the file if( !memory ) { off_t off; sys_lseek(f->fd, 0, SEEK_SET, &off); assert(!err); } err = qio_channel_create(&reading, f, ch_hints, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( int i = 0; i < num; i++ ) { uint64_t got = 0; uint64_t x; if( pat == 0 ) { if( i & 1 ) x = mask; else x = 0; } else { x = ((uint64_t) i) & mask; } { // check offset int64_t off = qio_channel_offset_unlocked(reading); assert( off == (width * i + 7) / 8 ); } //printf("Reading at %lli\n", (long long int) qio_channel_offset_unlocked(reading)); err = qio_channel_read_bits(false, reading, &got, width); assert(!err); //printf("Got %lli\n", (long long int) got); if( got != x ) { printf("Fails (%i %i %i) at %i got=%llx expect=%llx\n", width, num, pat, i, (unsigned long long int) got, (unsigned long long int) x); assert(got == x); break; } } qio_channel_release(reading); // Close the file. qio_file_release(f); if( reopen ) { unlink(filename); } }
int main(int argc, char** argv) { int offset, padding; int width, logn, maxlogn; qio_chtype_t type; qio_hint_t hints[] = {QIO_METHOD_DEFAULT, QIO_METHOD_READWRITE, QIO_METHOD_PREADPWRITE, QIO_METHOD_FREADFWRITE, QIO_METHOD_MEMORY, QIO_METHOD_MMAP, QIO_METHOD_MMAP|QIO_HINT_PARALLEL, QIO_METHOD_PREADPWRITE | QIO_HINT_NOFAST}; int nhints = sizeof(hints)/sizeof(qio_hint_t); int file_hint, ch_hint; { //for( file_hint = 0; file_hint < nhints; file_hint++ ) { // check_write_read_pat(1, 262144, 0, 0, file_hint, file_hint, 0); //} //check_write_read_pat(32,4096,0,3,QIO_METHOD_PREADPWRITE,0,1); //check_write_read_pat(32,4096,0,3,0,0,1); //exit(0); //check_write_read_pat(width=32, num=4096, pat=0, type=3, file_hints=default_type default, ch_hints=buffered default, reopen=1) // Run unit tests. for( offset = 0; offset < 63; offset++ ) { for( padding = 0; padding < 63; padding++ ) { check_bits(offset, padding); } } maxlogn = 19; if( valgrind ) maxlogn = 10; for( logn = 0; logn < maxlogn; logn+=9 ) { for( width = 1; width <= 64; width++ ) { for( file_hint = 0; file_hint < nhints; file_hint++ ) { ch_hint = file_hint; type = 0; check_write_read_pat(width,1 << logn,0,type,file_hint,ch_hint,0); check_write_read_pat(width,1 << logn,1,type,file_hint,ch_hint,1); } } } } // Do extra testing that showed a bug at one point... if( !valgrind ) { int i; int n = 256*1024*1024; qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; uint64_t got; uint64_t expect; qioerr err; //qbytes_iobuf_size = 256; err = qio_file_open_mem(&f, NULL, NULL); assert(!err); //err = qio_file_open_access(&f, "test.bin", "w+", 0, NULL); //assert(!err); err = qio_channel_create(&writing, f, 0, 0, 1, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < n; i++ ) { err = qio_channel_write_bits(false, writing, i & 0x1f, 5); //err = qio_channel_write_bits(false, writing, 0x1f, 5); assert(!err); } qio_channel_release(writing); if( argc > 2 ) { err = qio_channel_create(&reading, f, 0, 1, 0, 0, INT64_MAX, NULL); assert(!err); for( i = 0; i < n; i++ ) { got = 0; err = qio_channel_read_bits(false, reading, &got, 5); assert(!err); expect = i & 0x1f; //expect = 0x1f; if( got != expect ) { printf("Failed at i=%i got %llx expect %llx\n", i, (long long int) got, (long long int) expect); assert( got == expect ); } } qio_channel_release(reading); } qio_file_release(f); } printf("qio_bits_test PASS\n"); return 0; }
void test_readwriteint(void) { err_t err; qio_file_t* f; qio_channel_t* writing; qio_channel_t* reading; const char* testdata[] = {"\x00\x00\x00\x00\x00\x00\x00\x00", "\xff\xff\xff\xff\xff\xff\xff\xff", "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f", "\x01\x02\x03\x04\x05\x06\x07\x08", "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8", NULL }; int sizes[] = {1, -1, 2, -2, 4, -4, 8, -8, 0}; int byteorder[] = {QIO_NATIVE, QIO_BIG, QIO_LITTLE, 0}; char got[16]; int i,j,k; printf("Testing binary integer I/O\n"); // Open a temporary file. err = qio_file_open_tmp(&f, 0, NULL); assert(!err); for( i = 0; testdata[i]; i++ ) { for( j = 0; sizes[j]; j++ ) { for( k = 0; byteorder[k]; k++ ) { const char* data = testdata[i]; int sz = sizes[j]; int b_order = byteorder[k]; int len; len = sz; if( len < 0 ) len = - sz; memset(got, 0, sizeof(got)); // Create a "write to file" channel. err = qio_channel_create(&writing, f, QIO_CH_BUFFERED, 0, 1, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_write_int(true, b_order, writing, data, len, sz < 0); assert(!err); qio_channel_release(writing); writing = NULL; // Create a "read from file" channel. err = qio_channel_create(&reading, f, QIO_CH_BUFFERED, 1, 0, 0, INT64_MAX, NULL); assert(!err); err = qio_channel_read_int(true, b_order, reading, got, len, sz < 0); assert(!err); // Check that we read back what we wrote. assert( 0 == memcmp(got, data, len) ); qio_channel_release(reading); reading = NULL; } } } // Close the file. qio_file_release(f); f = NULL; }