X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libdocument%2Fev-file-helpers.c;h=d9b6448418b1739e33196265d76a37f433e5cb89;hb=21f638ab8e3ddb81ce7979939defcdb7f49ad376;hp=b6a50b6f8c470a5f1dbce4710007af53c496e95f;hpb=13a06349251874bd35d2f03c3fc93217cee749a2;p=evince.git diff --git a/libdocument/ev-file-helpers.c b/libdocument/ev-file-helpers.c index b6a50b6f..d9b64484 100644 --- a/libdocument/ev-file-helpers.c +++ b/libdocument/ev-file-helpers.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "ev-file-helpers.h" @@ -167,3 +168,116 @@ ev_xfer_uri_simple (const char *from, return (result == GNOME_VFS_OK); } + +/* Compressed files support */ +#define BZIPCOMMAND "bzip2" +#define GZIPCOMMAND "gzip" +#define N_ARGS 4 +#define BUFFER_SIZE 1024 + +static gchar * +compression_run (const gchar *uri, + EvCompressionType type, + gboolean compress, + GError **error) +{ + gchar *argv[N_ARGS]; + gchar *uri_dst = NULL; + gchar *filename, *filename_dst; + gchar *cmd; + gint fd, pout; + + if (type == EV_COMPRESSION_NONE) + return NULL; + + cmd = g_find_program_in_path ((type == EV_COMPRESSION_BZIP2) ? BZIPCOMMAND : GZIPCOMMAND); + if (!cmd) + return NULL; + + filename = g_filename_from_uri (uri, NULL, NULL); + if (!filename) { + g_free (cmd); + return NULL; + } + + filename_dst = g_build_filename (ev_tmp_dir (), "evinceXXXXXX", NULL); + fd = g_mkstemp (filename_dst); + if (fd < 0) { + g_free (cmd); + g_free (filename); + g_free (filename_dst); + return NULL; + } + + argv[0] = cmd; + argv[1] = compress ? "-c" : "-cd"; + argv[2] = filename; + argv[3] = NULL; + + if (g_spawn_async_with_pipes (NULL, argv, NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, + NULL, &pout, NULL, error)) { + GIOChannel *in, *out; + gchar buf[BUFFER_SIZE]; + GIOStatus read_st, write_st; + gsize bytes_read, bytes_written; + + in = g_io_channel_unix_new (pout); + g_io_channel_set_encoding (in, NULL, NULL); + out = g_io_channel_unix_new (fd); + g_io_channel_set_encoding (out, NULL, NULL); + + do { + read_st = g_io_channel_read_chars (in, buf, + BUFFER_SIZE, + &bytes_read, + error); + if (read_st == G_IO_STATUS_NORMAL) { + write_st = g_io_channel_write_chars (out, buf, + bytes_read, + &bytes_written, + error); + if (write_st == G_IO_STATUS_ERROR) + break; + } else if (read_st == G_IO_STATUS_ERROR) { + break; + } + } while (bytes_read > 0); + + g_io_channel_unref (in); + g_io_channel_unref (out); + } + + close (fd); + + if (*error == NULL) { + uri_dst = g_filename_to_uri (filename_dst, NULL, NULL); + } + + g_free (cmd); + g_free (filename); + g_free (filename_dst); + + return uri_dst; +} + +gchar * +ev_file_uncompress (const gchar *uri, + EvCompressionType type, + GError **error) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return compression_run (uri, type, FALSE, error); +} + +gchar * +ev_file_compress (const gchar *uri, + EvCompressionType type, + GError **error) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return compression_run (uri, type, TRUE, error); +}