2 * ngIRCd -- The Next Generation IRC Daemon
3 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * Please read the file COPYING, README and AUTHORS for more information.
11 * Connection compression using ZLIB
17 #define __conn_zip_c__
22 static char UNUSED id[] = "$Id: conn-zip.c,v 1.1 2002/12/30 16:07:23 alex Exp $";
37 Zip_InitConn( CONN_ID Idx )
39 /* Kompression fuer Link initialisieren */
43 My_Connections[Idx].zip.in.avail_in = 0;
44 My_Connections[Idx].zip.in.total_in = 0;
45 My_Connections[Idx].zip.in.total_out = 0;
46 My_Connections[Idx].zip.in.zalloc = NULL;
47 My_Connections[Idx].zip.in.zfree = NULL;
48 My_Connections[Idx].zip.in.data_type = Z_ASCII;
50 if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
53 Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
57 My_Connections[Idx].zip.out.total_in = 0;
58 My_Connections[Idx].zip.out.total_in = 0;
59 My_Connections[Idx].zip.out.zalloc = NULL;
60 My_Connections[Idx].zip.out.zfree = NULL;
61 My_Connections[Idx].zip.out.data_type = Z_ASCII;
63 if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
66 Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
70 My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in;
71 My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out;
73 Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
74 Conn_SetOption( Idx, CONN_ZIP );
81 Zip_Buffer( CONN_ID Idx, CHAR *Data, INT Len )
83 /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
84 * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
87 assert( Data != NULL );
90 /* Ist noch Platz im Kompressions-Puffer? */
91 if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 )
93 /* Nein! Puffer zunaechst leeren ...*/
94 if( ! Zip_Flush( Idx )) return FALSE;
98 memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len );
99 My_Connections[Idx].zip.wdatalen += Len;
106 Zip_Flush( CONN_ID Idx )
108 /* Daten komprimieren und in Schreibpuffer kopieren.
109 * Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
114 out = &My_Connections[Idx].zip.out;
116 out->next_in = My_Connections[Idx].zip.wbuf;
117 out->avail_in = My_Connections[Idx].zip.wdatalen;
118 out->next_out = My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen;
119 out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen;
121 result = deflate( out, Z_SYNC_FLUSH );
122 if(( result != Z_OK ) || ( out->avail_in > 0 ))
124 Log( LOG_ALERT, "Compression error: code %d!?", result );
125 Conn_Close( Idx, "Compression error!", NULL, FALSE );
129 out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out;
130 My_Connections[Idx].wdatalen += out_len;
131 My_Connections[Idx].bytes_out += out_len;
132 My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen;
133 My_Connections[Idx].zip.wdatalen = 0;
140 Unzip_Buffer( CONN_ID Idx )
142 /* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
143 * wird FALSE geliefert, ansonsten TRUE. Der Fall, dass keine
144 * Daten mehr zu entpacken sind, ist _kein_ Fehler! */
146 INT result, in_len, out_len;
149 assert( Idx > NONE );
151 if( My_Connections[Idx].zip.rdatalen <= 0 ) return TRUE;
153 in = &My_Connections[Idx].zip.in;
155 in->next_in = My_Connections[Idx].zip.rbuf;
156 in->avail_in = My_Connections[Idx].zip.rdatalen;
157 in->next_out = My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen;
158 in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1;
160 result = inflate( in, Z_SYNC_FLUSH );
163 Log( LOG_ALERT, "Decompression error: code %d (ni=%d, ai=%d, no=%d, ao=%d)!?", result, in->next_in, in->avail_in, in->next_out, in->avail_out );
164 Conn_Close( Idx, "Decompression error!", NULL, FALSE );
168 in_len = My_Connections[Idx].zip.rdatalen - in->avail_in;
169 out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out;
170 My_Connections[Idx].rdatalen += out_len;
172 if( in->avail_in > 0 )
174 /* es konnten nicht alle Daten entpackt werden, vermutlich war
175 * im Ziel-Puffer kein Platz mehr. Umkopieren ... */
176 My_Connections[Idx].zip.rdatalen -= in_len;
177 memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen );
179 else My_Connections[Idx].zip.rdatalen = 0;
180 My_Connections[Idx].zip.bytes_in += out_len;
187 Zip_SendBytes( CONN_ID Idx )
189 /* Anzahl gesendeter Bytes (komprimiert!) liefern */
191 assert( Idx > NONE );
192 return My_Connections[Idx].zip.bytes_out;
193 } /* Zip_SendBytes */
197 Zip_RecvBytes( CONN_ID Idx )
199 /* Anzahl gesendeter Bytes (komprimiert!) liefern */
201 assert( Idx > NONE );
202 return My_Connections[Idx].zip.bytes_in;
203 } /* Zip_RecvBytes */