diff --git a/Misc/CREDITS b/Misc/CREDITS new file mode 100644 index 00000000..b2528cdc --- /dev/null +++ b/Misc/CREDITS @@ -0,0 +1,16 @@ +The following files were unashamedly borrowed from other projects: + +zfstream.hxx +zfstream.cxx + zlib/contrib/iostream + +stopwatch.hxx was (blitz/time.h) + blitz + +Some modifications have been made to fit in with the FlightGear scheme of things. + +As far as I'm aware they are all covered by GNU's licensing agreements. + +Many thanks to their respective authors. + +Bernie Bright (bbright@c031.aone.net.au) diff --git a/Misc/Makefile.am b/Misc/Makefile.am new file mode 100644 index 00000000..56a51a8f --- /dev/null +++ b/Misc/Makefile.am @@ -0,0 +1,9 @@ +## Process this file with automake to produce Makefile.in + +noinst_LIBRARIES = libMisc.a + +libMisc_a_SOURCES = \ + fgstream.cxx \ + zfstream.cxx + +INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib diff --git a/Misc/fgstream.cxx b/Misc/fgstream.cxx new file mode 100644 index 00000000..32c69192 --- /dev/null +++ b/Misc/fgstream.cxx @@ -0,0 +1,119 @@ +// zlib input file stream wrapper. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#include // isspace() +#include "fgstream.hxx" + +//----------------------------------------------------------------------------- +// +// Open a possibly gzipped file for reading. +// +fg_gzifstream::fg_gzifstream( const string& name, int io_mode ) +{ + open( name, io_mode ); +} + +//----------------------------------------------------------------------------- +// +// Open a possibly gzipped file for reading. +// If the initial open fails and the filename has a ".gz" extension then +// remove the extension and try again. +// If the initial open fails and the filename doesn't have a ".gz" extension +// then append ".gz" and try again. +// +void +fg_gzifstream::open( const string& name, int io_mode ) +{ + gzstream.open( name.c_str(), io_mode ); + if ( gzstream.fail() ) + { + string s = name; + if ( s.substr( s.length() - 3, 3 ) == ".gz" ) + { + // remove ".gz" suffix + s.erase( s.length() - 3, 3 ); + } + else + { + // Append ".gz" suffix + s += ".gz"; + } + + // Try again. + gzstream.open( s.c_str(), io_mode ); + } +} + +//----------------------------------------------------------------------------- +// +// Remove whitespace characters from the stream. +// +istream& +fg_gzifstream::eat_whitespace() +{ + char c; + while ( gzstream.get(c) ) + { + if ( ! isspace( c ) ) + { + // put pack the non-space character + gzstream.putback(c); + break; + } + } + return gzstream; +} + +//----------------------------------------------------------------------------- +// +// Remove whitspace chatacters and comment lines from a stream. +// +istream& +fg_gzifstream::eat_comments() +{ + for (;;) + { + // skip whitespace + eat_whitespace(); + + char c; + gzstream.get( c ); + if ( c != '#' ) + { + // not a comment + gzstream.putback(c); + break; + } + + // skip to end of line. + while ( gzstream.get(c) && c != '\n' ) + ; + } + return gzstream; +} + + +// $Log$ +// Revision 1.1 1998/09/01 19:06:29 curt +// Initial revision. +// diff --git a/Misc/fgstream.hxx b/Misc/fgstream.hxx new file mode 100644 index 00000000..f9f74b6a --- /dev/null +++ b/Misc/fgstream.hxx @@ -0,0 +1,94 @@ +// zlib input file stream wrapper. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#ifndef _FGSTREAM_HXX +#define _FGSTREAM_HXX + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "zfstream.hxx" + +//----------------------------------------------------------------------------- +// +// Envelope class for gzifstream. +// +class fg_gzifstream +{ +public: + // + fg_gzifstream(); + + // Attempt to open a file with and without ".gz" extension. + fg_gzifstream( const string& name, + int io_mode = ios::in|ios::binary ); + + // Attempt to open a file with and without ".gz" extension. + void open( const string& name, + int io_mode = ios::in|ios::binary ); + + // Return the underlying stream. + istream& stream() { return gzstream; } + + // Check stream state. + bool operator ! () const { return !gzstream; } + + // Check for end of file. + bool eof() const { return gzstream.eof(); } + + // Remove whitespace from stream. + // Whitespace is as defined by isspace(). + istream& eat_whitespace(); + + // Removes comments and whitespace from stream. + // A comment is any line starting with '#'. + istream& eat_comments(); + + // Read one character from stream. + istream& get( char& c ) { return gzstream.get(c); } + + // Put a character back into the input buffer. + istream& putback( char c ) { return gzstream.putback(c); } + +private: + // The underlying compressed data stream. + gzifstream gzstream; + +private: + // Not defined! + fg_gzifstream( const fg_gzifstream& ); +}; + +#endif /* _FGSTREAM_HXX */ + +// $Log$ +// Revision 1.1 1998/09/01 19:06:29 curt +// Initial revision. +// diff --git a/Misc/stopwatch.hxx b/Misc/stopwatch.hxx new file mode 100644 index 00000000..400c08fc --- /dev/null +++ b/Misc/stopwatch.hxx @@ -0,0 +1,122 @@ +/*************************************************************************** + * stopwatch.hxx Timer class, for use in benchmarking + * + * Based on blitz/Timer.h + * + * $Id$ + * + * Copyright (C) 1997,1998 Todd Veldhuizen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Suggestions: blitz-suggest@cybervision.com + * Bugs: blitz-bugs@cybervision.com + * + * For more information, please see the Blitz++ Home Page: + * http://seurat.uwaterloo.ca/blitz/ + * + *************************************************************************** + * $Log$ + * Revision 1.1 1998/09/01 19:06:30 curt + * Initial revision. + * + * Revision 1.4 1998/03/14 00:04:47 tveldhui + * 0.2-alpha-05 + * + * Revision 1.3 1997/07/16 14:51:20 tveldhui + * Update: Alpha release 0.2 (Arrays) + * + * Revision 1.2 1997/01/24 14:42:00 tveldhui + * Periodic RCS update + * + */ + +// This class is not portable to non System V platforms. +// It will need to be rewritten for Windows, NT, Mac. +// NEEDS_WORK + +#ifndef _STOPWATCH_HXX +#define _STOPWATCH_HXX + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(__linux__) && ! defined(HAVE_GETRUSAGE) +# define HAVE_GETRUSAGE +#endif + +#ifdef HAVE_GETRUSAGE + #include +#else + #include +#endif + +class StopWatch { + +public: + StopWatch() + { +// state_ = uninitialized; + } + + void start() + { +// state_ = running; + t1_ = systemTime(); + } + + void stop() + { + t2_ = systemTime(); +// BZPRECONDITION(state_ == running); +// state_ = stopped; + } + + double elapsedSeconds() + { +// BZPRECONDITION(state_ == stopped); + return t2_ - t1_; + } + +private: + StopWatch(StopWatch&) { } + void operator=(StopWatch&) { } + + double systemTime() + { +#ifdef HAVE_GETRUSAGE + getrusage(RUSAGE_SELF, &resourceUsage_); + double seconds = resourceUsage_.ru_utime.tv_sec + + resourceUsage_.ru_stime.tv_sec; + double micros = resourceUsage_.ru_utime.tv_usec + + resourceUsage_.ru_stime.tv_usec; + return seconds + micros/1.0e6; +#else + return clock() / (double) CLOCKS_PER_SEC; +#endif + } + +// enum { uninitialized, running, stopped } state_; + +#ifdef HAVE_GETRUSAGE + struct rusage resourceUsage_; +#endif + + double t1_, t2_; +}; + +#endif // _STOPWATCH_HXX + diff --git a/Misc/strutils.cxx b/Misc/strutils.cxx new file mode 100644 index 00000000..4c2f520e --- /dev/null +++ b/Misc/strutils.cxx @@ -0,0 +1,74 @@ +// String utilities. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "strutils.hxx" + +// +string +trimleft( const string& s, const string& trimmings ) +{ + string result; + string::size_type pos = s.find_first_not_of( trimmings ); + if ( pos != string::npos ) + { + result.assign( s.substr( pos ) ); + } + + return result; +} + +// +string +trimright( const string& s, const string& trimmings ) +{ + string result; + + string::size_type pos = s.find_last_not_of( trimmings ); + if ( pos == string::npos ) + { + // Not found, return the original string. + result = s; + } + else + { + result.assign( s.substr( 0, pos+1 ) ); + } + + return result; +} + +// +string +trim( const string& s, const string& trimmings ) +{ + return trimright( trimleft( s, trimmings ), trimmings ); +} + +// $Log$ +// Revision 1.1 1998/09/01 19:06:30 curt +// Initial revision. +// diff --git a/Misc/strutils.hxx b/Misc/strutils.hxx new file mode 100644 index 00000000..1dba49e3 --- /dev/null +++ b/Misc/strutils.hxx @@ -0,0 +1,61 @@ +// String utilities. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#ifndef STRUTILS_H +#define STRUTILS_H + +#include +#include + +// Default characters to remove. +const string whitespace = " \n\r\t"; + +// Returns a string with trailing characters removed. +string trimleft( const string& s, const string& trimmings = whitespace ); + +// Returns a string with leading characters removed. +string trimright( const string& s, const string& trimmings = whitespace ); + +// Returns a string with leading and trailing characters removed. +string trim( const string& s, const string& trimmings = whitespace ); + +//----------------------------------------------------------------------------- + +inline double +atof( const string& str ) +{ + return ::atof( str.c_str() ); +} + +inline int +atoi( const string& str ) +{ + return ::atoi( str.c_str() ); +} + +#endif // STRUTILS_H + +// $Log$ +// Revision 1.1 1998/09/01 19:06:31 curt +// Initial revision. +// diff --git a/Misc/zfstream.cxx b/Misc/zfstream.cxx new file mode 100644 index 00000000..3a52ea31 --- /dev/null +++ b/Misc/zfstream.cxx @@ -0,0 +1,329 @@ + +#include +#include "Misc/zfstream.hxx" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p; + memset(char_mode,'\0',10); + p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( short comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( short comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() { + + return &buffer; + +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/Misc/zfstream.hxx b/Misc/zfstream.hxx new file mode 100644 index 00000000..4748090c --- /dev/null +++ b/Misc/zfstream.hxx @@ -0,0 +1,130 @@ + +#ifndef _zfstream_hxx +#define _zfstream_hxx + +#include + +#include "zlib/zlib.h" +#include "Include/fg_stl_config.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( short comp_level ); + int setcompressionstrategy( short comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + +// friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + + gzfilebuf *rdbuf(); + +private: + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator << _FG_NULL_TMPL_ARGS (gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, + const gzomanip &m) { + return (*m.func)(s, m.val); + +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) { + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif // _zfstream_hxx