Mercurial > ecos
diff packages/language/cxx/ustl/current/src/ofstream.cpp @ 2904:88af52c64ce4
* ecos.db: Add uSTL library package record.
* language/cxx/ustl/*: Initial check-in of the port of uSTL 1.3 to eCos
contributed by Uwe Kindler.
| author | jld |
|---|---|
| date | Thu, 20 Aug 2009 17:00:30 +0000 |
| parents | |
| children | 4885e0722884 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/src/ofstream.cpp @@ -0,0 +1,169 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#include "ofstream.h" +#include "ustring.h" +#include "uexception.h" +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <stdarg.h> + +namespace ustl { + +//---------------------------------------------------------------------- +#ifdef CYGVAR_USTL_CIN_COUT_CERR +ifstream cin (STDIN_FILENO); +ofstream cout (STDOUT_FILENO); +ofstream cerr (STDERR_FILENO); +#endif +//---------------------------------------------------------------------- + +/// Default constructor. +ofstream::ofstream (void) +: ostringstream (), + m_File () +{ + reserve (255); +} + +/// Constructs a stream for writing to \p Fd. +ofstream::ofstream (int Fd) +: ostringstream (), + m_File (Fd) +{ + clear (m_File.rdstate()); + reserve (255); +} + +/// Constructs a stream for writing to \p filename. +ofstream::ofstream (const char* filename, openmode mode) +: ostringstream (), + m_File (filename, mode) +{ + clear (m_File.rdstate()); +} + +/// Default destructor. +ofstream::~ofstream (void) throw() +{ + USTL_TRY { flush(); } USTL_CATCH_ALL; +} + +/// Flushes the buffer and closes the file. +void ofstream::close (void) +{ + clear (m_File.rdstate()); + flush(); + m_File.close(); +} + +/// Flushes the buffer to the file. +ofstream& ofstream::flush (void) +{ + clear(); + while (good() && pos() && overflow (remaining())) ; + m_File.sync(); + clear (m_File.rdstate()); + return (*this); +} + +/// Seeks to \p p based on \p d. +ofstream& ofstream::seekp (off_t p, seekdir d) +{ + flush(); + m_File.seekp (p, d); + clear (m_File.rdstate()); + return (*this); +} + +/// Called when more buffer space (\p n bytes) is needed. +ofstream::size_type ofstream::overflow (size_type n) +{ + if (eof() || (n > remaining() && n < capacity() - pos())) + return (ostringstream::overflow (n)); + size_type bw = m_File.write (cdata(), pos()); + clear (m_File.rdstate()); + erase (begin(), bw); + if (remaining() < n) + ostringstream::overflow (n); + return (remaining()); +} + +//---------------------------------------------------------------------- + +/// Constructs a stream to read from \p Fd. +ifstream::ifstream (int Fd) +: istringstream (), + m_Buffer (255), + m_File (Fd) +{ + link (m_Buffer.data(), streamsize(0)); +} + +/// Constructs a stream to read from \p filename. +ifstream::ifstream (const char* filename, openmode mode) +: istringstream (), + m_Buffer (255), + m_File (filename, mode) +{ + clear (m_File.rdstate()); + link (m_Buffer.data(), streamsize(0)); +} + +/// Reads at least \p n more bytes and returns available bytes. +ifstream::size_type ifstream::underflow (size_type n) +{ + if (eof()) + return (istringstream::underflow (n)); + + const ssize_t freeSpace = m_Buffer.size() - pos(); + const ssize_t neededFreeSpace = max (n, m_Buffer.size() / 2); + const size_t oughtToErase = Align (max (0, neededFreeSpace - freeSpace)); + const size_type nToErase = min (pos(), oughtToErase); + m_Buffer.memlink::erase (m_Buffer.begin(), nToErase); + const uoff_t oldPos (pos() - nToErase); + + size_type br = oldPos; + if (m_Buffer.size() - br < n) { + m_Buffer.resize (br + neededFreeSpace); + link (m_Buffer.data(), streamsize(0)); + } + cout.flush(); + + size_type brn = 1; + for (; br < oldPos + n && brn && m_File.good(); br += brn) + brn = m_File.readsome (m_Buffer.begin() + br, m_Buffer.size() - br); + clear (m_File.rdstate()); + + m_Buffer[br] = 0; + link (m_Buffer.data(), br); + seek (oldPos); + return (remaining()); +} + +/// Flushes the input. +int ifstream::sync (void) +{ + istringstream::sync(); + underflow (0U); + m_File.sync(); + clear (m_File.rdstate()); + return (-good()); +} + +/// Seeks to \p p based on \p d. +ifstream& ifstream::seekg (off_t p, seekdir d) +{ + m_Buffer.clear(); + link (m_Buffer); + m_File.seekg (p, d); + clear (m_File.rdstate()); + return (*this); +} + +//---------------------------------------------------------------------- + +} // namespace ustl
