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