Re: Gtk::Main::iteration();



W dniu 16 marca 2010 00:22 użytkownik Krzysztof Kosiński
<tweenk pl gmail com> napisał:
> See attached file.
> This is a simple program that uses only async calls to zero the
> contents of a file.
> Compile with:
> g++ gio-zero.cpp -o gio-zero `pkg-config --cflags --libs giomm-2.4 gthread-2.0`
>
> This example exposes a serious API bug, which I'll report; fortunately
> there is a workaround. See function get_file in the example.
>
> Regards, Krzysztof
>

Forgot the atachment :)

PS if you still have any problems, I can explain in Polish on GMail chat.

Regards, Krzysztof
#include <glibmm.h>
#include <giomm.h>
#include <cstring>

static gsize const zeros_size = 262144; // tweak this to your liking
Glib::RefPtr<Glib::MainLoop> loop;

void zero_file(Glib::RefPtr<Gio::File> &);
static void zero_query_info_callback(Glib::RefPtr<Gio::AsyncResult> &);
static void zero_replace_callback(Glib::RefPtr<Gio::AsyncResult> &, goffset);
static void zero_write(Glib::RefPtr<Gio::OutputStream> &, goffset, char *);
static void zero_write_callback(Glib::RefPtr<Gio::AsyncResult> &, goffset, char *);
static void zero_final_write_callback(Glib::RefPtr<Gio::AsyncResult> &, char *);
static void zero_close_callback(Glib::RefPtr<Gio::AsyncResult> &);
static Glib::RefPtr<Gio::File> get_file(Glib::RefPtr<Gio::AsyncResult> &);

void zero_file(Glib::RefPtr<Gio::File> &file) {
  file->query_info_async(sigc::ptr_fun(zero_query_info_callback));
}

void zero_query_info_callback(Glib::RefPtr<Gio::AsyncResult> &result) {
  Glib::RefPtr<Gio::File> f = get_file(result);
  Glib::RefPtr<Gio::FileInfo> info = f->query_info_finish(result);

  goffset file_size = info->get_size();

  f->replace_async(
    sigc::bind(
      sigc::ptr_fun(zero_replace_callback),
      file_size));
}

// Whis is called when the replace operation completes.
// We get an OutputStream that we can write to as the result.
void zero_replace_callback(Glib::RefPtr<Gio::AsyncResult> &result, goffset file_size) {
  Glib::RefPtr<Gio::File> f = get_file(result);
  Glib::RefPtr<Gio::OutputStream> out = f->replace_finish(result);

  // allocate 256k of zero bytes
  char *zeros = new char[zeros_size];
  std::memset(zeros, 0, zeros_size);

  zero_write(out, file_size, zeros);
}

// This writes chunks of zeros into the stream.
void zero_write(Glib::RefPtr<Gio::OutputStream> &out, goffset remaining_size, char *zeros) {
  if (static_cast<goffset>(zeros_size) >= remaining_size) {
    out->write_async(static_cast<void*>(zeros), static_cast<gsize>(remaining_size),
      sigc::bind(
        sigc::ptr_fun(zero_final_write_callback),
        zeros));
  } else {
    out->write_async(static_cast<void*>(zeros), zeros_size,
      sigc::bind(
        sigc::bind(
          sigc::ptr_fun(zero_write_callback),
          zeros),
        remaining_size - static_cast<goffset>(zeros_size)));
  }
}

// Gets called when there are still some zeros to write.
void zero_write_callback(Glib::RefPtr<Gio::AsyncResult> &result, goffset remaining_size, char *zeros) {
  Glib::RefPtr<Gio::OutputStream> out =
    Glib::RefPtr<Gio::OutputStream>::cast_dynamic(result->get_source_object());
  zero_write(out, remaining_size, zeros);
}

// Gets called when everything was written. Clean up here.
void zero_final_write_callback(Glib::RefPtr<Gio::AsyncResult> &result, char *zeros) {
  delete [] zeros;
  Glib::RefPtr<Gio::OutputStream> out =
    Glib::RefPtr<Gio::OutputStream>::cast_dynamic(result->get_source_object());
  out->close_async(sigc::ptr_fun(zero_close_callback));
}

void zero_close_callback(Glib::RefPtr<Gio::AsyncResult> &) {
  // notify your application that the write completed here.

  loop->quit();
}

Glib::RefPtr<Gio::File> get_file(Glib::RefPtr<Gio::AsyncResult> &result) {
  // This is a work-around for broken API.
  // result->get_source_object() return a Glib::RefPtr<Glib::Object>,
  // but Gio::File is not derived from Glib::Object, so when Gio::File
  // is the source object we always get NULL.
  return Glib::wrap(G_FILE(g_async_result_get_source_object(result->gobj())));
}

int main(int argc, char *argv[]) {
  if (argc != 2) return 0;
  char *filepath = argv[1];

  g_thread_init(NULL);
  Glib::init();
  Gio::init();

  // Put the code below in the place you want to overwrite the file with zeros.
  // You may need to replace create_for_commandline_arg with a different
  // file creation function, based on where the path comes from.
  Glib::RefPtr<Gio::File> file_to_zero = Gio::File::create_for_commandline_arg(filepath);
  zero_file(file_to_zero);

  loop = Glib::MainLoop::create();
  loop->run();

  return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]