ofstream.cpp revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1// This file is part of the ustl library, an STL implementation. 2// 3// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net> 4// This file is free software, distributed under the MIT License. 5// 6// ofstream.cc 7// 8 9#include "ofstream.h" 10#include "ustring.h" 11#include "uexception.h" 12#include <unistd.h> 13#include <errno.h> 14#include <stdio.h> 15#include <stdarg.h> 16 17namespace ustl { 18 19//---------------------------------------------------------------------- 20 21ifstream cin (STDIN_FILENO); 22ofstream cout (STDOUT_FILENO); 23ofstream cerr (STDERR_FILENO); 24 25//---------------------------------------------------------------------- 26 27/// Default constructor. 28ofstream::ofstream (void) 29: ostringstream (), 30 m_File () 31{ 32 reserve (255); 33} 34 35/// Constructs a stream for writing to \p Fd. 36ofstream::ofstream (int Fd) 37: ostringstream (), 38 m_File (Fd) 39{ 40 clear (m_File.rdstate()); 41 reserve (255); 42} 43 44/// Constructs a stream for writing to \p filename. 45ofstream::ofstream (const char* filename, openmode mode) 46: ostringstream (), 47 m_File (filename, mode) 48{ 49 clear (m_File.rdstate()); 50} 51 52/// Default destructor. 53ofstream::~ofstream (void) 54{ 55#if PLATFORM_ANDROID 56 flush(); 57#else /* !PLATFORM_ANDROID */ 58 try { flush(); } catch (...) {} 59#endif 60} 61 62/// Flushes the buffer to the file. 63void ofstream::flush (void) 64{ 65 while (pos() && overflow (remaining())); 66 m_File.sync(); 67 clear (m_File.rdstate()); 68} 69 70/// Seeks to \p p based on \p d. 71void ofstream::seekp (off_t p, seekdir d) 72{ 73 flush(); 74 m_File.seekp (p, d); 75 clear (m_File.rdstate()); 76} 77 78/// Called when more buffer space (\p n bytes) is needed. 79ofstream::size_type ofstream::overflow (size_type n) 80{ 81 if (eof() || (n > remaining() && n < capacity() - pos())) 82 return (ostringstream::overflow (n)); 83 size_type bw = m_File.write (cdata(), pos()); 84 clear (m_File.rdstate()); 85 erase (begin(), bw); 86 if (remaining() < n) 87 ostringstream::overflow (n); 88 return (remaining()); 89} 90 91//---------------------------------------------------------------------- 92 93/// Constructs a stream to read from \p Fd. 94ifstream::ifstream (int Fd) 95: istringstream (), 96 m_Buffer (255), 97 m_File (Fd) 98{ 99 link (m_Buffer.data(), 0U); 100} 101 102/// Constructs a stream to read from \p filename. 103ifstream::ifstream (const char* filename, openmode mode) 104: istringstream (), 105 m_Buffer (255), 106 m_File (filename, mode) 107{ 108 clear (m_File.rdstate()); 109 link (m_Buffer.data(), 0U); 110} 111 112/// Reads at least \p n more bytes and returns available bytes. 113ifstream::size_type ifstream::underflow (size_type n) 114{ 115 if (eof()) 116 return (istringstream::underflow (n)); 117 118 const ssize_t freeSpace = m_Buffer.size() - pos(); 119 const ssize_t neededFreeSpace = max (n, m_Buffer.size() / 2); 120 const size_t oughtToErase = Align (max (0, neededFreeSpace - freeSpace)); 121 const size_t nToErase = min (pos(), oughtToErase); 122 m_Buffer.memlink::erase (m_Buffer.begin(), nToErase); 123 const uoff_t oldPos (pos() - nToErase); 124 125 size_type br = oldPos; 126 if (m_Buffer.size() - br < n) { 127 m_Buffer.resize (br + neededFreeSpace); 128 link (m_Buffer.data(), 0U); 129 } 130 cout.flush(); 131 132 while (br - oldPos < n && m_File.good()) 133 br += m_File.readsome (m_Buffer.begin() + br, m_Buffer.size() - br); 134 clear (m_File.rdstate()); 135 136 m_Buffer[br] = string::c_Terminator; 137 link (m_Buffer.data(), br); 138 seek (oldPos); 139 return (remaining()); 140} 141 142/// Flushes the input. 143void ifstream::sync (void) 144{ 145 istringstream::sync(); 146 underflow (0U); 147 m_File.sync(); 148 clear (m_File.rdstate()); 149} 150 151/// Seeks to \p p based on \p d. 152void ifstream::seekg (off_t p, seekdir d) 153{ 154 m_Buffer.clear(); 155 link (m_Buffer); 156 m_File.seekg (p, d); 157 clear (m_File.rdstate()); 158} 159 160//---------------------------------------------------------------------- 161 162} // namespace ustl 163 164