// This file is part of the ustl library, an STL implementation. // // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net> // This file is free software, distributed under the MIT License. // // ofstream.cc // #include "ofstream.h" #include "ustring.h" #include "uexception.h" #include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdarg.h> namespace ustl { //---------------------------------------------------------------------- ifstream cin (STDIN_FILENO); ofstream cout (STDOUT_FILENO); ofstream cerr (STDERR_FILENO); //---------------------------------------------------------------------- /// 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) { #if PLATFORM_ANDROID flush(); #else /* !PLATFORM_ANDROID */ try { flush(); } catch (...) {} #endif } /// Flushes the buffer to the file. void ofstream::flush (void) { while (pos() && overflow (remaining())); m_File.sync(); clear (m_File.rdstate()); } /// Seeks to \p p based on \p d. void ofstream::seekp (off_t p, seekdir d) { flush(); m_File.seekp (p, d); clear (m_File.rdstate()); } /// 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(), 0U); } /// 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(), 0U); } /// 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_t 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(), 0U); } cout.flush(); while (br - oldPos < n && m_File.good()) br += m_File.readsome (m_Buffer.begin() + br, m_Buffer.size() - br); clear (m_File.rdstate()); m_Buffer[br] = string::c_Terminator; link (m_Buffer.data(), br); seek (oldPos); return (remaining()); } /// Flushes the input. void ifstream::sync (void) { istringstream::sync(); underflow (0U); m_File.sync(); clear (m_File.rdstate()); } /// Seeks to \p p based on \p d. void ifstream::seekg (off_t p, seekdir d) { m_Buffer.clear(); link (m_Buffer); m_File.seekg (p, d); clear (m_File.rdstate()); } //---------------------------------------------------------------------- } // namespace ustl