#ifdef PLAINMALLOC
#include <malloc.h>
#else
extern "C" {
#include <mmalloc.h>
}
#endif
#include <stdio.h>
#include <unistd.h>
#include <iostream.h>
#include <fstream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>

#ifndef SIZE
#define SIZE 2000
#endif

struct test {
	int i[SIZE] ;
	struct test * ptr;
};

void dump(struct test * tp) {
cout << "start dump" << endl;
while (tp) {
	cout << tp->i[0] << " " << tp->i[SIZE-1] << " " << endl;
	tp = tp->ptr;
}
cout << "end dump " << endl;
}

#ifdef PLAINMALLOC
#define mmalloc_attach(p1,p2) 0
#define mmalloc_detach(p1) 
#define mmalloc(p1,p2) malloc(p2)
#endif

int main(int argc, char ** argv) {
	
#ifndef PLAINMALLOC
	int fd = open("file.mmf",O_RDWR);
	cout << "fd : " << fd << endl;
#endif
	void * md = mmalloc_attach(fd,NULL);
	cout << "md : " << md << endl;

	struct test * newmem = 0;
	if ((argc > 1) && (argv[1][0] == 'r') ) {
#ifdef PLAINMALLOC
		cout << " cannot read using plain malloc" << endl;
		return 0;
#endif
		cout << "testing read" << endl;
		ifstream i("base");
		long l;
		i >> l;
		newmem = (test*) l;
	} else {
		cout << "testing write" << endl;
		newmem = (struct test*) mmalloc(md,sizeof(struct test) );
		assert(newmem);
		{ ofstream o("base"); o << (long) newmem; }
		newmem->i[0]=0;
		newmem->i[SIZE-1]=SIZE;
		newmem->ptr=0;
		test* tp = newmem;
		for (int i = 1; i < 10; i++) {
			cout << "allocation number: " << i << endl;
			test * ntp = (struct test*) mmalloc(md,sizeof(struct test) );
			cout << "allocation number: " << i << " done " << endl;
			assert(ntp);
			ntp->i[0] = i;
			ntp->i[SIZE-1] = SIZE + i;
			ntp->ptr = 0;
			tp->ptr = ntp;
			tp = ntp;
		}
	}
	cout << "newmem : " << newmem << endl;
	dump(newmem);
	mmalloc_detach(md);
#ifndef PLAINMALLOC
	close(fd);
#endif
	cout << "mtest finished " << endl;
	return 0;
}
