diff --git a/src/tl/tl/tlStream.cc b/src/tl/tl/tlStream.cc index 80fa4ef1a..2813a9114 100644 --- a/src/tl/tl/tlStream.cc +++ b/src/tl/tl/tlStream.cc @@ -43,7 +43,7 @@ #include "tlFileUtils.h" #include "tlLog.h" #include "tlResources.h" - +#include "tlBase64.h" #include "tlException.h" #include "tlString.h" #include "tlUri.h" @@ -242,6 +242,14 @@ InputStream::InputStream (const std::string &abstract_path) #endif + } else if (ex.test ("data:")) { + + std::vector data = tl::from_base64 (ex.get ()); + + char *data_ptr = new char [data.size ()]; + memcpy (data_ptr, data.begin ().operator-> (), data.size ()); + mp_delegate = new InputMemoryStream (data_ptr, data.size (), true); + } else if (ex.test ("pipe:")) { mp_delegate = new InputPipe (ex.get ()); diff --git a/src/tl/tl/tlStream.h b/src/tl/tl/tlStream.h index 9cd53a983..d34c630a3 100644 --- a/src/tl/tl/tlStream.h +++ b/src/tl/tl/tlStream.h @@ -122,13 +122,22 @@ public: * * @param data The memory block where to read from * @param length The length of the block + * @param owns_data If true, the memory becomes owned by the stream */ - InputMemoryStream (const char *data, size_t length) - : mp_data (data), m_length (length), m_pos (0) + InputMemoryStream (const char *data, size_t length, bool owns_data = false) + : mp_data (data), m_length (length), m_owns_data (owns_data), m_pos (0) { // .. nothing yet .. } + ~InputMemoryStream () + { + if (m_owns_data) { + delete [] const_cast (mp_data); + } + mp_data = 0; + } + virtual size_t read (char *b, size_t n) { if (m_pos + n > m_length) { @@ -170,7 +179,9 @@ private: InputMemoryStream &operator= (const InputMemoryStream &); const char *mp_data; - size_t m_length, m_pos; + size_t m_length; + bool m_owns_data; + size_t m_pos; }; /** diff --git a/src/tl/unit_tests/tlStreamTests.cc b/src/tl/unit_tests/tlStreamTests.cc index 236f7a72f..f55d53fd7 100644 --- a/src/tl/unit_tests/tlStreamTests.cc +++ b/src/tl/unit_tests/tlStreamTests.cc @@ -163,6 +163,23 @@ TEST(TextInputStream) } } +TEST(DataInputStream) +{ + tl::InputStream is ("data:SGVsbG8sIHdvcmxkIQpXaXRoIGFub3RoZXIgbGluZQoNDQpzZXBhcmF0ZWQgYnkgYSBMRkNSIGFuZCBDUkxGLg=="); + tl::TextInputStream tis (is); + EXPECT_EQ (tis.get_line (), "Hello, world!"); + EXPECT_EQ (tis.line_number (), size_t (1)); + EXPECT_EQ (tis.get_line (), "With another line"); + EXPECT_EQ (tis.line_number (), size_t (2)); + EXPECT_EQ (tis.peek_char (), '\n'); + EXPECT_EQ (tis.get_line (), ""); + EXPECT_EQ (tis.line_number (), size_t (3)); + EXPECT_EQ (tis.peek_char (), 's'); + EXPECT_EQ (tis.get_line (), "separated by a LFCR and CRLF."); + EXPECT_EQ (tis.line_number (), size_t (4)); + EXPECT_EQ (tis.at_end (), true); +} + namespace {