summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/memstream.cpp51
-rw-r--r--libadhocutil/memstream.h36
-rw-r--r--libadhocutil/unittests/Jamfile.jam8
-rw-r--r--libadhocutil/unittests/testMemStream.cpp34
4 files changed, 129 insertions, 0 deletions
diff --git a/libadhocutil/memstream.cpp b/libadhocutil/memstream.cpp
new file mode 100644
index 0000000..35d42ad
--- /dev/null
+++ b/libadhocutil/memstream.cpp
@@ -0,0 +1,51 @@
+#include "memstream.h"
+#include <cstdlib>
+
+namespace AdHoc {
+ MemStream::MemStream() :
+ buf(nullptr),
+ len(0),
+ strm(open_memstream(&buf, &len))
+ {
+ }
+
+ MemStream::~MemStream()
+ {
+ fclose(strm);
+ free(buf);
+ }
+
+ MemStream::operator FILE * ()
+ {
+ return strm;
+ }
+
+ MemStream::operator const char * () const
+ {
+ fflush(strm);
+ return buf;
+ }
+
+ MemStream::operator std::string_view() const
+ {
+ fflush(strm);
+ return { buf, len };
+ }
+
+ const char * MemStream::buffer() const
+ {
+ return *this;
+ }
+
+ std::string_view MemStream::sv() const
+ {
+ return *this;
+ }
+
+ size_t MemStream::length() const
+ {
+ fflush(strm);
+ return len;
+ }
+}
+
diff --git a/libadhocutil/memstream.h b/libadhocutil/memstream.h
new file mode 100644
index 0000000..b807d8b
--- /dev/null
+++ b/libadhocutil/memstream.h
@@ -0,0 +1,36 @@
+#ifndef LIBADHOC_MEMSTREAM_H
+#define LIBADHOC_MEMSTREAM_H
+
+#include <visibility.h>
+#include <cstdio>
+#include <string_view>
+
+namespace AdHoc {
+ class DLL_PUBLIC MemStream {
+ public:
+ MemStream();
+ ~MemStream();
+
+ MemStream(const MemStream &) = delete;
+ MemStream(MemStream &&) = delete;
+
+ void operator=(const MemStream &) = delete;
+ void operator=(MemStream &&) = delete;
+
+ operator FILE * ();
+ operator const char * () const;
+ operator std::string_view () const;
+
+ const char * buffer() const;
+ std::string_view sv() const;
+ size_t length() const;
+
+ private:
+ char * buf;
+ size_t len;
+ FILE * strm;
+ };
+}
+
+#endif
+
diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam
index 6b04540..0b749a8 100644
--- a/libadhocutil/unittests/Jamfile.jam
+++ b/libadhocutil/unittests/Jamfile.jam
@@ -287,3 +287,11 @@ run
<library>boost_utf
;
+run
+ testMemStream.cpp
+ : : :
+ <define>BOOST_TEST_DYN_LINK
+ <library>..//adhocutil
+ <library>boost_utf
+ ;
+
diff --git a/libadhocutil/unittests/testMemStream.cpp b/libadhocutil/unittests/testMemStream.cpp
new file mode 100644
index 0000000..b244b5e
--- /dev/null
+++ b/libadhocutil/unittests/testMemStream.cpp
@@ -0,0 +1,34 @@
+#define BOOST_TEST_MODULE NvpParse
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+#include "memstream.h"
+
+using namespace AdHoc;
+
+BOOST_FIXTURE_TEST_SUITE(s, MemStream);
+
+BOOST_AUTO_TEST_CASE(empty)
+{
+ BOOST_CHECK_EQUAL("", this->sv());
+ BOOST_CHECK_EQUAL("", this->buffer());
+ BOOST_CHECK_EQUAL(0, this->sv().length());
+ BOOST_CHECK_EQUAL(0, this->length());
+}
+
+using cast_types = boost::mpl::list<const char *, std::string_view, FILE *>;
+BOOST_AUTO_TEST_CASE_TEMPLATE(casts, T, cast_types )
+{
+ auto dummy = [](const T &) { };
+ dummy(*this);
+}
+
+BOOST_AUTO_TEST_CASE(simple)
+{
+ auto len = fprintf(*this, "Some %s write.", "simple");
+ BOOST_CHECK_EQUAL("Some simple write.", this->buffer());
+ BOOST_CHECK_EQUAL(len, this->length());
+}
+
+BOOST_AUTO_TEST_SUITE_END();
+