Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cstream.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      cstream.cc
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "cstream.h"
00022 #include "htdebug.h"
00023 #include "htendian.h"
00024 #include "minilzo.h"
00025 #include "tools.h"
00026 
00027 #include <string.h>
00028 
00029 void    ht_compressed_stream::init(ht_stream *stream, bool own_stream, UINT granularity)
00030 {
00031         ht_layer_stream::init(stream, own_stream);
00032         if ((get_access_mode() & (FAM_READ | FAM_WRITE)) == (FAM_READ | FAM_WRITE)) {
00033                 // ht_compressed_stream cant be used for read and write access simultaneously
00034                 assert(0);
00035         }
00036         buffer = (byte *)smalloc(granularity);
00037         bufferpos = 0;
00038         buffersize = granularity;
00039 }
00040 
00041 void    ht_compressed_stream::done()
00042 {
00043         if (get_access_mode() & FAM_WRITE) {
00044                 flush_compressed();
00045         }
00046         if (buffer) free(buffer);
00047         ht_layer_stream::done();
00048 }
00049 
00050 bool ht_compressed_stream::flush_compressed()
00051 {
00052         if (bufferpos) {
00053                 byte *cbuf = (byte *)smalloc(bufferpos + bufferpos / 64 + 16 + 3);
00054                 byte *workbuf = (byte *)smalloc(LZO1X_1_MEM_COMPRESS);
00055                 lzo_uint cbuf_len;
00056                 byte n[4];
00057                 
00058                 lzo1x_1_compress(buffer, bufferpos, cbuf, &cbuf_len, workbuf);
00059 
00060                 free(workbuf);
00061 
00062                 create_foreign_int(n, bufferpos, 4, big_endian);
00063                 if (stream->write(n, 4)!=4) {
00064                         free(cbuf);
00065                         return false;
00066                 }                       
00067                 create_foreign_int(n, cbuf_len, 4, big_endian);
00068                 if (stream->write(n, 4)!=4) {
00069                         free(cbuf);
00070                         return false;
00071                 }                       
00072                 if (stream->write(cbuf, cbuf_len)!=cbuf_len) {
00073                         free(cbuf);
00074                         return false;
00075                 }                       
00076 
00077                 free(cbuf);
00078                 
00079                 bufferpos = 0;
00080         }
00081         return true;
00082 }
00083 
00084 bool ht_compressed_stream::flush_uncompressed()
00085 {
00086         if (bufferpos==0) {
00087                 free(buffer);
00088                 buffer = NULL;
00089 
00090                 UINT cbuf_len;
00091                 UINT uncompressed_len;
00092                 byte n[4];
00093 
00094                 if (stream->read(n, 4)!=4) return false;
00095                 uncompressed_len = create_host_int(n, 4, big_endian);
00096                 if (stream->read(n, 4)!=4) return false;
00097                 cbuf_len = create_host_int(n, 4, big_endian);
00098 
00099                 buffer = (byte *)smalloc(uncompressed_len);
00100                 byte *cbuf = (byte *)smalloc(cbuf_len);
00101                 if (stream->read(cbuf, cbuf_len)!=cbuf_len) {
00102                         free(cbuf);
00103                         return false;
00104                 }
00105 
00106                 lzo_uint dummy;
00107                 lzo1x_decompress(cbuf, cbuf_len, buffer, &dummy, NULL);
00108                 assert(dummy == uncompressed_len);
00109 
00110                 free(cbuf);
00111 
00112                 buffersize = uncompressed_len;
00113                 bufferpos = uncompressed_len;          
00114         }
00115         return true;
00116 }
00117 
00118 UINT    ht_compressed_stream::read(void *aBuf, UINT size)
00119 {
00120         UINT ssize = size;
00121         byte *buf = (byte *)aBuf;
00122         while (size >= bufferpos) {
00123                 memcpy(buf, buffer+buffersize-bufferpos, bufferpos);
00124                 buf += bufferpos;
00125                 size -= bufferpos;
00126                 bufferpos = 0;
00127                 if (size) {
00128                         if (!flush_uncompressed()) return ssize - size;
00129                 } else break;
00130         }
00131         if (size) {
00132                 memcpy(buf, buffer+buffersize-bufferpos, size);
00133                 bufferpos -= size;
00134         }
00135         return ssize;
00136 }
00137 
00138 UINT    ht_compressed_stream::write(const void *aBuf, UINT size)
00139 {
00140         UINT ssize = size;
00141         const byte *buf = (const byte *)aBuf;
00142         while (bufferpos+size >= buffersize) {
00143                 memcpy(buffer+bufferpos, buf, buffersize-bufferpos);
00144                 size -= buffersize-bufferpos;
00145                 buf += buffersize-bufferpos;
00146                 bufferpos = buffersize;
00147                 if (size) {
00148                         if (!flush_compressed()) return ssize - size;
00149                 } else break;
00150         }
00151         if (size) {
00152                 memcpy(buffer+bufferpos, buf, size);
00153                 bufferpos += size;
00154         }
00155         return ssize;
00156 }

Generated on Fri May 7 21:15:29 2004 by doxygen 1.3.5