summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjell.ahlstedt@bredband.net>2016-11-21 16:27:27 +0100
committerKjell Ahlstedt <kjell.ahlstedt@bredband.net>2016-11-21 16:27:27 +0100
commit4aff300e67f0ec088297e6301d9fa2313acee565 (patch)
tree22b40785cee0dc887a85077e7c229298e99b5947 /tests
parent990b15acae0e9f0288a1cefdc72b70b0e87b7c0f (diff)
downloadglibmm-4aff300e67f0ec088297e6301d9fa2313acee565.tar.gz
Add tests/giomm_stream_vfuncs
* tests/Makefile.am: Add giomm_stream_vfuncs. * tests/giomm_stream_vfuncs/main.cc: New file. An updated version of a patch by Krzysztof KosiƄski <tweenk.pl@gmail.com> Bug #572471
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/giomm_stream_vfuncs/main.cc170
2 files changed, 174 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0db1869c..bbe85ae4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,6 +22,7 @@ check_PROGRAMS = \
giomm_ioerror_and_iodbuserror/test \
giomm_memoryinputstream/test \
giomm_simple/test \
+ giomm_stream_vfuncs/test \
giomm_asyncresult_sourceobject/test \
giomm_tls_client/test \
giomm_listmodel/test \
@@ -78,6 +79,9 @@ giomm_memoryinputstream_test_LDADD = $(giomm_ldadd)
giomm_simple_test_SOURCES = giomm_simple/main.cc
giomm_simple_test_LDADD = $(giomm_ldadd)
+giomm_stream_vfuncs_test_SOURCES = giomm_stream_vfuncs/main.cc
+giomm_stream_vfuncs_test_LDADD = $(giomm_ldadd)
+
giomm_asyncresult_sourceobject_test_SOURCES = giomm_asyncresult_sourceobject/main.cc
giomm_asyncresult_sourceobject_test_LDADD = $(giomm_ldadd)
diff --git a/tests/giomm_stream_vfuncs/main.cc b/tests/giomm_stream_vfuncs/main.cc
new file mode 100644
index 00000000..f70a1fa8
--- /dev/null
+++ b/tests/giomm_stream_vfuncs/main.cc
@@ -0,0 +1,170 @@
+/* Copyright (C) 2016 The giomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <giomm.h>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+
+// A simple custom stream that base64 encodes data.
+// Do not copy it to your code, because it's very slow.
+class Base64OutputStream : public Gio::FilterOutputStream
+{
+public:
+ unsigned get_column_width() const { return column_width; }
+ void set_column_width(unsigned cw) { column_width = cw; }
+ static Glib::RefPtr<Base64OutputStream> create(const Glib::RefPtr<OutputStream>& base_stream)
+ {
+ return Glib::RefPtr<Base64OutputStream>(new Base64OutputStream(base_stream));
+ }
+
+protected:
+ Base64OutputStream(const Glib::RefPtr<Gio::OutputStream>& base_stream)
+ : Gio::FilterOutputStream(base_stream), column(0), bit_count(0), bit_buffer(0), column_width(72) {}
+
+ gssize write_vfunc(const void* buffer, gsize count, const Glib::RefPtr<Gio::Cancellable>& cancellable) override
+ {
+ char const *byte = (char const *) buffer;
+ for (unsigned i = 0; i < count; ++i, ++byte)
+ {
+ // kindergarten implementation, because the object is not performance :)
+ bit_buffer <<= 8;
+ bit_buffer |= (*byte & 0xff);
+ bit_count += 8;
+
+ if (bit_count == 24)
+ {
+ clear_pending(); // TODO why is this necessary to avoid an outstanding op. exception?
+ flush(cancellable);
+ set_pending();
+ bit_count = 0;
+ }
+
+ if (cancellable && cancellable->is_cancelled())
+ throw Gio::Error(Gio::Error::CANCELLED, "Operation cancelled");
+ }
+ return count;
+ }
+
+ bool flush_vfunc(const Glib::RefPtr<Gio::Cancellable>& cancellable) override
+ {
+ if (bit_count != 24)
+ return true;
+ char to_write[5];
+ gsize len = 4;
+
+ for (unsigned i=0; i<4; ++i)
+ {
+ unsigned index = (bit_buffer & (0x3f<<(i*6))) >> (i*6);
+ to_write[3-i] = base64_encode_str[index];
+ }
+ column += 4;
+ // Yes, I know this is completely wrong.
+ if (column >= column_width)
+ {
+ column = 0;
+ to_write[4] = '\n';
+ ++len;
+ }
+
+ get_base_stream()->write(&to_write, len, cancellable);
+
+ bit_count = 0;
+ bit_buffer = 0;
+
+ return true;
+ }
+
+ bool close_vfunc(const Glib::RefPtr<Gio::Cancellable>& cancellable) override
+ {
+ char to_write[5] = "====";
+ //get any last bytes (1 or 2) out of the buffer
+ switch (bit_count)
+ {
+ case 16:
+ bit_buffer <<= 2; //pad to make 18 bits
+ to_write[0] = base64_encode_str[(bit_buffer & (0x3f << 12)) >> 12];
+ to_write[1] = base64_encode_str[(bit_buffer & (0x3f << 6)) >> 6];
+ to_write[2] = base64_encode_str[bit_buffer & 0x3f];
+ break;
+
+ case 8:
+ bit_buffer <<= 4; //pad to make 12 bits
+ to_write[0] = base64_encode_str[(bit_buffer & (0x3f << 6)) >> 6];
+ to_write[1] = base64_encode_str[bit_buffer & 0x3f];
+ break;
+ }
+
+ if (bit_count > 0)
+ {
+ get_base_stream()->write(&to_write, 5, cancellable);
+ }
+ else
+ {
+ // null terminate output
+ get_base_stream()->write("", 1, cancellable);
+ }
+ if (get_close_base_stream())
+ get_base_stream()->close(cancellable);
+
+ return true;
+ }
+
+private:
+ static char const *const base64_encode_str;
+ unsigned column;
+ unsigned bit_count;
+ unsigned bit_buffer;
+ unsigned column_width;
+};
+
+char const *const Base64OutputStream::base64_encode_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+int main(int, char**)
+{
+ Glib::init();
+ Gio::init();
+
+ try
+ {
+ char result[256];
+ Glib::RefPtr<Gio::MemoryOutputStream> memory_chunk = Gio::MemoryOutputStream::create(result, 256, nullptr, nullptr);
+ Glib::RefPtr<Base64OutputStream> base64 = Base64OutputStream::create(memory_chunk);
+
+ std::string data = "Custom GIO streams are cool!";
+
+ base64->set_close_base_stream(true);
+ base64->write(data);
+ base64->close();
+
+ const std::string base64_should_be("Q3VzdG9tIEdJTyBzdHJlYW1zIGFyZSBjb29sIQ==");
+ std::cout << "Original data: " << data << std::endl;
+ std::cout << "base64-encoded data: " << result << std::endl;
+ std::cout << "base64 should be: " << base64_should_be << std::endl;
+ if (base64_should_be != result)
+ {
+ std::cout << "Not correct!" << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ catch (Gio::Error e)
+ {
+ std::cout << "Gio error: " << e.what() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}