--- trunk/OOPSE-4/src/io/basic_ifstrstream.hpp 2005/04/11 21:58:05 2165
+++ trunk/OOPSE-4/src/io/basic_ifstrstream.hpp 2005/04/15 22:04:00 2204
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
*
* The University of Notre Dame grants you ("Licensee") a
@@ -60,271 +60,271 @@ namespace oopse {
namespace oopse {
-/**
- * @class basic_ifstrstream basic_ifstrstream.hpp "io/basic_ifstrstream.hpp"
- * @brief basic_ifstrstream class provides a stream interface to read data from files.
- *
In single mode, it falls back to ifstream. Don't need to read the whole file into memory.
- * In parallel mode, the master node will read the whole file and brocast it to other slave nodes.
- * After brocasting, every node will fall back to stringstream.
- *
- * @code
- * const int MAXLEN = 1024;
- * char buffer[MAXLEN];
- * ifstrstream in;
- * in.open("Shapes.frc");
- * if (in.is_open()) {
- * in.getline(buffer, MAXLEN);
- * }
- * in.close();
- * @endcode
- */
-template
-class basic_ifstrstream : public std::basic_istream<_CharT, _Traits> {
- public:
- //traits
- typedef _CharT char_type;
- typedef typename _Traits::int_type int_type;
- typedef typename _Traits::pos_type pos_type;
- typedef typename _Traits::off_type off_type;
- typedef _Traits traits_type;
+ /**
+ * @class basic_ifstrstream basic_ifstrstream.hpp "io/basic_ifstrstream.hpp"
+ * @brief basic_ifstrstream class provides a stream interface to read data from files.
+ * In single mode, it falls back to ifstream. Don't need to read the whole file into memory.
+ * In parallel mode, the master node will read the whole file and brocast it to other slave nodes.
+ * After brocasting, every node will fall back to stringstream.
+ *
+ * @code
+ * const int MAXLEN = 1024;
+ * char buffer[MAXLEN];
+ * ifstrstream in;
+ * in.open("Shapes.frc");
+ * if (in.is_open()) {
+ * in.getline(buffer, MAXLEN);
+ * }
+ * in.close();
+ * @endcode
+ */
+ template
+ class basic_ifstrstream : public std::basic_istream<_CharT, _Traits> {
+ public:
+ //traits
+ typedef _CharT char_type;
+ typedef typename _Traits::int_type int_type;
+ typedef typename _Traits::pos_type pos_type;
+ typedef typename _Traits::off_type off_type;
+ typedef _Traits traits_type;
- typedef std::basic_ios<_CharT, _Traits> _Basic_ios;
- typedef std::basic_istream<_CharT, _Traits> _Base;
+ typedef std::basic_ios<_CharT, _Traits> _Basic_ios;
+ typedef std::basic_istream<_CharT, _Traits> _Base;
#ifdef IS_MPI
- typedef std::basic_stringbuf<_CharT, _Traits, _Alloc> _Buf;
+ typedef std::basic_stringbuf<_CharT, _Traits, _Alloc> _Buf;
#else
- typedef std::basic_filebuf<_CharT, _Traits> _Buf;
+ typedef std::basic_filebuf<_CharT, _Traits> _Buf;
#endif
- static const int FileNotExists = -1;
- static const int FileIOError = -2;
+ static const int FileNotExists = -1;
+ static const int FileIOError = -2;
- public:
+ public:
- /** Constructs an object of class ifstream. */
- basic_ifstrstream()
- : std::basic_istream<_CharT, _Traits>(0),
- internalBuf_(), isRead(false) {
+ /** Constructs an object of class ifstream. */
+ basic_ifstrstream()
+ : std::basic_istream<_CharT, _Traits>(0),
+ internalBuf_(), isRead(false) {
- this->init(&internalBuf_);
- }
+ this->init(&internalBuf_);
+ }
- /**
- * Explicit constructor
- * @filename String containing the name of the file to be opened
- * @mode Flags describing the requested i/o mode for the file, default value is ios_base::in
- * @checkFilename Flags indicating checking the file name in parallel
- */
- explicit basic_ifstrstream(const char* filename, std::ios_base::openmode mode = std::ios_base::in, bool checkFilename = false)
- : std::basic_istream<_CharT, _Traits>(0),
- internalBuf_(), isRead(false) {
+ /**
+ * Explicit constructor
+ * @filename String containing the name of the file to be opened
+ * @mode Flags describing the requested i/o mode for the file, default value is ios_base::in
+ * @checkFilename Flags indicating checking the file name in parallel
+ */
+ explicit basic_ifstrstream(const char* filename, std::ios_base::openmode mode = std::ios_base::in, bool checkFilename = false)
+ : std::basic_istream<_CharT, _Traits>(0),
+ internalBuf_(), isRead(false) {
- this->init(&internalBuf_);
- isRead = internalOpen(filename, mode | std::ios_base::in, checkFilename);
- }
+ this->init(&internalBuf_);
+ isRead = internalOpen(filename, mode | std::ios_base::in, checkFilename);
+ }
- /**
- * virtual destructor will close the file(in single mode) and clear the stream buffer
- */
- ~basic_ifstrstream(){
- close();
- }
+ /**
+ * virtual destructor will close the file(in single mode) and clear the stream buffer
+ */
+ ~basic_ifstrstream(){
+ close();
+ }
- /**
- * Opens a file and associats a buffer with the specified file to perform the i/o operations
- * (single mode). Master reads a file and brocasts its content to the other slave nodes. After
- * brocasting, every nodes fall back to stringstream (parallel mode).
- * @filename String containing the name of the file to be opened
- * @mode Flags describing the requested i/o mode for the file
- * @checkFilename Flags indicating checking the file name in parallel
- */
- void open(const char* filename, std::ios_base::openmode mode = std::ios_base::in, bool checkFilename = false){
+ /**
+ * Opens a file and associats a buffer with the specified file to perform the i/o operations
+ * (single mode). Master reads a file and brocasts its content to the other slave nodes. After
+ * brocasting, every nodes fall back to stringstream (parallel mode).
+ * @filename String containing the name of the file to be opened
+ * @mode Flags describing the requested i/o mode for the file
+ * @checkFilename Flags indicating checking the file name in parallel
+ */
+ void open(const char* filename, std::ios_base::openmode mode = std::ios_base::in, bool checkFilename = false){
- if (!isRead ) {
- isRead = internalOpen(filename, mode, checkFilename);
- }
- }
+ if (!isRead ) {
+ isRead = internalOpen(filename, mode, checkFilename);
+ }
+ }
- /**
- * Tests if the stream is currently associated with a valid buffer.
- * @return true if a file has successfully been opened (single mode) or the whole file is read
- * and spreaded among all of the processors (parallel mode), otherwise false is returned
- */
- bool is_open ( ) {
+ /**
+ * Tests if the stream is currently associated with a valid buffer.
+ * @return true if a file has successfully been opened (single mode) or the whole file is read
+ * and spreaded among all of the processors (parallel mode), otherwise false is returned
+ */
+ bool is_open ( ) {
#ifdef IS_MPI
- return isRead;
+ return isRead;
#else
- //single version fall back to ifstream
- return internalBuf_.is_open();
+ //single version fall back to ifstream
+ return internalBuf_.is_open();
#endif
- }
+ }
- /**
- * In single mode, closes a file. The stream's file buffer is released from its association with
- * the currently open file. In parallel mode, clean the
- */
- void close() {
+ /**
+ * In single mode, closes a file. The stream's file buffer is released from its association with
+ * the currently open file. In parallel mode, clean the
+ */
+ void close() {
#ifndef IS_MPI
- //single version fall back to ifstream
- if (!internalBuf_.close())
- this->setstate(std::ios_base::failbit);
+ //single version fall back to ifstream
+ if (!internalBuf_.close())
+ this->setstate(std::ios_base::failbit);
#endif
- isRead = false;
- }
+ isRead = false;
+ }
- /**
- * Gets the stream buffer object associated with the stream
- * @return A pointer to the stream buffe object(filebuf in single mode, stringbuf in
- * parallel mode) associated with the stream.
- */
- _Buf* rdbuf() const{
- return static_cast<_Buf*>(&internalBuf_);
- }
+ /**
+ * Gets the stream buffer object associated with the stream
+ * @return A pointer to the stream buffe object(filebuf in single mode, stringbuf in
+ * parallel mode) associated with the stream.
+ */
+ _Buf* rdbuf() const{
+ return static_cast<_Buf*>(&internalBuf_);
+ }
- private:
+ private:
- /**
- * Internal function used to open the file
- * @return true if succesfully opens a file (single mode) or gets the file content (parallel mode)
- * otherwise return false
- * @filename String containing the name of the file to be opened
- * @mode Flags describing the requested i/o mode for the file
- * @todo use try - catch syntax to make the program more readable
- */
- bool internalOpen(const char* filename, std::ios_base::openmode mode, bool checkFilename){
+ /**
+ * Internal function used to open the file
+ * @return true if succesfully opens a file (single mode) or gets the file content (parallel mode)
+ * otherwise return false
+ * @filename String containing the name of the file to be opened
+ * @mode Flags describing the requested i/o mode for the file
+ * @todo use try - catch syntax to make the program more readable
+ */
+ bool internalOpen(const char* filename, std::ios_base::openmode mode, bool checkFilename){
#ifdef IS_MPI
- int commStatus;
- long fileSize;
- char* fbuf;
- int filenameLen;
- int diffFilename;
- int error;
- int myRank;
- int masterNode;
+ int commStatus;
+ long fileSize;
+ char* fbuf;
+ int filenameLen;
+ int diffFilename;
+ int error;
+ int myRank;
+ int masterNode;
- commStatus = MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
- masterNode = 0;
+ commStatus = MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
+ masterNode = 0;
- if (myRank == masterNode) {
+ if (myRank == masterNode) {
- if (checkFilename) {
+ if (checkFilename) {
- //check the filename is the same
- filenameLen = strlen(filename);
- commStatus = MPI_Bcast(&filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
- commStatus = MPI_Bcast((void*)filename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD);
+ //check the filename is the same
+ filenameLen = strlen(filename);
+ commStatus = MPI_Bcast(&filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
+ commStatus = MPI_Bcast((void*)filename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD);
- diffFilename = 0;
- commStatus = MPI_Allreduce(&diffFilename, &error, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ diffFilename = 0;
+ commStatus = MPI_Allreduce(&diffFilename, &error, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
- //if file names are different just return false
- if (error > 0)
- return false;
- }
+ //if file names are different just return false
+ if (error > 0)
+ return false;
+ }
- std::ifstream fin(filename, mode);
+ std::ifstream fin(filename, mode);
- if (fin.is_open()) {
+ if (fin.is_open()) {
- fin.seekg(0, std::ios::end);
- fileSize = fin.tellg();
- fin.seekg(0, std::ios::beg);
+ fin.seekg(0, std::ios::end);
+ fileSize = fin.tellg();
+ fin.seekg(0, std::ios::beg);
- // '\0' need one more char
- fbuf = new char[fileSize+1];
+ // '\0' need one more char
+ fbuf = new char[fileSize+1];
- assert(fbuf != 0);
+ assert(fbuf != 0);
- fin.read(fbuf, fileSize);
+ fin.read(fbuf, fileSize);
- if (fin.fail())
- fileSize = FileIOError;
+ if (fin.fail())
+ fileSize = FileIOError;
- //brocasting the file size
- commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
+ //brocasting the file size
+ commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
- if (fileSize < 0) {
- fin.close();
- delete fbuf;
+ if (fileSize < 0) {
+ fin.close();
+ delete fbuf;
- return false;
- }
+ return false;
+ }
- // make a c-style std::string and brocasting it
- fbuf[fileSize] = '\0';
- commStatus = MPI_Bcast(fbuf, fileSize + 1, MPI_CHAR, masterNode, MPI_COMM_WORLD);
+ // make a c-style std::string and brocasting it
+ fbuf[fileSize] = '\0';
+ commStatus = MPI_Bcast(fbuf, fileSize + 1, MPI_CHAR, masterNode, MPI_COMM_WORLD);
- //close the file and delete the buffer
- fin.close();
- internalBuf_.str(fbuf);
- delete fbuf;
- }else{
- fileSize = FileNotExists;
- commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
- return false;
- }
+ //close the file and delete the buffer
+ fin.close();
+ internalBuf_.str(fbuf);
+ delete fbuf;
+ }else{
+ fileSize = FileNotExists;
+ commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
+ return false;
+ }
- } else{ //slave nodes
+ } else{ //slave nodes
- //check file name
- if (checkFilename) {
- commStatus = MPI_Bcast(&filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
+ //check file name
+ if (checkFilename) {
+ commStatus = MPI_Bcast(&filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD);
- char * masterFilename = new char[filenameLen];
- commStatus = MPI_Bcast(masterFilename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD);
+ char * masterFilename = new char[filenameLen];
+ commStatus = MPI_Bcast(masterFilename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD);
- if( strcmp(masterFilename, filename) == 0)
- diffFilename = 0;
- else
- diffFilename = 1;
+ if( strcmp(masterFilename, filename) == 0)
+ diffFilename = 0;
+ else
+ diffFilename = 1;
- delete masterFilename;
+ delete masterFilename;
- commStatus = MPI_Allreduce(&diffFilename, &error, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ commStatus = MPI_Allreduce(&diffFilename, &error, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
- if (error > 0)
- return false;
- }
- //get file size
- commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
+ if (error > 0)
+ return false;
+ }
+ //get file size
+ commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD);
- if (fileSize >= 0 ) {
- fbuf = new char[fileSize+1];
- assert(fbuf);
+ if (fileSize >= 0 ) {
+ fbuf = new char[fileSize+1];
+ assert(fbuf);
- //receive file content
- commStatus = MPI_Bcast(fbuf, fileSize + 1, MPI_CHAR, masterNode, MPI_COMM_WORLD);
+ //receive file content
+ commStatus = MPI_Bcast(fbuf, fileSize + 1, MPI_CHAR, masterNode, MPI_COMM_WORLD);
- internalBuf_.str(fbuf);
- delete fbuf;
+ internalBuf_.str(fbuf);
+ delete fbuf;
- } else if (fileSize == FileNotExists ) {
- return false;
+ } else if (fileSize == FileNotExists ) {
+ return false;
- } else if (fileSize == FileIOError ) {
- return false;
- }
- }
+ } else if (fileSize == FileIOError ) {
+ return false;
+ }
+ }
#else
- //in single version, fall back to ifstream
- if (!internalBuf_.open(filename, mode)) {
- this->setstate(std::ios_base::failbit);
- return false;
- }
+ //in single version, fall back to ifstream
+ if (!internalBuf_.open(filename, mode)) {
+ this->setstate(std::ios_base::failbit);
+ return false;
+ }
#endif
- this->clear();
- return true;
- }
+ this->clear();
+ return true;
+ }
- _Buf internalBuf_; /** internal stream buffer */
- bool isRead; /** file opened flag */
-};
+ _Buf internalBuf_; /** internal stream buffer */
+ bool isRead; /** file opened flag */
+ };
-typedef basic_ifstrstream, std::allocator > ifstrstream;
+ typedef basic_ifstrstream, std::allocator > ifstrstream;
}//namespace oopse
#endif //IO_IFSTRSTREAM_HPP