#include <giomm.h>
#include <iostream>
#include <cstring>

namespace
{
  void destroy_func(void* data)
  {
    char* cdata = static_cast<char*>(data);
    // cdata is not null-terminated.
    std::cout << "Deleting " << std::string(cdata, cdata+7);
    delete[] cdata;
  }
}

int main(int, char**)
{
  Glib::init();
  Gio::init();

  try
  {
    Glib::RefPtr<Gio::MemoryInputStream> stream = Gio::MemoryInputStream::create();
    if(!stream)
    {
      std::cerr << "Could not create a MemoryInputStream." << std::endl;
      return EXIT_FAILURE; 
    }

    // Add data that shall not be deleted by stream.
    static const char data1[] = "Data not owned by stream.\n";
    stream->add_data(data1, sizeof data1 - 1, 0);

    // Add data that shall be deleted by destroy_func().
    char* data2 = new char[7];
    std::strcpy(data2, "data2\n");
    stream->add_data(data2, 6, destroy_func);

    // Add data that shall be deleted by destroy_func(), but use a sigc::slot.
    char* data3 = new char[7];
    std::strcpy(data3, "data3\n");
    stream->add_data(data3, 6, sigc::ptr_fun(destroy_func));

    gchar buffer[1000];
    std::memset(buffer, 0, sizeof buffer);
    const gsize bytes_read = stream->read(buffer, sizeof buffer - 1);

    if (bytes_read)
      std::cout << "Memory contents read: " << buffer << std::endl;
    else
    {
      std::cerr << "Gio::InputStream::read() read 0 bytes." << std::endl;
      return EXIT_FAILURE; 
    }
  }
  catch(const Glib::Exception& ex)
  {
    std::cerr << "Exception caught: " << ex.what() << std::endl;
    return EXIT_FAILURE; 
  }

  return EXIT_SUCCESS;
}
