//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// fstream.c -- 
//
// Author           : Richard C. Bilson
// Created On       : Wed May 27 17:56:53 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Wed Feb 17 14:03:05 2016
// Update Count     : 76
//

#include "fstream"

extern "C" {
#include <stdio.h>
#include <stdlib.h>
}

struct ofstream {
	FILE *file;
};

#define IO_MSG "I/O error "

int fail( ofstream * os ) {
	return ferror( os->file );
} // fail

int flush( ofstream * os ) {
	return fflush( os->file );
} // flush

void open( ofstream ** os, const char * name, const char * mode ) {
	FILE *t = fopen( name, mode );
	if ( t == 0 ) {										// do not change unless successful
		perror( IO_MSG "open output" );
		exit( EXIT_FAILURE );
	} // if
	(*os)->file = t;
} // open

void close( ofstream * os ) {
	if ( os->file == stdout || os->file == stderr ) return;

	if ( fclose( os->file ) == EOF ) {
		perror( IO_MSG "close output" );
	} // if 
} // close

ofstream * write( ofstream * os, const char * data, streamsize_type size ) {
	if ( fail( os ) ) {
		fprintf( stderr, "attempt write I/O on failed stream\n" );
		exit( EXIT_FAILURE );
	} // if

	if ( fwrite( data, 1, size, os->file ) != size ) {
		perror( IO_MSG "write" );
		exit( EXIT_FAILURE );
	} // if
	return os;
} // write

static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_) };
ofstream *sout = &soutFile;
static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_) };
ofstream *serr = &serrFile;

//---------------------------------------

struct ifstream {
	FILE *file;
};

int fail( ifstream * is ) {
	return ferror( is->file );
} // fail

int eof( ifstream * is ) {
	return feof( is->file );
} // eof

ifstream * get( ifstream * is, int * data ) {
	if ( fscanf( is->file, "%d", data ) == EOF ) {
		if ( ferror( is->file ) ) {
			fprintf( stderr, "invalid int read\n" );
			exit( EXIT_FAILURE );
		} // if
	} // if
	return is;
} // read

ifstream * read( ifstream * is, char * data, streamsize_type size ) {
	if ( fail( is ) ) {
		fprintf( stderr, "attempt read I/O on failed stream\n" );
		exit( EXIT_FAILURE );
	} // if

	if ( fread( data, size, 1, is->file ) == 0 ) {
		perror( IO_MSG "read" );
		exit( EXIT_FAILURE );
	} // if
	return is;
} // read
  
ifstream *ungetc( ifstream * is, char c ) {
	if ( fail( is ) ) {
		fprintf( stderr, "attempt ungetc I/O on failed stream\n" );
		exit( EXIT_FAILURE );
	} // if

	if ( ungetc( c, is->file ) == EOF ) {
		perror( IO_MSG "ungetc" );
		exit( EXIT_FAILURE );
	} // if
	return is;
} // ungetc

void open( ifstream ** is, const char * name, const char * mode ) {
	FILE *t = fopen( name, mode );
	if ( t == 0 ) {										// do not change unless successful
		perror( IO_MSG "open input" );
		exit( EXIT_FAILURE );
	} // if
	(*is)->file = t;
} // open

void close( ifstream * is ) {
	if ( is->file == stdin ) return;

	if ( fclose( is->file ) == EOF ) {
		perror( IO_MSG "close input" );
	} // if 
} // close

static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
ifstream *sin = &sinFile;

// Local Variables: //
// tab-width: 4 //
// compile-command: "cfa fstream.c" //
// End: //
