home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
umass_foa.tar
/
mdt_NEW
/
ISRhdrs
/
Isrstream.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-11
|
17KB
|
759 lines
#include <Token.h>
#include <Isrstream.h>
/*******************************************************************
* Isrostream *
* Isrostream is a subclass of ofstream that extends ofstream to *
* binary as well as ASCII files. Since we are working on UNIX, the *
* underlying file types are the same, the question is whether a *
* float, for example, is printed as four chars or a string of *
* decimal chars (e.g. "0.356786"). ASCII files are written as dec. *
* chars, binary as the more compact but unreadable four char *
* sequence. The same distinctions hold for ints, doubles, etc. *
* *
* The only oddity is that binary streams are set up to print *
* nothing if handed a constant char *, but to print the character *
* string if handed a regular char *. (Constant strings are usually *
* padding for human eyes, and since they are constant they do need *
* to be stored: the reading program can re-insert them.) *
* *
* This file is organized as: *
* 1) initialization functions *
* 2) primitive datatype <<'s *
*******************************************************************/
static int supply_warnings = 1;
/* A helper function to verify legal format and type values.
Returns 0 if everything is OK, -1 if illegal format, -2
if illegal type. */
int check_format_and_type(int format, int type)
{
if ((format != BINARY) && (format != ASCII)) {
cerr << "Unknown stream format: " << format << endl;
return(-1);
}
if ((type != ISR) && (type != FORIEGN)) {
cerr << "Unknown stream type: " << type << endl;
return(-2);
}
return(0);
}
Isrostream::Isrostream(int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
{
/* check that stream_type is valid */
if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
format = stream_format;
type = stream_type;
name = NULL;
state = Closed;
str = new ofstream;
}
Isrostream::Isrostream(char *filename, int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
{
/* check that stream_type is valid */
if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
format = stream_format;
type = stream_type;
name = filename;
str = new ofstream(filename, ios::out);
state = Open;
}
Isrostream::~Isrostream()
{
str->close();
delete str;
}
Isristream::Isristream(int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
{
/* check that stream_type is valid */
if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
format = stream_format;
type = stream_type;
name = NULL;
str = new ifstream;
state = Closed;
tokentype_table = NULL;
fileVersion = 0;
byteSwapNeeded = ISR_FALSE;
}
Isristream::Isristream(char *filename, int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
{
/* check that stream_type is valid */
if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
format = stream_format;
type = stream_type;
tokentype_table = NULL;
name = filename;
str = new ifstream(filename, ios::in);
state = Open;
fileVersion = 0;
byteSwapNeeded = ISR_FALSE;
}
Isristream::~Isristream()
{
str->close();
delete str;
}
/*************************************************************/
void Isristream::read_tokentype_table(int tokentype_count, int max_tokentype)
{
int i, index;
char *namestring;
tokentype_table = new TypeDirectory(max_tokentype);
for(i=0; i < tokentype_count; i++) {
*this >> index;
namestring = read_string(MAX_TOKENTYPE_NAME_LENGTH);
if ((0 > index) || (index > max_tokentype)) {
cerr << "tokentype index out of bounds\n";
exit(-1);
}
if (namestring[0] == '\0') {
cerr << "unable to read tokentype name\n";
exit(-1);
}
if (0 > tokentype_table->add_entry(index, namestring)) {
cerr << "file contains tokentype " << &namestring << " not otherwise known to system\n";
exit(-1);
}
}
}
/*************************************************************/
Isrostream& operator << (Isrostream& os, const short val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(short); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const unsigned short val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned short); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const int val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(int); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const unsigned int val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned int); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const long val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(long); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const unsigned long val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned long); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const float val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(float); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const double val)
{
if (os.format == ASCII) {
*os.str << val;
}
else {
char *ptr;
unsigned int i;
for (i = 0, ptr = (char *)&val; i < sizeof(double); i++, ptr++) {
os.str->put(*ptr);
}
}
return os;
}
Isrostream& operator << (Isrostream& os, const char *string)
{
if (os.format == ASCII) {
*os.str << string;
}
/* if stream is binary, do nothing! */
return os;
}
Isrostream& operator << (Isrostream& os, const char ch)
{
os.str->put(ch);
return os;
}
/* for printing strings, even to binary files. */
void Isrostream::print_string(char *string)
{
*str << string;
if (format == ASCII) *str << " ";
else str->put('\0');
}
int operator! (Isrostream& os)
{
return !(*os.str);
}
Isrostream& Isrostream::write(const char *s, int n)
{
str->write(s, n);
return *this;
}
void Isrostream::open (char *filename, int mode)
{
if (state == Closed) {
name = filename;
str->open(filename, mode);
state = Open;
}
}
void Isrostream::close()
{
if (state == Open) {
str->close();
state = Closed;
}
}
/************************************************************/
char *Isristream::read_string(int max_size)
{
char *string = (char *)malloc(max_size * sizeof(char));
if (NULL == string) {
cerr << "Error: unable to allocate memory for string.\n";
return NULL;
}
if (format == ASCII) {
*str >> string; /* add limiter against overflow */
return string;
}
else {
for (int i=0; i < max_size; i++) {
string[i] = str->get();
if (string[i] == '\0') return string;
}
cerr << "string longer than alloted length\n";
return NULL;
}
}
Isristream& operator >> (Isristream& is, short& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(short)-1;
i < sizeof(short); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(short); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, unsigned short& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(unsigned short)-1;
i < sizeof(unsigned short); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned short); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, int& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(int)-1; i < sizeof(int); i++, ptr++) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(int); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, unsigned int& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(unsigned int)-1; i < sizeof(unsigned int); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned int); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, long& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(long)-1; i < sizeof(long); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(long); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, unsigned long& val)
{
if (is.format == ASCII) {
*is.str >> val;
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(unsigned long)-1; i < sizeof(unsigned long); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(unsigned long); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
/* read_cstring : a helper function that returns True and advances the filepointer
if the next item in the file is cstring, but doesn't alter the file otherwise.
It is different from using >> to read a constant string because 1) it does not
print warnings and 2) it first clears the stream state (assuming that it had
failed trying to read a float) and then returns the resulting state. */
int Isristream::read_cstring (const char *cstring)
{
supply_warnings = 0;
str->clear();
*this >> cstring;
supply_warnings = 1;
return str->good();
}
Isristream& operator >> (Isristream& is, float& val)
{
if (!is) return is;
if (is.format == ASCII) {
*is.str >> val;
if (is.str->fail()) {
if (is.str->bad()) return is;
if (is.read_cstring("NaN")) val = (float) Token::NaN_Value.d;
else if (is.read_cstring("Infinity")) val = (float) Token::PosInf_Value.d;
else if (is.read_cstring("-Infinity")) val = (float) Token::NegInf_Value.d;
}
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(float)-1; i < sizeof(float); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(float); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, double& val)
{
if (is.format == ASCII) {
*is.str >> val;
if (is.str->fail()) {
if (is.str->bad()) return is;
if (is.read_cstring("NaN")) val = Token::NaN_Value.d;
else if (is.read_cstring("Infinity")) val = Token::PosInf_Value.d;
else if (is.read_cstring("-Infinity")) val = Token::NegInf_Value.d;
}
}
else {
char *ptr;
unsigned int i;
if (is.byteSwapNeeded)
{
for (i = 0, ptr = ((char *)&val)+sizeof(double)-1; i < sizeof(double); i++, ptr--) {
is.str->get(*ptr);
}
} else
{
for (i = 0, ptr = (char *)&val; i < sizeof(double); i++, ptr++) {
is.str->get(*ptr);
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, const char *string)
{
int ctr;
if (!is) return is;
if (is.format == ASCII) {
char *strptr;
char ch;
/* strip off leading whitespace from constant string */
strptr = (char *)string;
while(isspace(*strptr)) strptr++;
if (*strptr == '\0') return is;
/* strip off leading whitespace from file */
ch = is.str->get();
while (isspace(ch))
ch = is.str->get();
if (ch == EOF) return is;
is.str->putback(ch);
/* compare constant and I/O stream strings */
for(ctr = 0; '\0' != *strptr; strptr++, ctr++) {
ch = is.str->get();
if (ch != *strptr) {
is.str->putback(ch);
for (; ctr > 0; ctr--) {
strptr--;
is.str->putback(*strptr);
}
if (supply_warnings) {
cerr << "warning: ASCII input did not match constant string\n";
cerr << " looking for " << string << "; next char is " << ch << endl;
}
/* was ios::badbit */
is.str->clear(ios::failbit | is.str->rdstate() );
return is;
}
}
}
return is;
}
Isristream& operator >> (Isristream& is, const char ch)
{
char file_ch;
if (!is) return is;
if (isspace(ch)) return is;
/* strip off leading whitespace from file */
file_ch = is.str->get();
while (isspace(file_ch))
file_ch = is.str->get();
if (file_ch == EOF) return is;
if (file_ch != ch) {
cerr << "warning: ASCII input character did not match expected character\n";
cerr << " looking for " << ch << "; next char is " << file_ch << endl;
is.str->clear(ios::badbit | is.str->rdstate() );
}
return is;
}
int operator! (Isristream& is)
{
return !(*is.str);
}
void Isristream::putback(char ch)
{
str->putback(ch);
}
char Isristream::get()
{
return str->get();
}
Isristream& Isristream::read(char *s, int n)
{
str->read(s, n);
return *this;
}
void Isristream::open(char *filename, int mode)
{
if (state == Closed) {
name = filename;
str->open(filename, mode);
state = Open;
}
}
void Isristream::close ()
{
if (state == Closed) {
str->close();
state = Closed;
}
}
void Isristream::read_magic_header()
{
if (format == ASCII)
{
if (read_cstring(MagicASCII))
{
*this >> " fileVersion: ";
*this >> fileVersion;
} else
{
str->clear();
fileVersion = 0;
}
} else {
int ctr = 0;
char ch;
for (char *p = MagicB1;*p != '\0';p++,ctr++)
{
ch = str->get();
if (ch != *p) break;
}
if (*p != '\0')
{
str->putback(ch);
for (; ctr > 0; ctr--)
{
p--;
str->putback(*p);
}
fileVersion = 0;
byteSwapNeeded = ISR_FALSE;
return;
}
unsigned short int test;
byteSwapNeeded = ISR_FALSE;
*this >> test;
if (test == MagicB2) byteSwapNeeded = ISR_FALSE;
else byteSwapNeeded = ISR_TRUE;
*this >> fileVersion;
}
}
void Isrostream::write_magic_header()
{
if (format == ASCII)
{
*this << MagicASCII;
*this << " fileVersion: ";
*this << (unsigned short int)FileVersion;
*this << " ";
} else
{
unsigned short bsw_test = (unsigned short int)MagicB2,
fileVersion = (unsigned short int)FileVersion;
*str << MagicB1;
*this << bsw_test;
*this << fileVersion;
}
}
/**************************************************************
int match_stream_to_filename(Isrstream& stream, char *filename)
{
if (NULL != strstr(filename, ".isrb")) {
stream.format = BINARY;
stream.type = ISR;
return(0);
}
if (NULL != strstr(filename, ".isra")) {
stream.format = ASCII;
stream.type = ISR;
return(0);
}
if (NULL != strstr(filename, ".plane")) {
stream.format = BINARY;
stream.type = FORIEGN;
return(0);
}
if (NULL != strstr(filename, ".viff")) {
stream.format = BINARY;
stream.type = VIFF;
return(0);
}
return(-1);
}
*************************************************/