#include "nbbio.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define NVECTORS 3
void check(int d, int e, int line)
{
if (d != e) {
printf("check: %d != %d at line %d\n", d, e, line);
exit(1);
}
}
#define CHECK(d, e) check(d, e, __LINE__)
static void dumpBuf(const void *p, int len)
{
int i;
for (i=0; i<len; i++) {
printf("%02d ", 0xff & ((unsigned const char *)p)[i]);
if ((i & 31) == 31)
puts("");
}
puts("");
}
int main()
{
nbbio nb;
int err;
char buf[nbbio_BUFLEN];
char buf2[nbbio_BUFLEN];
int i;
int bytesused;
int len;
int c;
/* Sanity checks */
CHECK( nb.bytesUsed(), 0 );
CHECK( nb.contigBytesUsed(), 0 );
CHECK( nb.bytesFree(), nbbio_BUFLEN-1 );
CHECK( nb.contigBytesFree(), nbbio_BUFLEN-1 );
CHECK( nb.isEmpty(), TRUE );
CHECK( nb.isFull(), FALSE );
/* Fill a buffer with three lines, piecemeal */
const char *vectors[NVECTORS] = { "Hi", "there", "cutie" };
bytesused=0;
for (i=0; i < NVECTORS; i++) {
err = nb.put(vectors[i], 1);
bytesused++;
if (err) {
printf("Failed at line %d: %s\n", __LINE__, strerror(err));
exit(1);
}
err = nb.put(vectors[i]+1, strlen(vectors[i])-1);
bytesused+=strlen(vectors[i])-1;
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
if (i & 1) {
err = nb.put("\r\n", 2);
bytesused+=2;
} else {
err = nb.put("\n", 1);
bytesused++;
}
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
}
/* Sanity checks */
CHECK( nb.bytesUsed(), bytesused );
CHECK( nb.contigBytesUsed(), bytesused ); /* assume no wrap yet */
CHECK( nb.bytesFree(), nbbio_BUFLEN-1 - bytesused );
CHECK( nb.contigBytesFree(), nbbio_BUFLEN-1 - bytesused );
CHECK( nb.isEmpty(), FALSE );
CHECK( nb.isFull(), FALSE );
/* make sure we can get them out */
for (i=0; i < NVECTORS; i++) {
err = nb.readline(buf, sizeof(buf));
if (err) {
printf("Failed at line %d; can't read line %d\n", __LINE__, i);
exit(1);
}
if (strcmp(buf, vectors[i])) {
printf("Bad data; failed at line %d\n", __LINE__);
exit(1);
}
}
/* Sanity checks */
CHECK( nb.bytesUsed(), 0 );
CHECK( nb.contigBytesUsed(), 0 );
CHECK( nb.bytesFree(), nbbio_BUFLEN-1 );
CHECK( nb.contigBytesFree(), nbbio_BUFLEN - bytesused );
CHECK( nb.isEmpty(), TRUE ); /* assume last line ended in \n only */
CHECK( nb.isFull(), FALSE );
/* Fill it to the brim with one long line */
for (i=0; i<nbbio_BUFLEN-1; i++)
buf2[i] = 32 + (i & 63);
err = nb.put(buf2, nbbio_BUFLEN-1);
if (err) {
printf("Failed at line %d; can't put big line\n", __LINE__);
exit(1);
}
/* Sanity checks */
CHECK( nb.bytesUsed(), nbbio_BUFLEN-1 );
CHECK( nb.contigBytesUsed(), nbbio_BUFLEN-bytesused ); /* -old m_putTo */
CHECK( nb.bytesFree(), 0 );
CHECK( nb.contigBytesFree(), 0 );
CHECK( nb.isEmpty(), FALSE );
CHECK( nb.isFull(), TRUE );
for (i=0; i<nbbio_BUFLEN-1; i++) {
if (nb.isEmpty()) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
c = nb.readc();
int wanted = (32 + (i & 63));
if (c != wanted) {
printf("Failed at line %d: bad value; i = %d, wanted %d, got %d\n", __LINE__, i, wanted, c);
exit(1);
}
}
/* Sanity checks */
CHECK( nb.bytesUsed(), 0 );
CHECK( nb.contigBytesUsed(), 0 );
CHECK( nb.bytesFree(), nbbio_BUFLEN-1 );
CHECK( nb.contigBytesFree(), nbbio_BUFLEN-bytesused+1 );
CHECK( nb.isEmpty(), TRUE );
CHECK( nb.isFull(), FALSE );
/* File I/O */
int wfd = open("nbbiotest.dat", O_CREAT|O_TRUNC|O_RDWR, 0664);
if (wfd < 0) {
printf("Failed at line %d; can't create nbbiotest.dat\n", __LINE__);
perror("open");
exit(1);
}
bytesused=0;
for (i=0; i < NVECTORS; i++) {
err = nb.put(vectors[i], 1);
bytesused++;
if (err) {
printf("Failed at line %d: %s\n", __LINE__, strerror(err));
exit(1);
}
err = nb.put(vectors[i]+1, strlen(vectors[i])-1);
bytesused+=strlen(vectors[i])-1;
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
if (i & 1) {
err = nb.put("\r\n", 2);
bytesused+=2;
} else {
err = nb.put("\n", 1);
bytesused++;
}
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
}
err = nb.flushTo(wfd);
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
close(wfd);
/* Sanity checks */
CHECK( nb.bytesUsed(), 0 );
CHECK( nb.contigBytesUsed(), 0 );
CHECK( nb.bytesFree(), nbbio_BUFLEN-1 );
CHECK( nb.contigBytesFree(), nbbio_BUFLEN - 2 * bytesused + 1);
CHECK( nb.isEmpty(), TRUE );
CHECK( nb.isFull(), FALSE );
int rfd = open("nbbiotest.dat", O_RDONLY);
if (rfd < 0) {
printf("Failed at line %d; can't open nbbiotest.dat\n", __LINE__);
perror("open");
exit(1);
}
err = nb.fillFrom(rfd);
if (err) {
printf("Failed at line %d\n", __LINE__);
exit(1);
}
/* make sure we can get them out */
for (i=0; i < NVECTORS; i++) {
err = nb.readline(buf, sizeof(buf));
if (err) {
printf("Failed at line %d; can't read line %d\n", __LINE__, i);
exit(1);
}
if (strcmp(buf, vectors[i])) {
printf("Bad data; failed at line %d\n", __LINE__);
exit(1);
}
}
/* Check "fillFrom when # of bytes readable == # of contig bytes left",
* which could cause a premature EOF due to 2nd read() returning 0
* Thanks to Tom Emersoni <TOMEMERSON at ms.globalpay.com> for finding that one
*/
/* 1. Create a file with a single line of C's, len nbbio_BUFLEN/2 (inc CRLF) */
wfd = open("nbbiotest.dat", O_CREAT|O_TRUNC|O_RDWR, 0664);
if (wfd < 0) {
printf("Failed at line %d; can't create nbbiotest.dat\n", __LINE__);
perror("open");
exit(1);
}
memset(buf, 'C', nbbio_BUFLEN/2 - 2);
buf[nbbio_BUFLEN/2 - 2] = '\r';
buf[nbbio_BUFLEN/2 - 1] = '\n';
int nwrite = write(wfd, buf, nbbio_BUFLEN/2);
CHECK(nbbio_BUFLEN/2, nwrite);
err = close(wfd);
CHECK(err, 0);
/* 2. Rotate buf so there's two bytes of free space at the beginning,
* then fill buf with a line of B's until there's exactly nbbio_BUFLEN/2 contigFree
*/
nb.init();
CHECK(nb.contigBytesFree(), nbbio_BUFLEN-1);
CHECK(nb.bytesFree(), nbbio_BUFLEN-1);
nb.put("AZ", 2);
c = nb.readc();
CHECK(c, 'A');
c = nb.readc();
CHECK(c, 'Z');
CHECK(nb.contigBytesFree(), nbbio_BUFLEN-2); /* because putTo is 2 */
CHECK(nb.bytesFree(), nbbio_BUFLEN-1);
while (nb.contigBytesFree() > nbbio_BUFLEN/2 + 2) {
nb.put("B", 1);
CHECK(nb.contigBytesFree(), nb.bytesFree()-1);
}
nb.put("\r\n", 2);
CHECK(nb.contigBytesFree(), nbbio_BUFLEN/2);
CHECK(nb.bytesFree(), nbbio_BUFLEN/2+1);
/* 3. Fill buf from the file. Make sure it doesn't barf because
* we hit EOF.
*/
rfd = open("nbbiotest.dat", O_RDONLY);
if (rfd < 0) {
printf("Failed at line %d; can't open nbbiotest.dat\n", __LINE__);
perror("open");
exit(1);
}
err = nb.fillFrom(rfd);
CHECK(err, 0);
close(rfd);
/* 4. Make sure we can read both lines. */
memset(buf2, 255, sizeof(buf2));
err = nb.readline(buf2, sizeof(buf2));
CHECK(err, 0);
len = strlen(buf2);
CHECK(len, nbbio_BUFLEN/2 - 2 - 2);
CHECK(buf2[0], 'B'); /* first line all B's */
err = nb.readline(buf2, sizeof(buf2));
CHECK(err, 0);
CHECK(buf2[0], 'C'); /* 2nd line all C's */
err = memcmp(buf, buf2, nbbio_BUFLEN/2 - 2);
if (err) {
printf("got:");
dumpBuf(buf2, nbbio_BUFLEN/2-2);
printf("wanted:");
dumpBuf(buf, nbbio_BUFLEN/2-2);
}
CHECK(err, 0);
len = strlen(buf2);
if (len != nbbio_BUFLEN/2 - 2) {
printf("got:");
dumpBuf(buf2, len);
printf("wanted:");
dumpBuf(buf, nbbio_BUFLEN/2-2);
}
CHECK(len, nbbio_BUFLEN/2 - 2);
/* Whew. */
unlink("nbbiotest.dat");
printf("Test passed\n");
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1