aboutsummaryrefslogtreecommitdiffstats
path: root/src/utility/stream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utility/stream.cpp')
-rw-r--r--src/utility/stream.cpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/utility/stream.cpp b/src/utility/stream.cpp
new file mode 100644
index 00000000..06d4ba27
--- /dev/null
+++ b/src/utility/stream.cpp
@@ -0,0 +1,257 @@
+//
+// VMime library (http://vmime.sourceforge.net)
+// Copyright (C) 2002-2004 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "stream.hpp"
+#include "stringProxy.hpp"
+
+#include <algorithm> // for std::copy
+#include <iterator> // for std::back_inserter
+
+
+namespace vmime {
+namespace utility {
+
+
+// Helpers
+
+outputStream& operator<<(outputStream& os, const stream::value_type c)
+{
+ os.write(&c, 1);
+ return (os);
+}
+
+
+outputStream& operator<<(outputStream& os, const string& str)
+{
+ os.write(str.data(), str.length());
+ return (os);
+}
+
+
+const stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
+{
+ stream::value_type buffer[65536];
+ stream::size_type total = 0;
+
+ while (!is.eof())
+ {
+ const stream::size_type read = is.read(buffer, sizeof(buffer));
+
+ if (read != 0)
+ {
+ os.write(buffer, read);
+ total += read;
+ }
+ }
+
+ return (total);
+}
+
+
+
+// outputStreamAdapter
+
+outputStreamAdapter::outputStreamAdapter(std::ostream& os)
+ : m_stream(os)
+{
+}
+
+
+void outputStreamAdapter::write
+ (const value_type* const data, const size_type count)
+{
+ m_stream.write(data, count);
+}
+
+
+
+// outputStreamStringAdapter
+
+outputStreamStringAdapter::outputStreamStringAdapter(string& buffer)
+ : m_buffer(buffer)
+{
+ m_buffer.clear();
+}
+
+
+void outputStreamStringAdapter::write(const value_type* const data, const size_type count)
+{
+ // TODO: better way?
+ std::copy(data, data + count, std::back_inserter(m_buffer));
+}
+
+
+
+// inputStreamAdapter
+
+inputStreamAdapter::inputStreamAdapter(std::istream& is)
+ : m_stream(is)
+{
+}
+
+
+const bool inputStreamAdapter::eof() const
+{
+ return (m_stream.eof());
+}
+
+
+void inputStreamAdapter::reset()
+{
+ m_stream.seekg(0, std::ios::beg);
+ m_stream.clear();
+}
+
+
+const stream::size_type inputStreamAdapter::read
+ (value_type* const data, const size_type count)
+{
+ m_stream.read(data, count);
+ return (m_stream.gcount());
+}
+
+
+
+// inputStreamStringAdapter
+
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer)
+ : m_buffer(buffer), m_begin(0), m_end(buffer.length()), m_pos(0)
+{
+}
+
+
+inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer,
+ const string::size_type begin, const string::size_type end)
+ : m_buffer(buffer), m_begin(begin), m_end(end), m_pos(begin)
+{
+}
+
+
+const bool inputStreamStringAdapter::eof() const
+{
+ return (m_pos >= m_end);
+}
+
+
+void inputStreamStringAdapter::reset()
+{
+ m_pos = m_begin;
+}
+
+
+const stream::size_type inputStreamStringAdapter::read
+ (value_type* const data, const size_type count)
+{
+ if (m_pos + count >= m_end)
+ {
+ const size_type remaining = m_end - m_pos;
+
+ std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data);
+ m_pos = m_end;
+ return (remaining);
+ }
+ else
+ {
+ std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data);
+ m_pos += count;
+ return (count);
+ }
+}
+
+
+
+// inputStreamStringProxyAdapter
+
+inputStreamStringProxyAdapter::inputStreamStringProxyAdapter(const stringProxy& buffer)
+ : m_buffer(buffer), m_pos(0)
+{
+}
+
+
+const bool inputStreamStringProxyAdapter::eof() const
+{
+ return (m_pos >= m_buffer.length());
+}
+
+
+void inputStreamStringProxyAdapter::reset()
+{
+ m_pos = 0;
+}
+
+
+const stream::size_type inputStreamStringProxyAdapter::read
+ (value_type* const data, const size_type count)
+{
+ const size_type remaining = m_buffer.length() - m_pos;
+
+ if (count > remaining)
+ {
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_end(), data);
+ m_pos = m_buffer.length();
+ return (remaining);
+ }
+ else
+ {
+ std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_begin() + m_pos + count, data);
+ m_pos += count;
+ return (count);
+ }
+}
+
+
+
+// inputStreamPointerAdapter
+
+inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own)
+ : m_stream(is), m_own(own)
+{
+}
+
+
+inputStreamPointerAdapter::~inputStreamPointerAdapter()
+{
+ if (m_own)
+ delete (m_stream);
+}
+
+
+const bool inputStreamPointerAdapter::eof() const
+{
+ return (m_stream->eof());
+}
+
+
+void inputStreamPointerAdapter::reset()
+{
+ m_stream->seekg(0, std::ios::beg);
+ m_stream->clear();
+}
+
+
+const stream::size_type inputStreamPointerAdapter::read
+ (value_type* const data, const size_type count)
+{
+ m_stream->read(data, count);
+ return (m_stream->gcount());
+}
+
+
+} // utility
+} // vmime