From 964c76f2e0f3ca5aa1b3bbe13068bd7db1b545cb Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 9 Sep 2008 00:06:47 +0000 Subject: [PATCH] pandaFileStream --- dtool/src/cppparser/cppPreprocessor.cxx | 2 +- dtool/src/dtoolutil/Sources.pp | 14 +- dtool/src/dtoolutil/dtoolutil_composite2.cxx | 3 +- dtool/src/dtoolutil/executionEnvironment.cxx | 6 +- dtool/src/dtoolutil/filename.cxx | 167 ++++++ dtool/src/dtoolutil/filename.h | 6 + dtool/src/dtoolutil/pandaFileStream.I | 173 ++++++ dtool/src/dtoolutil/pandaFileStream.cxx | 17 + dtool/src/dtoolutil/pandaFileStream.h | 93 +++ dtool/src/dtoolutil/pandaFileStreamBuf.cxx | 556 ++++++++++++++++++ dtool/src/dtoolutil/pandaFileStreamBuf.h | 67 +++ dtool/src/interrogate/interrogate.cxx | 10 +- dtool/src/interrogate/interrogate_module.cxx | 2 +- .../src/interrogatedb/interrogateDatabase.cxx | 2 +- dtool/src/parser-inc/iostream | 2 + dtool/src/prc/configPageManager.cxx | 4 +- dtool/src/prc/notify.cxx | 2 +- dtool/src/prckeys/makePrcKey.cxx | 4 +- dtool/src/prckeys/signPrcFile_src.cxx | 4 +- panda/src/downloader/decompressor.cxx | 18 +- panda/src/downloader/downloadDb.cxx | 2 +- panda/src/downloader/download_utils.cxx | 4 +- panda/src/downloader/extractor.h | 2 +- panda/src/downloader/httpChannel.h | 2 +- panda/src/downloader/multiplexStream.I | 2 +- panda/src/downloadertools/check_md5.cxx | 2 +- panda/src/downloadertools/pdecrypt.cxx | 4 +- panda/src/downloadertools/pencrypt.cxx | 4 +- panda/src/downloadertools/punzip.cxx | 4 +- panda/src/downloadertools/pzip.cxx | 4 +- panda/src/egg/eggData.cxx | 2 +- panda/src/express/multifile.cxx | 14 +- panda/src/express/multifile.h | 6 +- panda/src/express/patchfile.cxx | 6 +- panda/src/express/patchfile.h | 6 +- panda/src/express/test_zstream.cxx | 2 +- panda/src/express/virtualFileMountSystem.cxx | 2 +- panda/src/gobj/shader.cxx | 4 +- panda/src/gobj/texture.cxx | 2 +- panda/src/gobj/vertexDataSaveFile.cxx | 12 +- panda/src/parametrics/parametricCurve.cxx | 2 +- .../parametrics/parametricCurveCollection.cxx | 2 +- panda/src/pnmimage/pnmImageHeader.cxx | 2 +- panda/src/putil/bamCache.cxx | 8 +- panda/src/putil/datagramInputFile.h | 2 +- panda/src/putil/datagramOutputFile.h | 2 +- 46 files changed, 1174 insertions(+), 82 deletions(-) create mode 100644 dtool/src/dtoolutil/pandaFileStream.I create mode 100644 dtool/src/dtoolutil/pandaFileStream.cxx create mode 100644 dtool/src/dtoolutil/pandaFileStream.h create mode 100644 dtool/src/dtoolutil/pandaFileStreamBuf.cxx create mode 100644 dtool/src/dtoolutil/pandaFileStreamBuf.h diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index e019a0667e..e2e475a26a 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/dtool/src/cppparser/cppPreprocessor.cxx @@ -121,7 +121,7 @@ open(const CPPFile &file) { assert(_in == NULL); _file = file; - ifstream *in = new ifstream; + pifstream *in = new pifstream; _in = in; return _file._filename.open_read(*in); diff --git a/dtool/src/dtoolutil/Sources.pp b/dtool/src/dtoolutil/Sources.pp index a7d5afaff8..281b071816 100644 --- a/dtool/src/dtoolutil/Sources.pp +++ b/dtool/src/dtoolutil/Sources.pp @@ -13,16 +13,19 @@ config_dtoolutil.h \ executionEnvironment.I executionEnvironment.h filename.I \ filename.h load_dso.h dSearchPath.I dSearchPath.h \ + pandaFileStream.h pandaFileStream.I \ + pandaFileStreamBuf.h \ pandaSystem.h pandaVersion.h \ - pfstream.h \ + pfstream.h pfstream.I pfstreamBuf.h \ vector_string.h gnu_getopt.c gnu_getopt.h gnu_getopt1.c \ - pfstreamBuf.h vector_src.h + vector_src.h #define INCLUDED_SOURCES \ checkPandaVersion.cxx \ config_dtoolutil.cxx \ executionEnvironment.cxx filename.cxx load_dso.cxx \ dSearchPath.cxx \ + pandaFileStream.cxx pandaFileStreamBuf.cxx \ pandaSystem.cxx \ pfstreamBuf.cxx pfstream.cxx \ vector_string.cxx @@ -32,9 +35,12 @@ config_dtoolutil.h \ executionEnvironment.I executionEnvironment.h filename.I \ filename.h load_dso.h dSearchPath.I dSearchPath.h \ + pandaFileStream.h pandaFileStream.I \ + pandaFileStreamBuf.h \ pandaSystem.h pandaVersion.h \ - pfstream.h pfstream.I vector_string.h gnu_getopt.h \ - pfstreamBuf.h vector_src.cxx vector_src.h + pfstream.h pfstream.I pfstreamBuf.h \ + vector_string.h gnu_getopt.h \ + vector_src.cxx vector_src.h #end lib_target #begin test_bin_target diff --git a/dtool/src/dtoolutil/dtoolutil_composite2.cxx b/dtool/src/dtoolutil/dtoolutil_composite2.cxx index bd313f6246..b71c922c2a 100644 --- a/dtool/src/dtoolutil/dtoolutil_composite2.cxx +++ b/dtool/src/dtoolutil/dtoolutil_composite2.cxx @@ -1,4 +1,5 @@ - +#include "pandaFileStream.cxx" +#include "pandaFileStreamBuf.cxx" #include "executionEnvironment.cxx" #include "vector_string.cxx" #include "pfstream.cxx" diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx index 8afd275c2f..b61a582a49 100644 --- a/dtool/src/dtoolutil/executionEnvironment.cxx +++ b/dtool/src/dtoolutil/executionEnvironment.cxx @@ -344,7 +344,7 @@ read_environment_variables() { // have a file called /proc/self/environ that may be read to // determine all of our environment variables. - ifstream proc("/proc/self/environ"); + pifstream proc("/proc/self/environ"); if (proc.fail()) { cerr << "Cannot read /proc/self/environ; environment variables unavailable.\n"; return; @@ -405,7 +405,7 @@ read_args() { #if defined(HAVE_PROC_SELF_MAPS) // This is how you tell whether or not libdtool.so is loaded, // and if so, where it was loaded from. - ifstream maps("/proc/self/maps"); + pifstream maps("/proc/self/maps"); while (!maps.fail() && !maps.eof()) { char buffer[PATH_MAX]; buffer[0] = 0; @@ -461,7 +461,7 @@ read_args() { // /proc/self/cmdline that may be read to determine all of our // command-line arguments. - ifstream proc("/proc/self/cmdline"); + pifstream proc("/proc/self/cmdline"); if (proc.fail()) { cerr << "Cannot read /proc/self/cmdline; command-line arguments unavailable to config.\n"; return; diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index 6854a45061..eee11a5afc 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -1913,6 +1913,173 @@ open_read_write(fstream &stream) const { return (!stream.fail()); } +//////////////////////////////////////////////////////////////////// +// Function: Filename::open_read +// Access: Published +// Description: Opens the indicated pifstream for reading the file, if +// possible. Returns true if successful, false +// otherwise. This requires the setting of the +// set_text()/set_binary() flags to open the file +// appropriately as indicated; it is an error to call +// open_read() without first calling one of set_text() +// or set_binary(). +//////////////////////////////////////////////////////////////////// +bool Filename:: +open_read(pifstream &stream) const { + assert(!get_pattern()); + assert(is_text() || is_binary()); + + ios_openmode open_mode = ios::in; + +#ifdef HAVE_IOS_BINARY + // For some reason, some systems (like Irix) don't define + // ios::binary. + if (!is_text()) { + open_mode |= ios::binary; + } +#endif + + string os_specific = to_os_specific(); + stream.clear(); + stream.open(os_specific.c_str(), open_mode); + return (!stream.fail()); +} + +//////////////////////////////////////////////////////////////////// +// Function: Filename::open_write +// Access: Published +// Description: Opens the indicated pifstream for writing the file, if +// possible. Returns true if successful, false +// otherwise. This requires the setting of the +// set_text()/set_binary() flags to open the file +// appropriately as indicated; it is an error to call +// open_read() without first calling one of set_text() +// or set_binary(). +// +// If truncate is true, the file is truncated to zero +// length upon opening it, if it already exists. +// Otherwise, the file is kept at its original length. +//////////////////////////////////////////////////////////////////// +bool Filename:: +open_write(pofstream &stream, bool truncate) const { + assert(!get_pattern()); + assert(is_text() || is_binary()); + + ios_openmode open_mode = ios::out; + + if (truncate) { + open_mode |= ios::trunc; + + } else { + // Some systems insist on having ios::in set to prevent the file + // from being truncated when we open it. Makes ios::trunc kind of + // pointless, doesn't it? On the other hand, setting ios::in also + // seems to imply ios::nocreate (!), so we should only set this if + // the file already exists. + if (exists()) { + open_mode |= ios::in; + } + } + +#ifdef HAVE_IOS_BINARY + // For some reason, some systems (like Irix) don't define + // ios::binary. + if (!is_text()) { + open_mode |= ios::binary; + } +#endif + + stream.clear(); + string os_specific = to_os_specific(); +#ifdef HAVE_OPEN_MASK + stream.open(os_specific.c_str(), open_mode, 0666); +#else + stream.open(os_specific.c_str(), open_mode); +#endif + + return (!stream.fail()); +} + +//////////////////////////////////////////////////////////////////// +// Function: Filename::open_append +// Access: Published +// Description: Opens the indicated pifstream for writing the file, if +// possible. Returns true if successful, false +// otherwise. This requires the setting of the +// set_text()/set_binary() flags to open the file +// appropriately as indicated; it is an error to call +// open_read() without first calling one of set_text() +// or set_binary(). +//////////////////////////////////////////////////////////////////// +bool Filename:: +open_append(pofstream &stream) const { + assert(!get_pattern()); + assert(is_text() || is_binary()); + + ios_openmode open_mode = ios::app; + +#ifdef HAVE_IOS_BINARY + // For some reason, some systems (like Irix) don't define + // ios::binary. + if (!is_text()) { + open_mode |= ios::binary; + } +#endif + + stream.clear(); + string os_specific = to_os_specific(); +#ifdef HAVE_OPEN_MASK + stream.open(os_specific.c_str(), open_mode, 0666); +#else + stream.open(os_specific.c_str(), open_mode); +#endif + + return (!stream.fail()); +} + +//////////////////////////////////////////////////////////////////// +// Function: Filename::open_read_write +// Access: Published +// Description: Opens the indicated pfstream for read/write access to +// the file, if possible. Returns true if successful, +// false otherwise. This requires the setting of the +// set_text()/set_binary() flags to open the file +// appropriately as indicated; it is an error to call +// open_read_write() without first calling one of +// set_text() or set_binary(). +//////////////////////////////////////////////////////////////////// +bool Filename:: +open_read_write(pfstream &stream) const { + assert(!get_pattern()); + assert(is_text() || is_binary()); + + ios_openmode open_mode = ios::out | ios::in; + + // Since ios::in also seems to imply ios::nocreate (!), we must + // guarantee the file already exists before we try to open it. + if (!exists()) { + touch(); + } + +#ifdef HAVE_IOS_BINARY + // For some reason, some systems (like Irix) don't define + // ios::binary. + if (!is_text()) { + open_mode |= ios::binary; + } +#endif + + stream.clear(); + string os_specific = to_os_specific(); +#ifdef HAVE_OPEN_MASK + stream.open(os_specific.c_str(), open_mode, 0666); +#else + stream.open(os_specific.c_str(), open_mode); +#endif + + return (!stream.fail()); +} + //////////////////////////////////////////////////////////////////// // Function: Filename::touch // Access: Published diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 52a0882eda..c1bd7381ab 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -16,6 +16,7 @@ #define FILENAME_H #include "dtoolbase.h" +#include "pandaFileStream.h" #include "typeHandle.h" #include "register_type.h" #include "vector_string.h" @@ -179,6 +180,11 @@ PUBLISHED: bool open_append(ofstream &stream) const; bool open_read_write(fstream &stream) const; + bool open_read(pifstream &stream) const; + bool open_write(pofstream &stream, bool truncate = true) const; + bool open_append(pofstream &stream) const; + bool open_read_write(pfstream &stream) const; + bool chdir() const; bool touch() const; bool unlink() const; diff --git a/dtool/src/dtoolutil/pandaFileStream.I b/dtool/src/dtoolutil/pandaFileStream.I new file mode 100644 index 0000000000..142ece9967 --- /dev/null +++ b/dtool/src/dtoolutil/pandaFileStream.I @@ -0,0 +1,173 @@ +// Filename: pandaFileStream.I +// Created by: drose (08Sep08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE IFileStream:: +IFileStream() : istream(&_buf) { +} + +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE IFileStream:: +IFileStream(const char *filename, ios::openmode mode) : istream(&_buf) { + open(filename, mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE IFileStream:: +~IFileStream() { + close(); +} + +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::open +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void IFileStream:: +open(const char *filename, ios::openmode mode) { + clear((ios_iostate)0); + _buf.open(filename, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: IFileStream::close +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void IFileStream:: +close() { + _buf.close(); +} + +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE OFileStream:: +OFileStream() : ostream(&_buf) { +} + +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE OFileStream:: +OFileStream(const char *filename, ios::openmode mode) : ostream(&_buf) { + open(filename, mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE OFileStream:: +~OFileStream() { + close(); +} + +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::open +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void OFileStream:: +open(const char *filename, ios::openmode mode) { + clear((ios_iostate)0); + _buf.open(filename, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: OFileStream::close +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void OFileStream:: +close() { + _buf.close(); +} + +//////////////////////////////////////////////////////////////////// +// Function: FileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE FileStream:: +FileStream() : iostream(&_buf) { +} + +//////////////////////////////////////////////////////////////////// +// Function: FileStream::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE FileStream:: +FileStream(const char *filename, ios::openmode mode) : iostream(&_buf) { + open(filename, mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: FileStream::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE FileStream:: +~FileStream() { + close(); +} + +//////////////////////////////////////////////////////////////////// +// Function: FileStream::open +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void FileStream:: +open(const char *filename, ios::openmode mode) { + clear((ios_iostate)0); + _buf.open(filename, mode); + if (!_buf.is_open()) { + clear(ios::failbit); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: FileStream::close +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void FileStream:: +close() { + _buf.close(); +} diff --git a/dtool/src/dtoolutil/pandaFileStream.cxx b/dtool/src/dtoolutil/pandaFileStream.cxx new file mode 100644 index 0000000000..ca0a2f4e40 --- /dev/null +++ b/dtool/src/dtoolutil/pandaFileStream.cxx @@ -0,0 +1,17 @@ +// Filename: pandaFileStream.cxx +// Created by: drose (08Sep08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "pandaFileStream.h" + + diff --git a/dtool/src/dtoolutil/pandaFileStream.h b/dtool/src/dtoolutil/pandaFileStream.h new file mode 100644 index 0000000000..d7fe38c28a --- /dev/null +++ b/dtool/src/dtoolutil/pandaFileStream.h @@ -0,0 +1,93 @@ +// Filename: pandaFileStream.h +// Created by: drose (08Sep08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PANDAFILESTREAM_H +#define PANDAFILESTREAM_H + +#include "dtoolbase.h" +#include "pandaFileStreamBuf.h" + +//////////////////////////////////////////////////////////////////// +// Class : IFileStream +// Description : Implements a C++ stream object suitable for reading +// from files on disk. This is similar to ifstream, but +// it provides low-level support for Panda's +// simple-threading implementation (using this interface +// will block only the current thread, rather than the +// entire process, on I/O waits). +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOL IFileStream : public istream { +public: + INLINE IFileStream(); + INLINE IFileStream(const char *filename, ios::openmode mode = ios::in); + INLINE ~IFileStream(); + + INLINE void open(const char *filename, ios::openmode mode = ios::in); + INLINE void close(); + +private: + PandaFileStreamBuf _buf; +}; + +//////////////////////////////////////////////////////////////////// +// Class : OFileStream +// Description : Implements a C++ stream object suitable for writing +// to files on disk. This is similar to ofstream, but +// it provides low-level support for Panda's +// simple-threading implementation (using this interface +// will block only the current thread, rather than the +// entire process, on I/O waits). +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOL OFileStream : public ostream { +public: + INLINE OFileStream(); + INLINE OFileStream(const char *filename, ios::openmode mode = ios::out); + INLINE ~OFileStream(); + + INLINE void open(const char *filename, ios::openmode mode = ios::out); + INLINE void close(); + +private: + PandaFileStreamBuf _buf; +}; + +//////////////////////////////////////////////////////////////////// +// Class : FileStream +// Description : Implements a C++ stream object suitable for reading +// from and/or writing to files on disk. This is +// similar to fstream, but it provides low-level support +// for Panda's simple-threading implementation (using +// this interface will block only the current thread, +// rather than the entire process, on I/O waits). +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOL FileStream : public iostream { +public: + INLINE FileStream(); + INLINE FileStream(const char *filename, ios::openmode mode = ios::in); + INLINE ~FileStream(); + + INLINE void open(const char *filename, ios::openmode mode = ios::in); + INLINE void close(); + +private: + PandaFileStreamBuf _buf; +}; + +#include "pandaFileStream.I" + +typedef IFileStream pifstream; +typedef OFileStream pofstream; +typedef FileStream pfstream; + +#endif diff --git a/dtool/src/dtoolutil/pandaFileStreamBuf.cxx b/dtool/src/dtoolutil/pandaFileStreamBuf.cxx new file mode 100644 index 0000000000..d4881a3cd0 --- /dev/null +++ b/dtool/src/dtoolutil/pandaFileStreamBuf.cxx @@ -0,0 +1,556 @@ +// Filename: pandaFileStreamBuf.cxx +// Created by: drose (08Sep08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "pandaFileStreamBuf.h" +#include "memoryHook.h" + +#ifndef _WIN32 +#include +#include +#include +#include +#endif // _WIN32 + +static const size_t file_buffer_size = 4096; + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PandaFileStreamBuf:: +PandaFileStreamBuf() { + _is_open = false; + _open_mode = (ios::openmode)0; + +#ifdef _WIN32 + // Windows case. + _handle = NULL; +#else + _fd = -1; +#endif // _WIN32 + +#ifdef HAVE_IOSTREAM + _buffer = (char *)PANDA_MALLOC_ARRAY(file_buffer_size * 2); + char *ebuf = _buffer + file_buffer_size * 2; + char *mbuf = _buffer + file_buffer_size; + setg(_buffer, mbuf, mbuf); + setp(mbuf, ebuf); + +#else + allocate(); + // Chop the buffer in half. The bottom half goes to the get buffer; + // the top half goes to the put buffer. + char *b = base(); + char *t = ebuf(); + char *m = b + (t - b) / 2; + setg(b, m, m); + setp(b, m); +#endif + + _gpos = 0; + _ppos = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PandaFileStreamBuf:: +~PandaFileStreamBuf() { + close(); +#ifdef HAVE_IOSTREAM + PANDA_FREE_ARRAY(_buffer); +#endif +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::open +// Access: Public +// Description: Attempts to open the file for input and/or output. +//////////////////////////////////////////////////////////////////// +void PandaFileStreamBuf:: +open(const char *filename, ios::openmode mode) { + close(); + + _filename = filename; + _open_mode = mode; + _is_open = false; + +#ifdef _WIN32 + // Windows case. + DWORD access = 0; + if (_open_mode & ios::in) { + access |= GENERIC_READ; + } + if (_open_mode & ios::out) { + access |= GENERIC_WRITE; + } + + DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + + DWORD creation_disposition = 0; + if ((_open_mode & (ios::trunc | ios::out)) == (ios::trunc | ios::out)) { + creation_disposition = CREATE_ALWAYS; + } else if (_open_mode & ios::out) { + creation_disposition = OPEN_ALWAYS; + } else { + creation_disposition = OPEN_EXISTING; + } + + DWORD flags = 0; + + if (!(_open_mode & ios::out)) { + flags |= FILE_ATTRIBUTE_READONLY; + } + +#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) + // In SIMPLE_THREADS mode, we use "overlapped" I/O. + flags |= FILE_FLAG_OVERLAPPED; +#endif + + _handle = CreateFile(_filename.c_str(), access, share_mode, + NULL, creation_disposition, flags, NULL); + if (_handle != INVALID_HANDLE_VALUE) { + // The file was successfully opened and locked. + _is_open = true; + } + +#else + // Posix case. + int flags = 0; + + if ((_open_mode & (ios::in | ios::out)) == (ios::in | ios::out)) { + flags |= O_RDWR | O_CREAT; + } else if (_open_mode & ios::in) { + flags |= O_RDONLY; + } else if (_open_mode & ios::out) { + flags |= O_WRONLY | O_CREAT; + } + + if (_open_mode & ios::app) { + flags |= O_APPEND; + } + + if ((_open_mode & (ios::trunc | ios::out)) == (ios::trunc | ios::out)) { + flags |= O_TRUNC; + } + +#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS) + // In SIMPLE_THREADS mode, we use non-blocking I/O. + flags |= O_NONBLOCK; +#endif + + _fd = ::open(_filename.c_str(), flags, 0666); + while (_fd == -1 && errno == EAGAIN) { + thread_yield(); + _fd = ::open(_filename.c_str(), flags, 0666); + } + + if (_fd != -1) { + _is_open = true; + } +#endif // _WIN32 + +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::is_open +// Access: Public +// Description: Returns true if the file is open, false otherwise. +//////////////////////////////////////////////////////////////////// +bool PandaFileStreamBuf:: +is_open() const { + return _is_open; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::close +// Access: Public +// Description: Empties the buffer and closes the file. +//////////////////////////////////////////////////////////////////// +void PandaFileStreamBuf:: +close() { + // Make sure the write buffer is flushed. + sync(); + +#ifdef _WIN32 + if (_handle != NULL) { + CloseHandle(_handle); + } + _handle = NULL; +#else + if (_fd != -1) { + ::close(_fd); + } + _fd = -1; +#endif // _WIN32 + + _is_open = false; + _open_mode = (ios::openmode)0; + + _gpos = 0; + _ppos = 0; + + pbump(pbase() - pptr()); + gbump(egptr() - gptr()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::seekoff +// Access: Public, Virtual +// Description: Implements seeking within the stream. +//////////////////////////////////////////////////////////////////// +streampos PandaFileStreamBuf:: +seekoff(streamoff off, ios_seekdir dir, ios_openmode which) { + streampos result = -1; + + // Sync the iostream buffer first. + sync(); + + if (which & ios::in) { + // Determine the current file position. + size_t n = egptr() - gptr(); + gbump(n); + _gpos -= n; + size_t cur_pos = _gpos; + size_t new_pos = cur_pos; + + // Now adjust the data pointer appropriately. + switch (dir) { + case ios::beg: + new_pos = (size_t)off; + break; + + case ios::cur: + new_pos = (size_t)((int)cur_pos + off); + break; + + case ios::end: +#ifdef _WIN32 + // Windows case. + { + LARGE_INTEGER li; + GetFileSizeEx(_handle, &li); + new_pos = (streampos)li.QuadPart + off; + } +#else + // Posix case. + new_pos = lseek(_fd, off, SEEK_END); + if (new_pos == -1) { + return -1; + } +#endif // _WIN32 + break; + + default: + // Shouldn't get here. + break; + } + + _gpos = new_pos; + result = new_pos; + } + + if (which & ios::out) { + // Determine the current file position. + size_t n = pptr() - pbase(); + streampos cur_pos = _ppos + (streamoff)n; + streampos new_pos = cur_pos; + + // Now adjust the data pointer appropriately. + switch (dir) { + case ios::beg: + new_pos = (streampos)off; + break; + + case ios::cur: + new_pos = (streampos)((int)cur_pos + off); + break; + + case ios::end: +#ifdef _WIN32 + // Windows case. + // Windows case. + { + LARGE_INTEGER li; + GetFileSizeEx(_handle, &li); + new_pos = (streampos)li.QuadPart + off; + } +#else + // Posix case. + new_pos = lseek(_fd, off, SEEK_END); + if (new_pos == (streampos)-1) { + return -1; + } +#endif // _WIN32 + break; + + default: + // Shouldn't get here. + break; + } + + _ppos = new_pos; + result = new_pos; + } + + return result; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::seekpos +// Access: Public, Virtual +// Description: A variant on seekoff() to implement seeking within a +// stream. +// +// The MSDN Library claims that it is only necessary to +// redefine seekoff(), and not seekpos() as well, as the +// default implementation of seekpos() is supposed to +// map to seekoff() exactly as I am doing here; but in +// fact it must do something else, because seeking +// didn't work on Windows until I redefined this +// function as well. +//////////////////////////////////////////////////////////////////// +streampos PandaFileStreamBuf:: +seekpos(streampos pos, ios_openmode which) { + return seekoff(pos, ios::beg, which); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::overflow +// Access: Protected, Virtual +// Description: Called by the system ostream implementation when its +// internal buffer is filled, plus one character. +//////////////////////////////////////////////////////////////////// +int PandaFileStreamBuf:: +overflow(int ch) { + size_t n = pptr() - pbase(); + if (n != 0) { + write_chars(pbase(), n); + pbump(-(int)n); + } + + if (ch != EOF) { + // Store the extra character back in the buffer. + assert(pptr() != epptr()); + *(pptr()) = ch; + pbump(1); + } + + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::sync +// Access: Protected, Virtual +// Description: Called by the system iostream implementation to +// implement a flush operation. +//////////////////////////////////////////////////////////////////// +int PandaFileStreamBuf:: +sync() { + size_t n = pptr() - pbase(); + + write_chars(pbase(), n); + pbump(-(int)n); + + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::underflow +// Access: Protected, Virtual +// Description: Called by the system istream implementation when its +// internal buffer needs more characters. +//////////////////////////////////////////////////////////////////// +int PandaFileStreamBuf:: +underflow() { + // Sometimes underflow() is called even if the buffer is not empty. + if (gptr() >= egptr()) { + // Mark the buffer filled (with buffer_size bytes). + size_t buffer_size = egptr() - eback(); + gbump(-(int)buffer_size); + + size_t num_bytes = buffer_size; + size_t read_count = read_chars(gptr(), buffer_size); + + if (read_count != num_bytes) { + // Oops, we didn't read what we thought we would. + if (read_count == 0) { + gbump(num_bytes); + return EOF; + } + + // Slide what we did read to the top of the buffer. + assert(read_count < num_bytes); + size_t delta = num_bytes - read_count; + memmove(gptr() + delta, gptr(), read_count); + gbump(delta); + } + } + + return (unsigned char)*gptr(); +} + + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::read_chars +// Access: Private +// Description: Attempts to extract the indicated number of +// characters from the current file position. Returns +// the number of characters extracted. +//////////////////////////////////////////////////////////////////// +size_t PandaFileStreamBuf:: +read_chars(char *start, size_t length) { + if (length == 0) { + return 0; + } + + // Make sure the write buffer is flushed. + sync(); + +#ifdef _WIN32 + // Windows case. + OVERLAPPED overlapped; + memset(&overlapped, 0, sizeof(overlapped)); + LARGE_INTEGER gpos; + gpos.QuadPart = _gpos; + overlapped.Offset = gpos.LowPart; + overlapped.OffsetHigh = gpos.HighPart; + + DWORD bytes_read = 0; + BOOL success = ReadFile(_handle, start, length, &bytes_read, &overlapped); + while (!success) { + DWORD error = GetLastError(); + if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) { + // Wait for more later. + thread_yield(); + } else if (error == ERROR_HANDLE_EOF) { + // End-of-file, normal result. + break; + } else { + cerr + << "Error reading " << length + << " bytes from " << _filename << ", windows error code 0x" << hex + << error << dec << ".\n"; + return 0; + } + success = GetOverlappedResult(_handle, &overlapped, &bytes_read, false); + } + + length = bytes_read; + +#else + // Posix case. + if (lseek(_fd, _gpos, SEEK_SET) == -1) { + cerr + << "Error seeking to position " << _gpos << " in " << _filename << "\n"; + return 0; + } + + ssize_t result = ::read(_fd, start, length); + while (result < 0) { + if (errno == EAGAIN) { + thread_yield(); + } else { + cerr + << "Error reading " << length << " bytes from " << _filename << "\n"; + return 0; + } + result = ::read(_fd, start, length); + } + + length = result; +#endif // _WIN32 + + _gpos += length; + return length; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaFileStreamBuf::write_chars +// Access: Private +// Description: Outputs the indicated stream of characters to the +// current file position. +//////////////////////////////////////////////////////////////////// +void PandaFileStreamBuf:: +write_chars(const char *start, size_t length) { + if (length == 0) { + // Trivial no-op. + return; + } + + // Make sure the read buffer is flushed. + size_t n = egptr() - gptr(); + gbump(n); + _gpos -= n; + +#ifdef _WIN32 + // Windows case. + OVERLAPPED overlapped; + memset(&overlapped, 0, sizeof(overlapped)); + LARGE_INTEGER ppos; + ppos.QuadPart = _ppos; + overlapped.Offset = ppos.LowPart; + overlapped.OffsetHigh = ppos.HighPart; + + DWORD bytes_written = 0; + BOOL success = WriteFile(_handle, start, length, &bytes_written, &overlapped); + while (!success) { + DWORD error = GetLastError(); + if (error == ERROR_IO_INCOMPLETE || error == ERROR_IO_PENDING) { + // Wait for more later. + thread_yield(); + } else { + cerr + << "Error writing " << length + << " bytes to " << _filename << ", windows error code 0x" << hex + << error << dec << ". Disk full?\n"; + return; + } + success = GetOverlappedResult(_handle, &overlapped, &bytes_written, false); + } + assert(bytes_written == length); + _ppos += bytes_written; + +#else + // Posix case. + if (!(_open_mode & ios::app)) { + if (lseek(_fd, _ppos, SEEK_SET) == -1) { + cerr + << "Error seeking to position " << _ppos << " in " << _filename << "\n"; + return; + } + } + + while (length > 0) { + ssize_t result = ::write(_fd, start, length); + if (result < 0) { + if (errno == EAGAIN) { + thread_yield(); + } else { + cerr + << "Error writing " << length << " bytes to " << _filename << "\n"; + return; + } + continue; + } + + start += result; + length -= result; + _ppos += result; + } +#endif // _WIN32 +} diff --git a/dtool/src/dtoolutil/pandaFileStreamBuf.h b/dtool/src/dtoolutil/pandaFileStreamBuf.h new file mode 100644 index 0000000000..43a33bc742 --- /dev/null +++ b/dtool/src/dtoolutil/pandaFileStreamBuf.h @@ -0,0 +1,67 @@ +// Filename: pandaFileStreamBuf.h +// Created by: drose (08Sep08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PANDAFILESTREAMBUF_H +#define PANDAFILESTREAMBUF_H + +#include "dtoolbase.h" + +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +//////////////////////////////////////////////////////////////////// +// Class : PandaFileStreamBuf +// Description : The streambuf object that implements +// pifstream and pofstream. +//////////////////////////////////////////////////////////////////// +class EXPCL_DTOOL PandaFileStreamBuf : public streambuf { +public: + PandaFileStreamBuf(); + virtual ~PandaFileStreamBuf(); + + void open(const char *filename, ios::openmode mode); + bool is_open() const; + void close(); + +protected: + virtual streampos seekoff(streamoff off, ios_seekdir dir, ios_openmode which); + virtual streampos seekpos(streampos pos, ios_openmode which); + + virtual int overflow(int c); + virtual int sync(); + virtual int underflow(); + +private: + size_t read_chars(char *start, size_t length); + void write_chars(const char *start, size_t length); + +private: + string _filename; + bool _is_open; + ios::openmode _open_mode; + +#ifdef _WIN32 + HANDLE _handle; +#else + int _fd; // Posix file descriptor +#endif // _WIN32 + + char *_buffer; + streampos _ppos; + streampos _gpos; +}; + +#endif diff --git a/dtool/src/interrogate/interrogate.cxx b/dtool/src/interrogate/interrogate.cxx index 3bf7f4312c..feaa8a9b7d 100644 --- a/dtool/src/interrogate/interrogate.cxx +++ b/dtool/src/interrogate/interrogate.cxx @@ -512,7 +512,7 @@ main(int argc, char *argv[]) { Filename nfilename = filename; nfilename.set_extension("N"); nfilename.set_text(); - ifstream nfile; + pifstream nfile; if (nfilename.open_read(nfile)) { builder.read_command_file(nfile); } @@ -526,8 +526,8 @@ main(int argc, char *argv[]) { int file_identifier = time((time_t *)NULL); InterrogateModuleDef *def = builder.make_module_def(file_identifier); - ofstream * the_output_include = NULL; - ofstream output_include; + pofstream * the_output_include = NULL; + pofstream output_include; if (1==2 && !output_include_filename.empty()) @@ -556,7 +556,7 @@ main(int argc, char *argv[]) { // Now output all of the wrapper functions. if (!output_code_filename.empty()) { - ofstream output_code; + pofstream output_code; output_code_filename.open_write(output_code); output_code @@ -585,7 +585,7 @@ main(int argc, char *argv[]) { // And now output the bulk of the database. if (!output_data_filename.empty()) { - ofstream output_data; + pofstream output_data; output_data_filename.open_write(output_data); if (output_data.fail()) diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 964ba77b20..65aa76fe53 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -340,7 +340,7 @@ int main(int argc, char *argv[]) // Now output the table. if (!output_code_filename.empty()) { - ofstream output_code; + pofstream output_code; if (!output_code_filename.open_write(output_code)) { diff --git a/dtool/src/interrogatedb/interrogateDatabase.cxx b/dtool/src/interrogatedb/interrogateDatabase.cxx index a1ccef24aa..70947cb53c 100644 --- a/dtool/src/interrogatedb/interrogateDatabase.cxx +++ b/dtool/src/interrogatedb/interrogateDatabase.cxx @@ -911,7 +911,7 @@ load_latest() { } else { - ifstream input; + pifstream input; pathname.set_text(); if (!pathname.open_read(input)) { interrogatedb_cat->error() << "Unable to read " << pathname << ".\n"; diff --git a/dtool/src/parser-inc/iostream b/dtool/src/parser-inc/iostream index 4b4b15d339..9f51a96e72 100644 --- a/dtool/src/parser-inc/iostream +++ b/dtool/src/parser-inc/iostream @@ -34,6 +34,8 @@ __published: cur = 1, end = 2, }; + enum openmode { + }; }; class ios : public ios_base { __published: diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx index 615561d879..59967b1ca6 100644 --- a/dtool/src/prc/configPageManager.cxx +++ b/dtool/src/prc/configPageManager.cxx @@ -309,7 +309,7 @@ reload_implicit_pages() { // Read and decrypt the file. filename.set_binary(); - ifstream in; + pifstream in; if (!filename.open_read(in)) { prc_cat.error() << "Unable to read " << filename << "\n"; @@ -326,7 +326,7 @@ reload_implicit_pages() { // Just read the file. filename.set_text(); - ifstream in; + pifstream in; if (!filename.open_read(in)) { prc_cat.error() << "Unable to read " << filename << "\n"; diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index 42b943d086..f87c0e01c5 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -540,7 +540,7 @@ config_initialized() { } else { Filename filename = notify_output; filename.set_text(); - ofstream *out = new ofstream; + pofstream *out = new pofstream; if (!filename.open_write(*out)) { nout << "Unable to open file " << filename << " for output.\n"; delete out; diff --git a/dtool/src/prckeys/makePrcKey.cxx b/dtool/src/prckeys/makePrcKey.cxx index 5a7470a8ba..d95bcbdaf3 100644 --- a/dtool/src/prckeys/makePrcKey.cxx +++ b/dtool/src/prckeys/makePrcKey.cxx @@ -144,7 +144,7 @@ write_public_keys(Filename outfile) { outfile.set_text(); cerr << "Rewriting " << outfile << "\n"; - ofstream out; + pofstream out; if (!outfile.open_write(out)) { cerr << "Unable to open " << outfile << " for writing.\n"; exit(1); @@ -212,7 +212,7 @@ write_private_key(EVP_PKEY *pkey, Filename outfile, int n, time_t now, outfile.set_text(); cerr << "Rewriting " << outfile << "\n"; - ofstream out; + pofstream out; if (!outfile.open_write(out)) { cerr << "Unable to open " << outfile << " for writing.\n"; exit(1); diff --git a/dtool/src/prckeys/signPrcFile_src.cxx b/dtool/src/prckeys/signPrcFile_src.cxx index ba4f6fc33c..1ae410149a 100644 --- a/dtool/src/prckeys/signPrcFile_src.cxx +++ b/dtool/src/prckeys/signPrcFile_src.cxx @@ -155,7 +155,7 @@ void sign_prc(Filename filename, bool no_comments, EVP_PKEY *pkey) { filename.set_text(); - ifstream in; + pifstream in; if (!filename.open_read(in)) { cerr << "Unable to read file " << filename << "\n"; exit(1); @@ -223,7 +223,7 @@ sign_prc(Filename filename, bool no_comments, EVP_PKEY *pkey) { // Now open the file in write mode and rewrite it with the new // signature. - ofstream out; + pofstream out; if (!filename.open_write(out)) { cerr << "Unable to rewrite file " << filename << "\n"; exit(1); diff --git a/panda/src/downloader/decompressor.cxx b/panda/src/downloader/decompressor.cxx index fdd46b4b9f..4df8aaafe2 100644 --- a/panda/src/downloader/decompressor.cxx +++ b/panda/src/downloader/decompressor.cxx @@ -92,30 +92,30 @@ initiate(const Filename &source_file, const Filename &dest_file) { _source_filename = Filename(source_file); _source_filename.set_binary(); - ifstream *source_fstream = new ifstream; - _source = source_fstream; - if (!_source_filename.open_read(*source_fstream)) { + pifstream *source_pfstream = new pifstream; + _source = source_pfstream; + if (!_source_filename.open_read(*source_pfstream)) { downloader_cat.error() << "Unable to read " << _source_filename << "\n"; return get_write_error(); } // Determine source file length - source_fstream->seekg(0, ios::end); - _source_length = source_fstream->tellg(); + source_pfstream->seekg(0, ios::end); + _source_length = source_pfstream->tellg(); if (_source_length == 0) { downloader_cat.warning() << "Zero length file: " << source_file << "\n"; return EU_error_file_empty; } - source_fstream->seekg(0, ios::beg); + source_pfstream->seekg(0, ios::beg); // Open destination file Filename dest_filename(dest_file); dest_filename.set_binary(); - ofstream *dest_fstream = new ofstream; - _dest = dest_fstream; + pofstream *dest_pfstream = new pofstream; + _dest = dest_pfstream; if (dest_filename.exists()) { downloader_cat.info() << dest_filename << " already exists, removing.\n"; @@ -130,7 +130,7 @@ initiate(const Filename &source_file, const Filename &dest_file) { << dest_filename << " does not already exist.\n"; } } - if (!dest_filename.open_write(*dest_fstream, true)) { + if (!dest_filename.open_write(*dest_pfstream, true)) { downloader_cat.error() << "Unable to write to " << dest_filename << "\n"; return get_write_error(); diff --git a/panda/src/downloader/downloadDb.cxx b/panda/src/downloader/downloadDb.cxx index 79c25da156..c3998476ba 100644 --- a/panda/src/downloader/downloadDb.cxx +++ b/panda/src/downloader/downloadDb.cxx @@ -362,7 +362,7 @@ read_db(Ramfile &file, bool want_server_info) { //////////////////////////////////////////////////////////////////// bool DownloadDb:: write_db(Filename &file, Db db, bool want_server_info) { - ofstream write_stream; + pofstream write_stream; file.set_binary(); if (!file.open_write(write_stream)) { downloader_cat.error() diff --git a/panda/src/downloader/download_utils.cxx b/panda/src/downloader/download_utils.cxx index b979378404..d1aba78fd6 100644 --- a/panda/src/downloader/download_utils.cxx +++ b/panda/src/downloader/download_utils.cxx @@ -22,7 +22,7 @@ unsigned long check_crc(Filename name) { - ifstream read_stream; + pifstream read_stream; name.set_binary(); if (!name.open_read(read_stream)) { downloader_cat.error() @@ -48,7 +48,7 @@ check_crc(Filename name) { unsigned long check_adler(Filename name) { - ifstream read_stream; + pifstream read_stream; name.set_binary(); if (!name.open_read(read_stream)) { downloader_cat.error() diff --git a/panda/src/downloader/extractor.h b/panda/src/downloader/extractor.h index 1acd6ee0e4..59856282e1 100644 --- a/panda/src/downloader/extractor.h +++ b/panda/src/downloader/extractor.h @@ -73,7 +73,7 @@ private: size_t _subfile_length; size_t _total_bytes_extracted; istream *_read; - ofstream _write; + pofstream _write; Filename _subfile_filename; }; diff --git a/panda/src/downloader/httpChannel.h b/panda/src/downloader/httpChannel.h index 4eb852c61a..9067e37d4d 100644 --- a/panda/src/downloader/httpChannel.h +++ b/panda/src/downloader/httpChannel.h @@ -346,7 +346,7 @@ private: DownloadDest _download_dest; bool _subdocument_resumes; Filename _download_to_filename; - ofstream _download_to_file; + pofstream _download_to_file; Ramfile *_download_to_ramfile; int _read_index; diff --git a/panda/src/downloader/multiplexStream.I b/panda/src/downloader/multiplexStream.I index 4a26917fb7..3951c13f7d 100644 --- a/panda/src/downloader/multiplexStream.I +++ b/panda/src/downloader/multiplexStream.I @@ -72,7 +72,7 @@ add_standard_output() { INLINE bool MultiplexStream:: add_file(Filename file) { file.set_text(); - ofstream *out = new ofstream; + pofstream *out = new pofstream; if (!file.open_append(*out)) { delete out; return false; diff --git a/panda/src/downloadertools/check_md5.cxx b/panda/src/downloadertools/check_md5.cxx index 7a46018b4b..7ae4f04dd3 100644 --- a/panda/src/downloadertools/check_md5.cxx +++ b/panda/src/downloadertools/check_md5.cxx @@ -25,7 +25,7 @@ bool output_decimal = false; bool suppress_filename = false; -ofstream binary_output; +pofstream binary_output; void usage() { diff --git a/panda/src/downloadertools/pdecrypt.cxx b/panda/src/downloadertools/pdecrypt.cxx index 499aa9ca66..2d1392a8e2 100644 --- a/panda/src/downloadertools/pdecrypt.cxx +++ b/panda/src/downloadertools/pdecrypt.cxx @@ -129,7 +129,7 @@ main(int argc, char *argv[]) { } // Open source file - ifstream read_stream; + pifstream read_stream; source_file.set_binary(); if (!source_file.open_read(read_stream)) { cerr << "Couldn't read: " << source_file << endl; @@ -137,7 +137,7 @@ main(int argc, char *argv[]) { } else { // Open destination file - ofstream write_stream; + pofstream write_stream; dest_file.set_binary(); if (!dest_file.open_write(write_stream, true)) { cerr << "Failed to open: " << dest_file << endl; diff --git a/panda/src/downloadertools/pencrypt.cxx b/panda/src/downloadertools/pencrypt.cxx index 249616349f..2d2d0b5658 100644 --- a/panda/src/downloadertools/pencrypt.cxx +++ b/panda/src/downloadertools/pencrypt.cxx @@ -186,7 +186,7 @@ main(int argc, char *argv[]) { } // Open source file - ifstream read_stream; + pifstream read_stream; source_file.set_binary(); if (!source_file.open_read(read_stream)) { cerr << "Couldn't read: " << source_file << endl; @@ -194,7 +194,7 @@ main(int argc, char *argv[]) { } else { // Open destination file - ofstream write_stream; + pofstream write_stream; dest_file.set_binary(); if (!dest_file.open_write(write_stream, true)) { cerr << "Failed to open: " << dest_file << endl; diff --git a/panda/src/downloadertools/punzip.cxx b/panda/src/downloadertools/punzip.cxx index c34f184976..29e6924a12 100644 --- a/panda/src/downloadertools/punzip.cxx +++ b/panda/src/downloadertools/punzip.cxx @@ -110,7 +110,7 @@ main(int argc, char *argv[]) { } // Open source file - ifstream read_stream; + pifstream read_stream; source_file.set_binary(); if (!source_file.open_read(read_stream)) { cerr << "Couldn't read: " << source_file << endl; @@ -118,7 +118,7 @@ main(int argc, char *argv[]) { } else { // Open destination file - ofstream write_stream; + pofstream write_stream; dest_file.set_binary(); if (!dest_file.open_write(write_stream, true)) { cerr << "Failed to open: " << dest_file << endl; diff --git a/panda/src/downloadertools/pzip.cxx b/panda/src/downloadertools/pzip.cxx index d5a0a227e2..8f6975cc2d 100644 --- a/panda/src/downloadertools/pzip.cxx +++ b/panda/src/downloadertools/pzip.cxx @@ -125,7 +125,7 @@ main(int argc, char *argv[]) { } // Open source file - ifstream read_stream; + pifstream read_stream; source_file.set_binary(); if (!source_file.open_read(read_stream)) { cerr << "Couldn't read: " << source_file << endl; @@ -133,7 +133,7 @@ main(int argc, char *argv[]) { } else { // Open destination file - ofstream write_stream; + pofstream write_stream; dest_file.set_binary(); if (!dest_file.open_write(write_stream, true)) { cerr << "Failed to open: " << dest_file << endl; diff --git a/panda/src/egg/eggData.cxx b/panda/src/egg/eggData.cxx index bf1b14456c..4751e12566 100644 --- a/panda/src/egg/eggData.cxx +++ b/panda/src/egg/eggData.cxx @@ -249,7 +249,7 @@ write_egg(Filename filename) { } #endif // HAVE_ZLIB - ofstream file; + pofstream file; if (!filename.open_write(file)) { egg_cat.error() << "Unable to open " << filename << " for writing.\n"; return false; diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index 9bc28b82a4..49e2306d54 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -705,7 +705,7 @@ repack() { } Filename temp_filename = Filename::temporary(dirname, "mftemp"); temp_filename.set_binary(); - ofstream temp; + pofstream temp; if (!temp_filename.open_write(temp)) { express_cat.info() << "Unable to open temporary file " << temp_filename << "\n"; @@ -1028,7 +1028,7 @@ get_subfile_internal_length(int index) const { // Description: Returns an istream that may be used to read the // indicated subfile. You may seek() within this // istream to your heart's content; even though it will -// be a reference to the already-opened fstream of the +// be a reference to the already-opened pfstream of the // Multifile itself, byte 0 appears to be the beginning // of the subfile and EOF appears to be the end of the // subfile. @@ -1132,7 +1132,7 @@ extract_subfile(int index, const Filename &filename) { Filename fname = filename; fname.set_binary(); fname.make_dir(); - ofstream out; + pofstream out; if (!fname.open_write(out, true)) { express_cat.info() << "Unable to write to file " << filename << "\n"; @@ -1194,7 +1194,7 @@ compare_subfile(int index, const Filename &filename) { return false; } - ifstream in2; + pifstream in2; Filename bin_filename = Filename::binary_filename(filename); if (!bin_filename.open_read(in2)) { express_cat.info() @@ -1752,7 +1752,7 @@ write_data(ostream &write, istream *read, streampos fpos, nassertr(write.tellp() == fpos, fpos); istream *source = _source; - ifstream source_file; + pifstream source_file; if (source == (istream *)NULL && !_source_filename.empty()) { // If we have a filename, open it up and read that. if (!_source_filename.open_read(source_file)) { @@ -1871,7 +1871,7 @@ write_data(ostream &write, istream *read, streampos fpos, //////////////////////////////////////////////////////////////////// // Function: Multifile::Subfile::rewrite_index_data_start // Access: Public -// Description: Seeks within the indicate fstream back to the index +// Description: Seeks within the indicate pfstream back to the index // record and rewrites just the _data_start and // _data_length part of the index record. //////////////////////////////////////////////////////////////////// @@ -1901,7 +1901,7 @@ rewrite_index_data_start(ostream &write, Multifile *multifile) { //////////////////////////////////////////////////////////////////// // Function: Multifile::Subfile::rewrite_index_flags // Access: Public -// Description: Seeks within the indicate fstream back to the index +// Description: Seeks within the indicate pfstream back to the index // record and rewrites just the _flags part of the // index record. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/express/multifile.h b/panda/src/express/multifile.h index 1eca8b3b3e..ef32332a83 100644 --- a/panda/src/express/multifile.h +++ b/panda/src/express/multifile.h @@ -177,9 +177,9 @@ private: bool _encryption_flag; string _encryption_password; - ifstream _read_file; - ofstream _write_file; - fstream _read_write_file; + pifstream _read_file; + pofstream _write_file; + pfstream _read_write_file; Filename _multifile_name; int _file_major_ver; diff --git a/panda/src/express/patchfile.cxx b/panda/src/express/patchfile.cxx index 6b183a84e7..4b15441e75 100644 --- a/panda/src/express/patchfile.cxx +++ b/panda/src/express/patchfile.cxx @@ -1397,7 +1397,7 @@ build(Filename file_orig, Filename file_new, Filename patch_name) { patch_name.set_binary(); // Open the original file for read - ifstream stream_orig; + pifstream stream_orig; file_orig.set_binary(); if (!file_orig.open_read(stream_orig)) { express_cat.error() @@ -1406,7 +1406,7 @@ build(Filename file_orig, Filename file_new, Filename patch_name) { } // Open the new file for read - ifstream stream_new; + pifstream stream_new; file_new.set_binary(); if (!file_new.open_read(stream_new)) { express_cat.error() @@ -1415,7 +1415,7 @@ build(Filename file_orig, Filename file_new, Filename patch_name) { } // Open patch file for write - ofstream write_stream; + pofstream write_stream; if (!patch_name.open_write(write_stream)) { express_cat.error() << "Patchfile::build() - Failed to open file: " << patch_name << endl; diff --git a/panda/src/express/patchfile.h b/panda/src/express/patchfile.h index 92e94778b1..e4e767b818 100644 --- a/panda/src/express/patchfile.h +++ b/panda/src/express/patchfile.h @@ -175,9 +175,9 @@ protected: PN_uint32 _total_bytes_to_process; PN_uint32 _total_bytes_processed; - ifstream _patch_stream; - ofstream _write_stream; - ifstream _origfile_stream; + pifstream _patch_stream; + pofstream _write_stream; + pifstream _origfile_stream; Filename _patch_file; Filename _orig_file; diff --git a/panda/src/express/test_zstream.cxx b/panda/src/express/test_zstream.cxx index e1cf4e1afa..a4c518ceed 100644 --- a/panda/src/express/test_zstream.cxx +++ b/panda/src/express/test_zstream.cxx @@ -128,7 +128,7 @@ main(int argc, char *argv[]) { Filename source_filename = argv[1]; source_filename.set_binary(); - ifstream source; + pifstream source; if (!source_filename.open_read(source)) { cerr << "Unable to open source " << source_filename << ".\n"; diff --git a/panda/src/express/virtualFileMountSystem.cxx b/panda/src/express/virtualFileMountSystem.cxx index 729ba01bda..062307e1ba 100644 --- a/panda/src/express/virtualFileMountSystem.cxx +++ b/panda/src/express/virtualFileMountSystem.cxx @@ -103,7 +103,7 @@ open_read_file(const Filename &file) const { #endif // WIN32 Filename pathname(_physical_filename, file); pathname.set_binary(); - ifstream *stream = new ifstream; + pifstream *stream = new pifstream; if (!pathname.open_read(*stream)) { // Couldn't open the file for some reason. close_read_file(stream); diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 87917b7a3c..507edb17ba 100755 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -16,8 +16,6 @@ #include "shader.h" #include "preparedGraphicsObjects.h" #include "virtualFileSystem.h" -#include -#include #ifdef HAVE_CG #include "Cg/cg.h" @@ -1511,7 +1509,7 @@ make(const string &body) { fns << "genshader" << index; string fn = fns.str(); gobj_cat.warning() << "Dumping shader: " << fn << "\n"; - ofstream s; + pofstream s; s.open(fn.c_str()); s << body; s.close(); diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 563d178302..9ad8d2a14f 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -4482,7 +4482,7 @@ read_dds_file(const Filename &fullpath, bool header_only) { bool Texture:: write_txo_file(const Filename &fullpath) const { Filename filename = Filename::binary_filename(fullpath); - ofstream out; + pofstream out; if (!filename.open_write(out)) { gobj_cat.error() << "Unable to open " << filename << "\n"; diff --git a/panda/src/gobj/vertexDataSaveFile.cxx b/panda/src/gobj/vertexDataSaveFile.cxx index d0f1fdfe20..8c31510338 100644 --- a/panda/src/gobj/vertexDataSaveFile.cxx +++ b/panda/src/gobj/vertexDataSaveFile.cxx @@ -100,7 +100,12 @@ VertexDataSaveFile(const Filename &directory, const string &prefix, flags |= O_NONBLOCK; #endif - _fd = open(os_specific.c_str(), flags, 0666); + _fd = ::open(os_specific.c_str(), flags, 0666); + while (_fd == -1 && errno == EAGAIN) { + Thread::force_yield(); + _fd = ::open(os_specific.c_str(), flags, 0666); + } + if (_fd == -1) { // Couldn't open the file: permissions problem or bad directory. if (!_filename.exists()) { @@ -230,12 +235,12 @@ write_data(const unsigned char *data, size_t size, bool compressed) { if (lseek(_fd, block->get_start(), SEEK_SET) == -1) { gobj_cat.error() << "Error seeking to position " << block->get_start() << " in save file.\n"; - return false; + return NULL; } while (size > 0) { ssize_t result = ::write(_fd, data, size); - if (result == -1) { + if (result < 0) { if (errno == EAGAIN) { Thread::force_yield(); } else { @@ -243,6 +248,7 @@ write_data(const unsigned char *data, size_t size, bool compressed) { << "Error writing " << size << " bytes to save file. Disk full?\n"; return NULL; } + continue; } Thread::consider_yield(); diff --git a/panda/src/parametrics/parametricCurve.cxx b/panda/src/parametrics/parametricCurve.cxx index 174b63e6f3..258b90e2b5 100644 --- a/panda/src/parametrics/parametricCurve.cxx +++ b/panda/src/parametrics/parametricCurve.cxx @@ -363,7 +363,7 @@ stitch(const ParametricCurve *, const ParametricCurve *) { //////////////////////////////////////////////////////////////////// bool ParametricCurve:: write_egg(Filename filename, CoordinateSystem cs) { - ofstream out; + pofstream out; filename.set_text(); if (!filename.open_write(out)) { diff --git a/panda/src/parametrics/parametricCurveCollection.cxx b/panda/src/parametrics/parametricCurveCollection.cxx index 9e811e1fcd..0ed6ade549 100644 --- a/panda/src/parametrics/parametricCurveCollection.cxx +++ b/panda/src/parametrics/parametricCurveCollection.cxx @@ -745,7 +745,7 @@ write(ostream &out, int indent_level) const { //////////////////////////////////////////////////////////////////// bool ParametricCurveCollection:: write_egg(Filename filename, CoordinateSystem cs) { - ofstream out; + pofstream out; filename.set_text(); if (!filename.open_write(out)) { diff --git a/panda/src/pnmimage/pnmImageHeader.cxx b/panda/src/pnmimage/pnmImageHeader.cxx index 2f579ff826..bfac826941 100644 --- a/panda/src/pnmimage/pnmImageHeader.cxx +++ b/panda/src/pnmimage/pnmImageHeader.cxx @@ -285,7 +285,7 @@ make_writer(const Filename &filename, PNMFileType *type) const { } } else { - ofstream *new_ostream = new ofstream; + pofstream *new_ostream = new pofstream; Filename actual_name = Filename::binary_filename(filename); if (!actual_name.open_write(*new_ostream)) { delete new_ostream; diff --git a/panda/src/putil/bamCache.cxx b/panda/src/putil/bamCache.cxx index 64ed5e60ee..89564b3137 100644 --- a/panda/src/putil/bamCache.cxx +++ b/panda/src/putil/bamCache.cxx @@ -216,7 +216,7 @@ store(BamCacheRecord *record) { temp_pathname.set_extension(extension); temp_pathname.set_binary(); - ofstream temp_file; + pofstream temp_file; if (!temp_pathname.open_write(temp_file)) { util_cat.error() << "Could not open cache file: " << temp_pathname << "\n"; @@ -660,7 +660,7 @@ do_read_index(Filename &index_pathname) { } index_pathname.set_binary(); - ifstream index_file; + pifstream index_file; if (!index_pathname.open_read(index_file)) { util_cat.error() << "Could not open index file: " << index_pathname << "\n"; @@ -725,7 +725,7 @@ do_read_index(Filename &index_pathname) { bool BamCache:: do_write_index(Filename &index_pathname, const BamCacheIndex *index) { index_pathname.set_binary(); - ofstream index_file; + pofstream index_file; if (!index_pathname.open_write(index_file)) { util_cat.error() @@ -851,7 +851,7 @@ read_record(const Filename &source_pathname, PT(BamCacheRecord) BamCache:: do_read_record(Filename &cache_pathname, bool read_data) { cache_pathname.set_binary(); - ifstream cache_file; + pifstream cache_file; if (!cache_pathname.open_read(cache_file)) { util_cat.debug() << "Could not open cache file: " << cache_pathname << "\n"; diff --git a/panda/src/putil/datagramInputFile.h b/panda/src/putil/datagramInputFile.h index 011e26ba1a..1840998bb2 100644 --- a/panda/src/putil/datagramInputFile.h +++ b/panda/src/putil/datagramInputFile.h @@ -48,7 +48,7 @@ private: bool _read_first_datagram; bool _error; PT(VirtualFile) _vfile; - ifstream _in_file; + pifstream _in_file; istream *_in; bool _owns_in; }; diff --git a/panda/src/putil/datagramOutputFile.h b/panda/src/putil/datagramOutputFile.h index 1313d609f5..d306e8fb39 100644 --- a/panda/src/putil/datagramOutputFile.h +++ b/panda/src/putil/datagramOutputFile.h @@ -42,7 +42,7 @@ public: private: bool _wrote_first_datagram; bool _error; - ofstream _out_file; + pofstream _out_file; ostream *_out; bool _owns_out; };