first commit
This commit is contained in:
169
extern/ustl/1.5/ofstream.cc
vendored
Normal file
169
extern/ustl/1.5/ofstream.cc
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
// 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.
|
||||
|
||||
#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) throw()
|
||||
{
|
||||
try { flush(); } catch (...) {}
|
||||
}
|
||||
|
||||
/// 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
|
||||
Reference in New Issue
Block a user