aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-02 22:24:16 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-02 22:24:16 +0000
commitd47ccc4a0abc3f87339fdb7d24bcb4b854fdc647 (patch)
tree66498c226f11bdc32acce123b9cc0eb2b86fb598
parent9ee3e69e7d5cc3a4ae500855fb57dbc36ac759b8 (diff)
downloadpaludis-d47ccc4a0abc3f87339fdb7d24bcb4b854fdc647.tar.gz
paludis-d47ccc4a0abc3f87339fdb7d24bcb4b854fdc647.tar.xz
Add BufferOutputStream
-rw-r--r--paludis/util/buffer_output_stream-fwd.hh28
-rw-r--r--paludis/util/buffer_output_stream.cc130
-rw-r--r--paludis/util/buffer_output_stream.hh70
-rw-r--r--paludis/util/buffer_output_stream_TEST.cc57
-rw-r--r--paludis/util/files.m41
5 files changed, 286 insertions, 0 deletions
diff --git a/paludis/util/buffer_output_stream-fwd.hh b/paludis/util/buffer_output_stream-fwd.hh
new file mode 100644
index 0000000..81e7315
--- /dev/null
+++ b/paludis/util/buffer_output_stream-fwd.hh
@@ -0,0 +1,28 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_BUFFER_OUTPUT_STREAM_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_BUFFER_OUTPUT_STREAM_FWD_HH 1
+
+namespace paludis
+{
+ struct BufferOutputStream;
+}
+
+#endif
diff --git a/paludis/util/buffer_output_stream.cc b/paludis/util/buffer_output_stream.cc
new file mode 100644
index 0000000..fdb2106
--- /dev/null
+++ b/paludis/util/buffer_output_stream.cc
@@ -0,0 +1,130 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/util/buffer_output_stream.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/condition_variable.hh>
+#include <list>
+#include <string>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<BufferOutputStreamBuf>
+ {
+ Mutex mutex;
+
+ std::list<std::string> complete_strings;
+ std::string active_string;
+
+ Implementation()
+ {
+ }
+ };
+}
+
+BufferOutputStreamBuf::BufferOutputStreamBuf() :
+ PrivateImplementationPattern<BufferOutputStreamBuf>(new Implementation<BufferOutputStreamBuf>())
+{
+ setg(0, 0, 0);
+}
+
+BufferOutputStreamBuf::~BufferOutputStreamBuf()
+{
+}
+
+BufferOutputStreamBuf::int_type
+BufferOutputStreamBuf::overflow(int_type c)
+{
+ Lock lock(_imp->mutex);
+
+ if (c != traits_type::eof())
+ {
+ _imp->active_string.append(std::string(1, c));
+ if (c == '\n')
+ {
+ _imp->complete_strings.push_back(_imp->active_string);
+ _imp->active_string.clear();
+ }
+ }
+
+ return c;
+}
+
+std::streamsize
+BufferOutputStreamBuf::xsputn(const char * s, std::streamsize num)
+{
+ Lock lock(_imp->mutex);
+
+ _imp->active_string.append(std::string(s, num));
+ if (std::string::npos != _imp->active_string.find('\n', _imp->active_string.length() - num))
+ {
+ _imp->complete_strings.push_back(_imp->active_string);
+ _imp->active_string.clear();
+ }
+
+ return num;
+}
+
+void
+BufferOutputStreamBuf::unbuffer(std::ostream & stream)
+{
+ std::list<std::string> c;
+
+ {
+ Lock lock(_imp->mutex);
+ _imp->complete_strings.swap(c);
+ }
+
+ for (std::list<std::string>::const_iterator s(c.begin()), s_end(c.end()) ;
+ s != s_end ; ++s)
+ stream << *s;
+
+ stream << std::flush;
+}
+
+BufferOutputStreamBase::BufferOutputStreamBase()
+{
+}
+
+BufferOutputStreamBase::~BufferOutputStreamBase()
+{
+}
+
+BufferOutputStream::BufferOutputStream() :
+ std::ostream(&buf)
+{
+}
+
+BufferOutputStream::~BufferOutputStream()
+{
+}
+
+void
+BufferOutputStream::unbuffer(std::ostream & s)
+{
+ flush();
+ buf.unbuffer(s);
+}
+
+template class PrivateImplementationPattern<BufferOutputStreamBuf>;
+
diff --git a/paludis/util/buffer_output_stream.hh b/paludis/util/buffer_output_stream.hh
new file mode 100644
index 0000000..d8f8209
--- /dev/null
+++ b/paludis/util/buffer_output_stream.hh
@@ -0,0 +1,70 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_BUFFER_OUTPUT_STREAM_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_BUFFER_OUTPUT_STREAM_HH 1
+
+#include <paludis/util/buffer_output_stream-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <ostream>
+
+namespace paludis
+{
+ class PALUDIS_VISIBLE BufferOutputStreamBuf :
+ private PrivateImplementationPattern<BufferOutputStreamBuf>,
+ public std::streambuf
+ {
+ protected:
+ virtual int_type overflow(int_type c);
+ virtual std::streamsize xsputn(const char * s, std::streamsize num);
+
+ public:
+ BufferOutputStreamBuf();
+ ~BufferOutputStreamBuf();
+
+ void unbuffer(std::ostream &);
+ };
+
+ class PALUDIS_VISIBLE BufferOutputStreamBase
+ {
+ protected:
+ BufferOutputStreamBuf buf;
+
+ public:
+ BufferOutputStreamBase();
+ ~BufferOutputStreamBase();
+ };
+
+ class PALUDIS_VISIBLE BufferOutputStream :
+ protected BufferOutputStreamBase,
+ public std::ostream
+ {
+ public:
+ BufferOutputStream();
+ ~BufferOutputStream();
+
+ void unbuffer(std::ostream &);
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<BufferOutputStreamBuf>;
+#endif
+}
+
+#endif
diff --git a/paludis/util/buffer_output_stream_TEST.cc b/paludis/util/buffer_output_stream_TEST.cc
new file mode 100644
index 0000000..023036c
--- /dev/null
+++ b/paludis/util/buffer_output_stream_TEST.cc
@@ -0,0 +1,57 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/util/buffer_output_stream.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <sstream>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct BufferOutputStreamTest : TestCase
+ {
+ BufferOutputStreamTest() : TestCase("buffer_output_stream") { }
+
+ void run()
+ {
+ BufferOutputStream s;
+ std::stringstream t;
+
+ for (int n(0), n_end(1000) ; n != n_end ; ++n)
+ {
+ s << n << std::endl;
+ t << n << std::endl;
+ }
+
+ std::stringstream ss;
+ s.unbuffer(ss);
+
+ TEST_CHECK_EQUAL(ss.str(), t.str());
+
+ s << "foo" << std::endl;
+ std::stringstream sss;
+ s.unbuffer(sss);
+ TEST_CHECK_EQUAL(sss.str(), "foo\n");
+ }
+ } test_buffer_output_stream;
+}
+
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index 387a68b..46f46ab 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -12,6 +12,7 @@ add(`accept_visitor', `hh')
add(`action_queue', `hh', `cc', `test')
add(`active_object_ptr', `hh', `cc', `fwd', `test')
add(`attributes', `hh')
+add(`buffer_output_stream', `hh', `cc', `fwd', `test')
add(`byte_swap', `hh', `test')
add(`channel', `hh', `cc')
add(`checked_delete', `hh')