#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/baseversion.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/fileredirector.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programcontext.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textreader.h"
#include "gromacs/utility/textwriter.h"
#include "shellcompletions.h"
binaryName_(helpModule.binaryName_),
links_(eHelpOutputFormat_Rst)
{
- File linksFile("links.dat", "r");
- std::string line;
- while (linksFile.readLine(&line))
+ TextReader linksFile("links.dat");
+ std::string line;
+ while (linksFile.readLineTrimmed(&line))
{
links_.addLink("[REF]." + line + "[ref]",
formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
#include "gromacs/selection/selection.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
#include "gromacs/selection/selhelp.h"
#include "gromacs/topology/topology.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
#include "gromacs/utility/filestream.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
/*! \brief
* Reads a single selection line from stdin.
*
- * \param[in] infile File to read from (typically File::standardInput()).
+ * \param[in] infile Stream to read from (typically the StandardInputStream).
* \param[in] bInteractive Whether to print interactive prompts.
* \param[out] line The read line in stored here.
* \returns true if something was read, false if at end of input.
*
* Handles line continuation, reading also the continuing line(s) in one call.
*/
-bool promptLine(File *infile, bool bInteractive, std::string *line)
+bool promptLine(TextInputStream *infile, bool bInteractive, std::string *line)
{
if (bInteractive)
{
fprintf(stderr, "> ");
}
- if (!infile->readLineWithTrailingSpace(line))
+ if (!infile->readLine(line))
{
return false;
}
std::string buffer;
// Return value ignored, buffer remains empty and works correctly
// if there is nothing to read.
- infile->readLineWithTrailingSpace(&buffer);
+ infile->readLine(&buffer);
line->append(buffer);
}
if (endsWith(*line, "\n"))
_gmx_sel_yypstate_new(), &_gmx_sel_yypstate_delete);
if (bStdIn)
{
- File &stdinFile(File::standardInput());
- const bool bInteractive = _gmx_sel_is_lexer_interactive(scanner);
+ TextInputStream &stdinFile(StandardInputStream::instance());
+ const bool bInteractive = _gmx_sel_is_lexer_interactive(scanner);
if (bInteractive)
{
printCurrentStatus(sc, grps, oldCount, maxnr, context, true);
try
{
- yyscan_t scanner;
- File file(filename, "r");
+ yyscan_t scanner;
+ TextInputFile file(filename);
// TODO: Exception-safe way of using the lexer.
_gmx_sel_init_lexer(&scanner, &impl_->sc_, false, -1,
impl_->bExternalGroupsSet_,
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/trajectoryanalysis/analysismodule.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
+#include "gromacs/utility/filestream.h"
#include "gromacs/utility/gmxassert.h"
#include "runnercommon.h"
common->initIndexGroups(selections, bUseDefaultGroups_);
- const bool bInteractive = File::standardInput().isInteractive();
+ const bool bInteractive = StandardInputStream::instance().isInteractive();
seloptManager.parseRequestedFromStdin(bInteractive);
common->doneIndexGroups(selections);
* implementations for these interfaces that just use the file system.
*
* The header textwriter.h provides gmx::TextWriter for more formatting support
- * when writing to a text stream.
+ * when writing to a text stream. Similarly, textreader.h provides more
+ * formatting support when reading from a text stream.
*
* The header path.h declares helpers for manipulating paths as strings and for
* managing directories and files.
#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
open(filename, mode);
}
-File::File(FILE *fp, bool bClose)
- : impl_(new Impl(fp, bClose))
-{
-}
-
File::~File()
{
}
}
}
-bool File::isInteractive() const
-{
- GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
- "Attempted to access a file object that is not open");
-#ifdef HAVE_UNISTD_H
- return isatty(fileno(impl_->fp_));
-#else
- return true;
-#endif
-}
-
FILE *File::handle()
{
GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
}
}
-bool File::readLine(std::string *line)
-{
- if (!readLineWithTrailingSpace(line))
- {
- return false;
- }
- size_t endPos = line->find_last_not_of(" \t\r\n");
- if (endPos != std::string::npos)
- {
- line->resize(endPos + 1);
- }
- return true;
-}
-
-bool File::readLineWithTrailingSpace(std::string *line)
-{
- line->clear();
- const size_t bufsize = 256;
- std::string result;
- char buf[bufsize];
- buf[0] = '\0';
- FILE *fp = handle();
- while (fgets(buf, bufsize, fp) != NULL)
- {
- size_t length = std::strlen(buf);
- result.append(buf, length);
- if (length < bufsize - 1 || buf[length - 1] == '\n')
- {
- break;
- }
- }
- if (ferror(fp))
- {
- GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
- "fgets", errno);
- }
- *line = result;
- return !result.empty() || !feof(fp);
-}
-
void File::writeString(const char *str)
{
if (fprintf(handle(), "%s", str) < 0)
}
}
-void File::writeLine(const char *line)
-{
- size_t length = std::strlen(line);
-
- writeString(line);
- if (length == 0 || line[length-1] != '\n')
- {
- writeString("\n");
- }
-}
-
-void File::writeLine()
-{
- writeString("\n");
-}
-
// static
bool File::exists(const char *filename)
{
return exists(filename.c_str());
}
-// static
-File &File::standardInput()
-{
- static File stdinObject(stdin, false);
- return stdinObject;
-}
-
// static
std::string File::readToString(const char *filename)
{
*/
void close();
- /*! \brief
- * Returns whether the file is an interactive terminal.
- *
- * Only works on Unix, otherwise always returns true.
- * It only makes sense to call this for File::standardInput() and
- * friends.
- *
- * Thie file must be open.
- * Does not throw.
- */
- bool isInteractive() const;
/*! \brief
* Returns a file handle for interfacing with C functions.
*
* The file must be open.
*/
void readBytes(void *buffer, size_t bytes);
- /*! \brief
- * Reads a single line from the file.
- *
- * \param[out] line String to receive the line.
- * \returns false if nothing was read because the file ended.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- *
- * On error or when false is returned, \p line will be empty.
- * Trailing space will be removed from the line.
- * To loop over all lines in the file, use:
- * \code
- std::string line;
- while (file.readLine(&line))
- {
- // ...
- }
- \endcode
- */
- bool readLine(std::string *line);
- /*! \brief
- * Reads a single line from the file.
- *
- * \param[out] line String to receive the line.
- * \returns false if nothing was read because the file ended.
- * \throws std::bad_alloc if out of memory.
- * \throws FileIOError on any I/O error.
- *
- * On error or when false is returned, \p line will be empty.
- * Works as readLine(), except that terminating newline will be present
- * in \p line if it was present in the file.
- *
- * \see readLine()
- */
- bool readLineWithTrailingSpace(std::string *line);
/*! \brief
* Writes a string to the file.
void writeString(const char *str);
//! \copydoc writeString(const char *)
void writeString(const std::string &str) { writeString(str.c_str()); }
- /*! \brief
- * Writes a line to the file.
- *
- * \param[in] line Line to write.
- * \throws FileIOError on any I/O error.
- *
- * If \p line does not end in a newline, one newline is appended.
- * Otherwise, works as writeString().
- *
- * The file must be open.
- */
- void writeLine(const char *line);
- //! \copydoc writeLine(const char *)
- void writeLine(const std::string &line) { writeLine(line.c_str()); }
- /*! \brief
- * Writes a newline to the file.
- *
- * \throws FileIOError on any I/O error.
- */
- void writeLine();
/*! \brief
* Checks whether a file exists and is a regular file.
//! \copydoc exists(const char *)
static bool exists(const std::string &filename);
- /*! \brief
- * Returns a File object for accessing stdin.
- *
- * \throws std::bad_alloc if out of memory (only on first call).
- */
- static File &standardInput();
-
/*! \brief
* Reads contents of a file to a std::string.
*
const std::string &text);
private:
- /*! \brief
- * Initialize file object from an existing file handle.
- *
- * \param[in] fp %File handle to use (may be NULL).
- * \param[in] bClose Whether this object should close its file handle.
- * \throws std::bad_alloc if out of memory.
- *
- * Used internally to implement standardInput().
- */
- File(FILE *fp, bool bClose);
-
class Impl;
PrivateImplPointer<Impl> impl_;
#include "filestream.h"
+#include "config.h"
+
#include <cerrno>
#include <cstdio>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/stringutil.h"
namespace gmx
{
+namespace
+{
+
+//! Helper function for implementing readLine() for input streams.
+bool readLineImpl(FILE *fp, std::string *line)
+{
+ line->clear();
+ const size_t bufsize = 256;
+ std::string result;
+ char buf[bufsize];
+ buf[0] = '\0';
+ while (std::fgets(buf, bufsize, fp) != NULL)
+ {
+ const size_t length = std::strlen(buf);
+ result.append(buf, length);
+ if (length < bufsize - 1 || buf[length - 1] == '\n')
+ {
+ break;
+ }
+ }
+ if (std::ferror(fp))
+ {
+ GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
+ "fgets", errno);
+ }
+ *line = result;
+ return !result.empty() || !std::feof(fp);
+}
+
+} // namespace
+
namespace internal
{
using internal::FileStreamImpl;
+/********************************************************************
+ * StandardInputStream
+ */
+
+bool StandardInputStream::isInteractive() const
+{
+#ifdef HAVE_UNISTD_H
+ return isatty(fileno(stdin));
+#else
+ return true;
+#endif
+}
+
+bool StandardInputStream::readLine(std::string *line)
+{
+ return readLineImpl(stdin, line);
+}
+
+// static
+StandardInputStream &StandardInputStream::instance()
+{
+ static StandardInputStream stdinObject;
+ return stdinObject;
+}
+
+/********************************************************************
+ * TextInputFile
+ */
+
+TextInputFile::TextInputFile(const std::string &filename)
+ : impl_(new FileStreamImpl(filename.c_str(), "r"))
+{
+}
+
+TextInputFile::TextInputFile(FILE *fp)
+ : impl_(new FileStreamImpl(fp))
+{
+}
+
+TextInputFile::~TextInputFile()
+{
+}
+
+FILE *TextInputFile::handle()
+{
+ return impl_->handle();
+}
+
+bool TextInputFile::readLine(std::string *line)
+{
+ return readLineImpl(impl_->handle(), line);
+}
+
+void TextInputFile::close()
+{
+ impl_->close();
+}
+
/********************************************************************
* TextOutputFile
*/
}
/*! \libinternal \brief
- * Text output stream implementation for writing to a file.
+ * Text input stream implementation for reading from `stdin`.
*
- * Implementations for the TextOutputStream methods throw FileIOError on any
+ * Implementations for the TextInputStream methods throw FileIOError on any
* I/O error.
*
* \inlibraryapi
* \ingroup module_utility
*/
-class TextOutputFile : public TextOutputStream
+class StandardInputStream : public TextInputStream
+{
+ public:
+ /*! \brief
+ * Returns whether `stdin` is an interactive terminal.
+ *
+ * Only works on Unix, otherwise always returns true.
+ *
+ * Does not throw.
+ */
+ bool isInteractive() const;
+
+ // From TextInputStream
+ virtual bool readLine(std::string *line);
+ virtual void close() {}
+
+ /*! \brief
+ * Returns a stream for accessing `stdin`.
+ *
+ * Does not throw.
+ */
+ static StandardInputStream &instance();
+};
+
+/*! \libinternal \brief
+ * Text input stream implementation for reading from a file.
+ *
+ * Implementations for the TextInputStream methods throw FileIOError on any
+ * I/O error.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextInputFile : public TextInputStream
{
public:
/*! \brief
* \throws std::bad_alloc if out of memory.
* \throws FileIOError on any I/O error.
*/
- explicit TextOutputFile(const std::string &filename);
+ explicit TextInputFile(const std::string &filename);
/*! \brief
* Initializes file object from an existing file handle.
*
* The caller is responsible of closing the file; close() does nothing
* for an object constructed this way.
*/
+ explicit TextInputFile(FILE *fp);
+ virtual ~TextInputFile();
+
+ /*! \brief
+ * Returns a raw handle to the input file.
+ *
+ * This is provided for interoperability with older C-like code.
+ */
+ FILE *handle();
+
+ // From TextInputStream
+ virtual bool readLine(std::string *line);
+ virtual void close();
+
+ private:
+ PrivateImplPointer<internal::FileStreamImpl> impl_;
+};
+
+/*! \libinternal \brief
+ * Text output stream implementation for writing to a file.
+ *
+ * Implementations for the TextOutputStream methods throw FileIOError on any
+ * I/O error.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextOutputFile : public TextOutputStream
+{
+ public:
+ //! \copydoc TextInputFile::TextInputFile(const std::string &)
+ explicit TextOutputFile(const std::string &filename);
+ //! \copydoc TextInputFile::TextInputFile(FILE *)
explicit TextOutputFile(FILE *fp);
virtual ~TextOutputFile();
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements gmx::TextReader.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_utility
+ */
+#include "gmxpre.h"
+
+#include "textreader.h"
+
+#include "gromacs/utility/filestream.h"
+#include "gromacs/utility/nodelete.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+class TextReader::Impl
+{
+ public:
+ explicit Impl(const TextInputStreamPointer &stream)
+ : stream_(stream)
+ {
+ }
+
+ TextInputStreamPointer stream_;
+};
+
+TextReader::TextReader(const std::string &filename)
+ : impl_(new Impl(TextInputStreamPointer(new TextInputFile(filename))))
+{
+}
+
+TextReader::TextReader(TextInputStream *stream)
+ : impl_(new Impl(TextInputStreamPointer(stream, no_delete<TextInputStream>())))
+{
+}
+
+TextReader::TextReader(const TextInputStreamPointer &stream)
+ : impl_(new Impl(stream))
+{
+}
+
+TextReader::~TextReader()
+{
+}
+
+bool TextReader::readLine(std::string *line)
+{
+ return impl_->stream_->readLine(line);
+}
+
+bool TextReader::readLineTrimmed(std::string *line)
+{
+ if (!readLine(line))
+ {
+ return false;
+ }
+ const size_t endPos = line->find_last_not_of(" \t\r\n");
+ if (endPos != std::string::npos)
+ {
+ line->resize(endPos + 1);
+ }
+ return true;
+}
+
+void TextReader::close()
+{
+ impl_->stream_->close();
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares gmx::TextReader.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_TEXTREADER_H
+#define GMX_UTILITY_TEXTREADER_H
+
+#include <string>
+
+#include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/textstream.h"
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Reads text from a TextInputStream.
+ *
+ * This class provides more formatted reading capabilities than reading raw
+ * lines from the stream (and a natural place to implement more such
+ * capabilities).
+ *
+ * All methods that read from the stream can throw any exceptions that the
+ * underlying stream throws.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextReader
+{
+ public:
+ /*! \brief
+ * Creates a reader that reads from specified file.
+ *
+ * \param[in] filename Path to the file to open.
+ * \throws std::bad_alloc if out of memory.
+ * \throws FileIOError on any I/O error.
+ *
+ * This constructor is provided for convenience for reading directly
+ * from a file, without the need to construct multiple objects.
+ */
+ explicit TextReader(const std::string &filename);
+ /*! \brief
+ * Creates a reader that reads from specified stream.
+ *
+ * \param[in] stream Stream to read from.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The caller is responsible of the lifetime of the stream (should
+ * remain in existence as long as the reader exists).
+ *
+ * This constructor is provided for convenience for cases where the
+ * stream is not allocated with `new` and/or not managed by a
+ * boost::shared_ptr (e.g., if the stream is an object on the stack).
+ */
+ explicit TextReader(TextInputStream *stream);
+ /*! \brief
+ * Creates a reader that reads from specified stream.
+ *
+ * \param[in] stream Stream to read from.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * The reader keeps a reference to the stream, so the caller can pass
+ * in a temporary if necessary.
+ */
+ explicit TextReader(const TextInputStreamPointer &stream);
+ ~TextReader();
+
+ /*! \brief
+ * Reads a single line (including newline) from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns `false` if nothing was read because the file ended.
+ *
+ * On error or when false is returned, \p line will be empty.
+ * Newlines will be returned as part of \p line if it was present in
+ * the stream.
+ * To loop over all lines in the stream, use:
+ * \code
+ std::string line;
+ while (reader.readLine(&line))
+ {
+ // ...
+ }
+ \endcode
+ */
+ bool readLine(std::string *line);
+ /*! \brief
+ * Reads a single line from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns false if nothing was read because the file ended.
+ *
+ * On error or when false is returned, \p line will be empty.
+ * Works as readLine(), except that trailing whitespace will be removed
+ * from \p line.
+ *
+ * \see readLine()
+ */
+ bool readLineTrimmed(std::string *line);
+
+ /*! \brief
+ * Closes the underlying stream.
+ */
+ void close();
+
+ private:
+ class Impl;
+
+ PrivateImplPointer<Impl> impl_;
+};
+
+} // namespace gmx
+
+#endif
namespace gmx
{
+/*! \libinternal \brief
+ * Interface for reading text.
+ *
+ * Concrete implementations can read the text from, e.g., a file or an in-memory
+ * string. The main use is to allow unit tests to inject in-memory buffers
+ * instead of writing files to be read by the code under test, but there are
+ * also use cases outside the tests where it is useful to abstract out whether
+ * the input is from a real file or something else.
+ *
+ * To use more advanced formatting than reading raw lines, use TextReader.
+ *
+ * Both methods in the interface can throw std::bad_alloc or other exceptions
+ * that indicate failures to read from the stream.
+ *
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+class TextInputStream
+{
+ public:
+ virtual ~TextInputStream() {}
+
+ /*! \brief
+ * Reads a line (with newline included) from the stream.
+ *
+ * \param[out] line String to receive the line.
+ * \returns `false` if nothing was read because the stream ended.
+ *
+ * On error or when `false` is returned, \p line will be empty.
+ */
+ virtual bool readLine(std::string *line) = 0;
+ /*! \brief
+ * Closes the stream.
+ *
+ * It is not allowed to read from a stream after it has been closed.
+ * See TextOutputStream::close() for rationale for a close() method
+ * separate from the destructor. For input, failures during close
+ * should be rare, but it is clearer to keep the interface symmetric.
+ */
+ virtual void close() = 0;
+};
+
/*! \libinternal \brief
* Interface for writing text.
*
virtual void close() = 0;
};
+//! Shorthand for a smart pointer to a TextInputStream.
+typedef boost::shared_ptr<TextInputStream> TextInputStreamPointer;
//! Shorthand for a smart pointer to a TextOutputStream.
typedef boost::shared_ptr<TextOutputStream> TextOutputStreamPointer;