#include "stdio.h"
#include "stdlib.h"
#include "sys/stat.h"
#include "sys/types.h"
#include "fcntl.h"

#define BLOCK_SIZE 512
#define BUF_SIZE   1024
#define TOTAL_BUF  (BUF_SIZE<<1)

typedef struct 
{
	char data[BUF_SIZE*2+1];
	int base,top;
	int length;
}buf_queue;

void do_dd(int infilefd ,int outfilefd ,int iperbytes ,int operbytes ,int cperbytes ,int totalblocks);
static inline int buf_empty(buf_queue *buf);
static inline int buf_length(buf_queue *buf);

int read2buf(int fd,buf_queue *buf,int size);
int writefrombuf(int fd,buf_queue *buf,int size);

int main(int argc,char **argv)
{
	int i;
	int iperbytes=BLOCK_SIZE,operbytes=BLOCK_SIZE,cperbytes=0;
	int totalblocks = -1,seekblocks=0,skipblocks=0;
	clock_t begin,end;
	off_t fbegin,fend;
	int noxfer=0;
	int infilefd,outfilefd;
	char *infile=NULL,*outfile=NULL,*iflags=NULL,*oflags=NULL;
	for(i=1;i (BUF_SIZE*2)) && (operbytes > (BUF_SIZE * 2)))
		iperbytes = operbytes = BUF_SIZE*2;
	else
	{
		if(iperbytes > BUF_SIZE)
			iperbytes = BUF_SIZE;
		if(operbytes > BUF_SIZE)
			operbytes = BUF_SIZE;
	}
	if((buf = (buf_queue* )malloc(sizeof(buf_queue)))==NULL)
		perror("malloc memory failed :");
	buf->base=buf->top=0;
	buf->length =0;
	readbytes = iperbytes;
	writebytes = operbytes;
	while(readbytes == iperbytes )
	{
		while((buf_empty(buf) >= iperbytes) && (readbytes == iperbytes) )
		{
			readbytes = read2buf(infilefd,buf,iperbytes);
		}
		while( buf_length(buf) >= operbytes && (writebytes == operbytes)) 
		{
			writefrombuf(outfilefd,buf,operbytes);
		}
	}
	writefrombuf(outfilefd,buf,buf_length(buf));	
}

inline int buf_empty(buf_queue *buf)
{
	return TOTAL_BUF-buf->length;
}

inline int buf_length(buf_queue *buf)
{
	return buf->length;
}

//read data into top and need the stuation is size < buf_empty;
int read2buf(int fd,buf_queue *buf,int size)
{
	int readbytes,totalread = 0,toread;
	if(size > (TOTAL_BUF-buf->top))
		toread = TOTAL_BUF - buf->top;
	else
		toread = size;
	while(toread)
	{
		if((readbytes = read(fd,buf->data+buf->top,toread)) == -1)
		{
			perror("read file error : ");
			return -1;
		}
		totalread += readbytes;
		buf->length +=readbytes;
		buf->top = (buf->top + readbytes) % TOTAL_BUF;
		if(readbytes != toread)
			return totalread;
		toread = size - toread;
		size = toread;
	}
	return totalread;
}

//read data into top and need the stuation is size < buf_empty;
int writefrombuf(int fd,buf_queue *buf,int size)
{
	int writebytes,totalwrite = 0,towrite;
	
	if(size > (TOTAL_BUF-buf->base))
		towrite = TOTAL_BUF - buf->base;
	else
		towrite = size;
	while(towrite)
	{
		if((writebytes = write(fd,buf->data+buf->base,towrite)) == -1)
		{
			perror("write error ");
			return -1;
		}
		totalwrite += writebytes;
		buf->length-=writebytes;
		buf->base = (buf->base + writebytes) % TOTAL_BUF;
		if(writebytes != towrite)
			return totalwrite;
		towrite = size - towrite;
		size = towrite;
	}
	return totalwrite;
}

/*
//read data into top and need the stuation is size < buf_empty;
int read2buf(int fd,char *buf,char *base,char *top,int size)
{
	int toread = 0,readbytes = 0;
	if(top > base)
	{
		toread = buf + BUF_SIZE - top
		if(size <= toread)
		{
			toread = size;
			readbytes = read(fd,top,toread);
			top = top + ((top - buf + readbytes) % BUF_SIZE)
			return readbytes;
		}else
		{
			readbytes = read(fd,top,toread);
			top = top + ((top - buf + readbytes) % BUF_SIZE)
			if(readbytes != toread)
				return readbytes;
			else
			{
				toread = size-toread;
				readbytes = read(fd,top,toread);
				top = top + ((top - buf + readbytes) % BUF_SIZE)
				return size-(toread - size)
			}
		}
	}
	else
	{
		readbytes = read(fd,top,size);
		top = top + ((top - buf + readbytes) % BUF_SIZE)
		return readbytes;
	}
}
*/