#include "io.h"
#include <stdio.h>
#include <stdlib.h>

struct io_file {
	FILE *fp;
	int pos;
};

struct io_file *io_open(const char *fname) {
	struct io_file * const f = malloc(sizeof *f);
	if (NULL == f) return NULL;
	f->fp = fopen(fname,"rb+");
	if (NULL == f->fp) f->fp = fopen(fname,"wb+");
	if (NULL == f->fp) {
		perror(fname);
		free(f);
		return NULL;
	}
	f->pos = -1;
	return f;
}

void io_close(struct io_file *f) {
	if (NULL != f) {
		fclose(f->fp);
		free(f);
	}
}

int io_out(struct io_file *f,int pos,const void *o,int len) {
	if (NULL == f || -1 == pos) return -1;

        if (pos != f->pos && fseek(f->fp,pos,SEEK_SET)) {
                perror("seek");
		return -1;
        }

        if (NULL != o && 1 != fwrite(o,len,1,f->fp)) {
                perror("write");
		return -1;
        }

        return f->pos = pos + len;
}

int io_in(struct io_file *f,int pos,void *i,int len) {
	if (NULL == f || -1 == pos) return -1;

	if (pos != f->pos && fseek(f->fp,pos,SEEK_SET)) {
		perror("seek");
		return -1;
	}

	if (NULL != i && 1 != fread(i,len,1,f->fp)) {
		if (feof(f->fp))
			fputs("read: unexpected EOF\n",stderr); /* TODO */
		else
			perror("read");
		return -1;
	}

	return f->pos = pos + len;
}
