/* * Copyright (C) 2004 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Authors: * Mark McLoughlin */ #include #include #define FILE_PATH "/etc/services" #define CHUNK_LEN 256 static z_stream inflate_stream; static gboolean do_decompression (const char *buf, int len) { z_stream *zs = &inflate_stream; char outbuf [1024 * 5]; zs->next_in = (char *) buf; zs->avail_in = len; while (1) { int ret; zs->next_out = outbuf; zs->avail_out = sizeof (outbuf); ret = inflate (zs, Z_SYNC_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) { g_print ("inflate returned %d: %s\n", ret, zs->msg ? zs->msg : ""); return FALSE; } if (ret == Z_STREAM_END) { g_print ("Reached end of stream\n"); inflateReset (zs); } if (zs->avail_in == 0) break; } return TRUE; } static gboolean do_compression (z_stream *zs, int flush, const char *contents, int len) { char outbuf [32]; g_print ("Compressing %d bytes with %s(%d) flush\n", len, flush == Z_SYNC_FLUSH ? "sync" : "full", flush); zs->next_in = (char *) contents; zs->avail_in = len; while (1) { int ret; zs->next_out = outbuf; zs->avail_out = sizeof (outbuf); ret = deflate (zs, flush); if (ret != Z_OK && ret != Z_STREAM_END) { g_print ("deflate returned %d: %s\n", ret, zs->msg ? zs->msg : ""); g_print ("\n---\n"); return FALSE; } g_assert (do_decompression (outbuf, sizeof (outbuf) - zs->avail_out)); if (zs->avail_out != 0) { g_print ("Finished compressing - %d bytes in final chunk\n", sizeof (outbuf) - zs->avail_out); break; } g_print ("Wrote out a 32 byte chunk\n"); } g_assert (zs->avail_in == 0); g_print ("\n---\n"); return TRUE; } int main (int argc, char **argv) { char *contents; gsize len; GError *error; z_stream zs; char *chunk; int chunk_len; inflate_stream.zalloc = Z_NULL; inflate_stream.zfree = Z_NULL; inflate_stream.opaque = Z_NULL; if (inflateInit (&inflate_stream) != Z_OK) { g_warning ("Unable to initialize the decompression stream: %s\n", inflate_stream.msg ? inflate_stream.msg : ""); return 1; } contents = NULL; len = 0; error = NULL; if (!g_file_get_contents (FILE_PATH, &contents, &len, &error)) { g_warning ("Unable to read '%s': %s", FILE_PATH, error->message); g_error_free (error); return 1; } g_print ("Read %d bytes from %s\n", len, FILE_PATH); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if (deflateInit (&zs, Z_DEFAULT_COMPRESSION) != Z_OK) { g_warning ("Unable to initialize the compression stream: %s", zs.msg ? zs.msg : ""); return 1; } chunk_len = CHUNK_LEN; chunk = contents; /* Write all but the last chunk with this stream */ while (len > chunk_len) { /* Use finish the stream with the last chunk */ int flush = (len - chunk_len) > chunk_len ? Z_SYNC_FLUSH : Z_FINISH; g_assert (do_compression (&zs, flush, chunk, chunk_len)); chunk += chunk_len; len -= chunk_len; } deflateEnd (&zs); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.opaque = Z_NULL; if (deflateInit (&zs, Z_DEFAULT_COMPRESSION) != Z_OK) { g_warning ("Unable to initialize the compression stream: %s", zs.msg ? zs.msg : ""); return 1; } g_assert (do_compression (&zs, Z_SYNC_FLUSH, chunk, len)); deflateEnd (&zs); g_free (contents); inflateEnd (&inflate_stream); return 0; }