W dniu 16 marca 2010 00:22 użytkownik Krzysztof Kosiński <tweenk...@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; }
_______________________________________________ gtkmm-list mailing list gtkmm-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtkmm-list