Commit cb697dfe authored by Niels Möller's avatar Niels Möller
Browse files

New zlib-related files.

Rev: src/abstract_compress.c:1.1
Rev: src/abstract_compress.h:1.1
Rev: src/compress.c:1.1
Rev: src/compress.h:1.1
Rev: src/zlib.c:1.10
Rev: src/zlib.h:1.4(DEAD)
parent 2377f8f6
/* zlib.h
/* abstract_compress.c
*
* Processor to compress packets using zlib
*
* $Id$ */
* interface to compression algorithms...
*
* $Id$
*/
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
* Copyright (C) 1998 Balazs Scheidler, Niels Möller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -23,17 +24,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_ZLIB_H_INCLUDED
#define LSH_ZLIB_H_INCLUDED
/* The input to the compressor should be a packet with payload only. */
struct zlib_processor
{
struct abstract_write_pipe c;
z_stream state;
}
struct packet_processor *make_zlib_processor(packet_processor *continuation,
level);
#include "abstract_compress.h"
#endif /* LSH_ZLIB_H_INCLUDED */
#define CLASS_DEFINE
#include "abstract_compress.h.x"
#undef CLASS_DEFINE
/* abstract_compress.h
*
* interface to compression algorithms...
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Balazs Scheidler, Niels Mller
*
* 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 of the
* License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_ABSTRACT_COMPRESS_H_INCLUDED
#define LSH_ABSTRACT_COMPRESS_H_INCLUDED
#include "lsh_types.h"
#define CLASS_DECLARE
#include "abstract_compress.h.x"
#undef CLASS_DECLARE
/* CLASS:
(class
(name compress_instance)
(vars
(codec method (string)
"struct lsh_string *data" "int free")))
*/
#define CODEC(instance, packet, free) \
((instance)->codec((instance), (packet), (free)))
#define COMPRESS_DEFLATE 0
#define COMPRESS_INFLATE 1
/* CLASS:
(class
(name compress_algorithm)
(vars
(make_compress method (object compress_instance)
"int mode")))
*/
#define MAKE_CODEC(algo, mode) \
((algo)->make_compress((algo), (mode)))
#define MAKE_DEFLATE(algo) MAKE_CODEC((algo), COMPRESS_DEFLATE)
#define MAKE_INFLATE(algo) MAKE_CODEC((algo), COMPRESS_INFLATE)
#endif
/* compress.c
*
* packet compressor
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Balazs Scheidler, Niels Möller
*
* 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 of the
* License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "lsh_types.h"
#include "xalloc.h"
#include "compress.h"
#include "compress.c.x"
/* CLASS:
(class
(name packet_compressor)
(super abstract_write_pipe)
(vars
(compressor object compress_instance)
(connection object ssh_connection)
(mode simple int)))
*/
static int do_packet_deflate(struct abstract_write *closure,
struct lsh_string *packet)
{
CAST(packet_compressor, self, closure);
return A_WRITE(self->super.next,
(self->connection->send_compress
? CODEC(self->connection->send_compress, packet, 1)
: packet));
}
static int do_packet_inflate(struct abstract_write *closure,
struct lsh_string *packet)
{
CAST(packet_compressor, self, closure);
return A_WRITE(self->super.next,
(self->connection->rec_compress
? CODEC(self->connection->rec_compress, packet, 1)
: packet));
}
struct abstract_write *make_packet_codec(struct abstract_write *next,
struct ssh_connection *connection,
int mode)
{
NEW(packet_compressor, res);
res->super.super.write = (mode == COMPRESS_INFLATE)
? do_packet_inflate
: do_packet_deflate;
res->super.next = next;
res->connection = connection;
return &res->super.super;
}
/* compress.h
*
* header for compression algorithms
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Balazs Scheidler, Niels Möller
*
* 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 of the
* License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LSH_COMPRESS_H_INCLUDED
#define LSH_COMPRESS_H_INCLUDED
#include "abstract_io.h"
#include "abstract_compress.h"
#include "connection.h"
struct compress_algorithm *make_zlib_algorithm(int level);
struct compress_algorithm *make_zlib(void);
struct abstract_write *make_packet_codec(struct abstract_write *next,
struct ssh_connection *connection,
int mode);
#define make_packet_deflate(next, connection) \
make_packet_codec(next, connection, COMPRESS_DEFLATE)
#define make_packet_inflate(next, connection) \
make_packet_codec(next, connection, COMPRESS_INFLATE)
#endif /* LSH_COMPRESS_H_INCLUDED */
/* zlib.c
*
* zlib compression algorithm
*
*
* $Id$ */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 1998 Niels Möller
* Copyright (C) 1998 Balazs Scheidler, Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
......@@ -23,34 +23,186 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "zlib.h"
#include "compress.h"
#include "format.h"
#include "werror.h"
#include "xalloc.h"
#include <zlib.h>
static void do_free_zstream(z_stream *z);
#include "zlib.c.x"
/* CLASS:
(class
(name zlib_instance)
(super compress_instance)
(vars
(zstream special-struct z_stream
#f do_free_zstream)))
*/
/* CLASS:
(class
(name zlib_algorithm)
(super compress_algorithm)
(vars
(level . int)))
*/
/* zlib memory functions */
static void *zlib_alloc(void *opaque UNUSED, unsigned int items, unsigned int size)
{
return lsh_space_alloc(items * size);
}
static void zlib_free(void *opaque UNUSED, void *address)
{
lsh_space_free(address);
}
#error zlib.c not working at all
static char foo_inflate[] = "inflate";
static char foo_deflate[] = "deflate";
static int do_deflate(struct abstract_write *w,
struct lsh_string *packet)
static void do_free_zstream(z_stream *z)
{
CAST(zlib_processor, closure, w);
/* Call deflteEnd() or inflateEnd(). But which? We use the opague
* pointer, as we don't use that for anything else. */
int res;
if (z->opaque == foo_inflate)
res = inflateEnd(z);
else if (z->opaque == foo_deflate)
res = deflateEnd(z);
else
fatal("Internal error!\n");
if (res != Z_OK)
werror("do_free_zstream: Freeing failed: %s\n",
z->msg ? z->msg : "No error");
}
/* compress incoming data */
static struct lsh_string *do_zlib_deflate(struct compress_instance *c,
struct lsh_string *data,
int free)
{
CAST(zlib_instance, self, c);
struct lsh_string *chunk, *compressed;
int rc;
/* deflated packet may be longer */
chunk = lsh_string_alloc(2 * data->length + 10);
self->zstream.next_in = (char *) &data->data;
self->zstream.avail_in = data->length;
compressed = NULL;
struct lsh_string *new;
while (self->zstream.avail_in)
{
self->zstream.next_out = (char *) &chunk->data;
self->zstream.avail_out = 2 * data->length + 10;
self->zstream.total_out = 0;
rc = deflate(&self->zstream, Z_SYNC_FLUSH);
if (compressed) {
compressed = ssh_format("%lfS%ls", compressed,
self->zstream.total_out, chunk->data);
}
else {
compressed = ssh_format("%ls", self->zstream.total_out, chunk->data);
}
}
lsh_string_free(chunk);
/* call deflate, copy into new packet */
if (free)
lsh_string_free(data);
return compressed;
}
/* decompress incoming data */
static struct lsh_string *do_zlib_inflate(struct compress_instance *c,
struct lsh_string *data,
int free)
{
CAST(zlib_instance, self, c);
struct lsh_string *chunk, *uncompressed;
int rc;
new = lsh_string_alloc(...);
lsh_string_free(packet);
/* let's assume data can be compressed to 50% */
return apply_processor(closure->c->next, new);
chunk = lsh_string_alloc(2 * data->length + 10);
self->zstream.next_in = (char *) &data->data;
self->zstream.avail_in = data->length;
uncompressed = NULL;
while (self->zstream.avail_in)
{
self->zstream.next_out = (char *) &chunk->data;
self->zstream.avail_out = 2 * data->length + 10;
self->zstream.total_out = 0;
rc = inflate(&self->zstream, Z_SYNC_FLUSH);
if (uncompressed) {
uncompressed = ssh_format("%lfS%ls", uncompressed,
self->zstream.total_out, chunk->data);
}
else {
uncompressed = ssh_format("%ls", self->zstream.total_out, chunk->data);
}
}
lsh_string_free(chunk);
if (free)
lsh_string_free(data);
return uncompressed;
}
struct abstract_write *make_packet_zlib(abstract_write *continuation,
int level)
static struct compress_instance *
make_zlib_instance(struct compress_algorithm *c, int mode)
{
struct zlib_processor *closure;
NEW(closure);
CAST(zlib_algorithm, closure, c);
NEW(zlib_instance, res);
res->zstream.zalloc = zlib_alloc;
res->zstream.zfree = zlib_free;
switch (mode)
{
case COMPRESS_DEFLATE:
res->zstream.opaque = foo_deflate;
res->super.codec = do_zlib_deflate;
deflateInit(&res->zstream, closure->level);
break;
case COMPRESS_INFLATE:
res->zstream.opaque = foo_inflate;
res->super.codec = do_zlib_inflate;
inflateInit(&res->zstream);
break;
}
return &res->super;
}
closure->super.super.write = do_deflate;
closure->c->next = continuation;
/* inititialize closure->zstream */
struct compress_algorithm *make_zlib_algorithm(int level)
{
if ( (level != Z_DEFAULT_COMPRESSION)
&& ( (level < Z_NO_COMPRESSION)
|| (level > Z_BEST_COMPRESSION) ))
return NULL;
else
{
NEW(zlib_algorithm, closure);
closure->super.make_compress = make_zlib_instance;
closure->level = level;
return &closure->super.super;
return &closure->super;
}
}
struct compress_algorithm *make_zlib(void)
{
return make_zlib_algorithm(Z_DEFAULT_COMPRESSION);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment