Build system improvements
[ustl.git] / ofstream.cc
blob00e8f3de4c07ad5ce2687ccc6ce78ad6c425b085
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 //
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>
17 namespace ustl {
19 //----------------------------------------------------------------------
21 ifstream cin (STDIN_FILENO);
22 ofstream cout (STDOUT_FILENO);
23 ofstream cerr (STDERR_FILENO);
25 //----------------------------------------------------------------------
27 /// Default constructor.
28 ofstream::ofstream (void)
29 : ostringstream (),
30 m_File ()
32 reserve (255);
35 /// Constructs a stream for writing to \p Fd.
36 ofstream::ofstream (int Fd)
37 : ostringstream (),
38 m_File (Fd)
40 clear (m_File.rdstate());
41 reserve (255);
44 /// Constructs a stream for writing to \p filename.
45 ofstream::ofstream (const char* filename, openmode mode)
46 : ostringstream (),
47 m_File (filename, mode)
49 clear (m_File.rdstate());
52 /// Default destructor.
53 ofstream::~ofstream (void)
55 try { flush(); } catch (...) {}
58 /// Flushes the buffer and closes the file.
59 void ofstream::close (void)
61 clear (m_File.rdstate());
62 flush();
63 m_File.close();
66 /// Flushes the buffer to the file.
67 void ofstream::flush (void)
69 while (pos() && overflow (remaining())) ;
70 m_File.sync();
71 clear (m_File.rdstate());
74 /// Seeks to \p p based on \p d.
75 void ofstream::seekp (off_t p, seekdir d)
77 flush();
78 m_File.seekp (p, d);
79 clear (m_File.rdstate());
82 /// Called when more buffer space (\p n bytes) is needed.
83 ofstream::size_type ofstream::overflow (size_type n)
85 if (eof() || (n > remaining() && n < capacity() - pos()))
86 return (ostringstream::overflow (n));
87 size_type bw = m_File.write (cdata(), pos());
88 clear (m_File.rdstate());
89 erase (begin(), bw);
90 if (remaining() < n)
91 ostringstream::overflow (n);
92 return (remaining());
95 //----------------------------------------------------------------------
97 /// Constructs a stream to read from \p Fd.
98 ifstream::ifstream (int Fd)
99 : istringstream (),
100 m_Buffer (255),
101 m_File (Fd)
103 link (m_Buffer.data(), size_t(0));
106 /// Constructs a stream to read from \p filename.
107 ifstream::ifstream (const char* filename, openmode mode)
108 : istringstream (),
109 m_Buffer (255),
110 m_File (filename, mode)
112 clear (m_File.rdstate());
113 link (m_Buffer.data(), size_t(0));
116 /// Reads at least \p n more bytes and returns available bytes.
117 ifstream::size_type ifstream::underflow (size_type n)
119 if (eof())
120 return (istringstream::underflow (n));
122 const ssize_t freeSpace = m_Buffer.size() - pos();
123 const ssize_t neededFreeSpace = max (n, m_Buffer.size() / 2);
124 const size_t oughtToErase = Align (max (0, neededFreeSpace - freeSpace));
125 const size_t nToErase = min (pos(), oughtToErase);
126 m_Buffer.memlink::erase (m_Buffer.begin(), nToErase);
127 const uoff_t oldPos (pos() - nToErase);
129 size_type br = oldPos;
130 if (m_Buffer.size() - br < n) {
131 m_Buffer.resize (br + neededFreeSpace);
132 link (m_Buffer.data(), size_t(0));
134 cout.flush();
136 size_type brn = 1;
137 for (; br < oldPos + n && brn && m_File.good(); br += brn)
138 brn = m_File.readsome (m_Buffer.begin() + br, m_Buffer.size() - br);
139 clear (m_File.rdstate());
141 m_Buffer[br] = string::c_Terminator;
142 link (m_Buffer.data(), br);
143 seek (oldPos);
144 return (remaining());
147 /// Flushes the input.
148 void ifstream::sync (void)
150 istringstream::sync();
151 underflow (0U);
152 m_File.sync();
153 clear (m_File.rdstate());
156 /// Seeks to \p p based on \p d.
157 void ifstream::seekg (off_t p, seekdir d)
159 m_Buffer.clear();
160 link (m_Buffer);
161 m_File.seekg (p, d);
162 clear (m_File.rdstate());
165 //----------------------------------------------------------------------
167 } // namespace ustl