#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sio_fs.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

void store_pattern (char *, char, int, int);

int
main(int argc, char **argv)
{
	sio_file_io_list_t fl[10];
	sio_file_io_list_t fl2[10];
	sio_mem_io_list_t ml[10];
	sio_mem_io_list_t ml2[10];
	sio_transfer_len_t xfer;
	sio_async_handle_t handles[2];
	sio_return_t rv;
	sio_count_t ind;
	sio_async_status_t status;
	void *buf;
	char *p;
	int bsize;
	int fd, fd1, nb;

	if (argc !=2) {
	  fprintf(stderr, "usage: %s buffer-size(KB) \n", argv[0]);
          exit(1);
        } else { 
          bsize = atoi(argv[1]);
        }

	rv = sio_open(&fd, "newfile",  SIO_MODE_CREATE |  SIO_MODE_WRITE |
		      SIO_MODE_READ, NULL , 0);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_open: %s\n", sio_error_string(rv));
		exit (1);
	}


	fl[0].offset = 0;
	fl[0].size = bsize*1024;
	fl[0].stride = 0;
	fl[0].element_cnt = 1;

	fl2[0].offset = 0;
	fl2[0].size = bsize*1024;
	fl2[0].stride = 0;
	fl2[0].element_cnt = 1;

	buf = (void *) malloc(bsize*1024);
	if ( buf == NULL ) {
	       fprintf(stderr,"malloc failed\n");
	       exit(1);
	}
	
	fd1 = open("/usr/tmp/text.db", O_RDONLY, 0);
	nb = read(fd1, buf, bsize*1024);
	if (nb !=1024*bsize) {
	 fprintf(stderr, "read failed !\n");
	  exit(1);
	}

	ml[0].addr = buf;
	ml[0].size = bsize*1024;
	ml[0].stride = 0;
	ml[0].element_cnt = 1;

	ml2[0].addr = buf;
	ml2[0].size = bsize*1024;
	ml2[0].stride = 0;
	ml2[0].element_cnt = 1;

#if 1 /* test synchronous calls */

	rv = sio_sg_write(fd, fl, 1, ml, 1, &xfer);
	printf("sio_sg_write: rv = %d, xfer = %ld\n", rv, xfer);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_sg_write: %s\n", sio_error_string(rv));
	}

	memset(buf,'0',bsize*1024); 
	rv = sio_sg_read(fd, fl2, 1, ml2, 1, &xfer);
	printf("sio_sg_read: rv = %d, xfer = %ld\n", rv, xfer);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_sg_read: %s\n", sio_error_string(rv));
	}
	
	p = (char *) buf;
	p[bsize*1024-1]='\0';
	fprintf(stderr,"file contents:\n %s \n", p);
	
	rv = sio_close(fd);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_close: %s\n", sio_error_string(rv));
		goto bad;
	}

#else /* test async */
	
	/* write pattern to file */
	rv = sio_sg_write(fd, fl, 1, ml, 1, &xfer);
	printf("sio_sg_write: rv = %d, xfer = %ld\n", rv, xfer);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_sg_write: %s\n", sio_error_string(rv));
	}

	memset(buf,'0',1024); 
	rv = sio_async_sg_read(fd, fl2, 1, ml2, 1, &handles[0]);
	rv = sio_async_sg_read(fd, fl2, 1, ml2, 1, &handles[1]);
	do {
		rv = sio_async_status_any(handles, 2, &ind, &status,
		    SIO_ASYNC_NONBLOCKING);
	} while (rv != SIO_SUCCESS);
	if (rv == SIO_SUCCESS)
		handles[ind] = SIO_ASYNC_DUMMY_HANDLE;
	printf("sio_async_status_any ret: ind = %d, count = 0x%lx, status = %d\n", ind, status.count, status.status);
	do {
		rv = sio_async_status_any(handles, 2, &ind, &status,
		    SIO_ASYNC_NONBLOCKING);
	        printf("poll returns: %s\n", sio_error_string(rv));
	} while (rv != SIO_SUCCESS);
	printf("sio_async_status_any ret: ind = %d, count = 0x%lx, status = %d\n", ind, status.count, status.status);

	p = (char *) buf;
	p[bsize*1024-1]='\0';
	fprintf(stderr,"file contents:\n %s \n", p);

	rv = sio_close(fd);
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_close: %s\n", sio_error_string(rv));
		goto bad;
	}

#endif

#if 0	
	rv = sio_unlink("/tmp/bar");
	if (rv != SIO_SUCCESS) {
		fprintf(stderr, "sio_unlink: %s\n", sio_error_string(rv));
		goto bad;
	}
#endif
	
	free(buf);
	exit(0);

      bad: 
	if (buf !=NULL)
	  free(buf);
	exit(1);
}

/* store a pattern in a character buffer. The pattern consists
   of successive contiguous runs of alphabetic characters. Each
   run is of length region size. Used to test scatter gather ops.
*/

void store_pattern (char *buf, char sc, int region_size, int tot_size)
{
  int i;
  char c;

  for (i=0; i<tot_size; i++) {
    c = sc + (i / region_size);
    buf[i] = c;
  }

}


