Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

vos/corelibs/typechain/handlers/type_z.cc

Go to the documentation of this file.
00001 /* $Id: type_z.cc,v 1.4 2003/07/25 06:13:39 tetron Exp $ */
00002 
00003 /*
00004     Copyright (C) 2003 Reed Hedges <reed@zerohour.net>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library 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 GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00019 */
00020 
00021 
00022 
00023 #include <sys/types.h>
00024 #include <sys/uio.h>
00025 #include <string>
00026 #include <fstream>
00027 #include <iostream>
00028 #include <math.h>
00029 #include <unistd.h>
00030 #include <fcntl.h>
00031 #include <stdio.h>
00032 #include <zlib.h>
00033 
00034 #include "type_z.hh"
00035 
00036 static const int GZREAD_BUFSIZE = 2048;
00037 static const int GZWRITE_BUFSIZE = 2048;
00038 
00039 /* Called when loaded as shared library */
00040 
00041 extern "C" void plugin_init(void *param) {
00042     void (*registerHandler)(TypeHandler* handler) = (void (*)(TypeHandler*))param;
00043     registerHandler(new TypeDeflate());
00044     registerHandler(new TypeGZip());
00045 }
00046 
00047 
00048 
00049 /* Constructors */
00050 
00051 TypeDeflate::TypeDeflate() : TypeHandler("deflate", "deflated") {
00052 
00053 }
00054 
00055 TypeGZip::TypeGZip() : TypeHandler("gzip", "gz") {
00056 
00057 }
00058 
00059 /*  Decode */
00060 
00061 void TypeDeflate::decode(string& data, TypeParams& params)
00062 {
00063     fprintf(stderr, "Deflate: starting...\n");
00064     string dl = params["datalen"];
00065     cerr << "there are " << params.size() << " parameters.\n";
00066     for(map<string,string>::const_iterator i = params.begin(); i != params.end(); i++) {
00067         cerr << " params[" << i->first << "] = " << i->second << endl;
00068     }
00069     cerr << "datalen is: " << params["datalen"] << endl;
00070     if(dl == "")
00071         throw TypeChain::DecodeError("no \"datalen\" parameter!", "deflate");
00072     unsigned long destlen = atoi(dl.c_str());
00073     char dest[destlen];
00074     int r = uncompress((Bytef*)dest, &destlen, (Bytef*)data.c_str(), data.length());
00075                 // does data.c_str() need to be massaged?
00076     if(r != Z_OK || r < 0) {
00077         string error;
00078         switch(r) {
00079             case Z_MEM_ERROR: error = "zlib couldn't allocate memory"; break;
00080             case Z_BUF_ERROR: error = "zlib: buffer too small"; break;
00081             case Z_DATA_ERROR: error = "zlib: bad data"; break;
00082             default: error = "unknown error";
00083         }
00084         throw TypeChain::DecodeError(error, "deflate");
00085     }
00086     fprintf(stderr, "Deflate: done.\n");
00087     data = dest; // Will this copy dest, or do we need to strdup?
00088 }
00089 
00090 
00091 
00092 void TypeGZip::decode(string& data, TypeParams& params) {
00093     int r;
00094     char buf[GZREAD_BUFSIZE];
00095 //    printf("type_z(gzip): data is %ld bytes long.\n", data.length());
00096     int p[2];
00097     r = pipe(p);
00098     if(r < 0) {
00099         throw TypeChain::DecodeError("error creating pipe", "gzip");
00100         exit(r);
00101     }
00102     int readMe = p[0];
00103     int writeMe = p[1];
00104     r = write(writeMe, data.c_str(), data.length());
00105     close(writeMe);
00106     gzFile z = gzdopen(readMe, "rb");
00107     if(z == NULL)
00108         throw TypeChain::DecodeError("error: zlib couldn't open the pipe", "gzip");
00109     data = "";
00110     while((r = gzread(z, buf, GZREAD_BUFSIZE))) {
00111         data.append(buf, r);
00112     }
00113     if(r < 0)  {
00114         gzclose(z);
00115         throw TypeChain::DecodeError("error reading gz data", "gzip");
00116     }
00117     gzclose(z);
00118 }
00119 
00120 
00121 
00122 
00123 void TypeDeflate::encode(string& data, TypeParams& params)
00124 {
00125     // TODO: get compression level out of params and call compress2.
00126 
00127     // This buffer will hold the result. From the zlib manual:
00128     //   "...must be at least 0.1% larger than sourceLen plus 12 bytes."
00129     unsigned long destlen = data.length() + (int)ceil(data.length() * 0.01) + 12;
00130     char dest[destlen];
00131 
00132     fprintf(stderr, "Deflate: encoding...\n");
00133     int r = compress((Bytef*)dest, &destlen, (Bytef*)data.c_str(), data.length());
00134     if(r != Z_OK || r < 0) {
00135         string error;
00136         switch(r) {
00137             case Z_MEM_ERROR: error = "zlib couldn't allocate memory"; break;
00138             case Z_BUF_ERROR: error = "zlib: buffer too small"; break;
00139             case Z_DATA_ERROR: error = "zlib: bad data"; break;
00140             default: error = "unknown error";
00141         }
00142         throw TypeChain::DecodeError(error, "deflate");
00143     }
00144     fprintf(stderr, "Deflate: done compressing.\n");
00145     params["datalen"] = data.length();
00146     data = dest;    // Will dest be copied, or do I need to use strdup?
00147 }
00148 
00149 
00150 void TypeGZip::encode(string& data, TypeParams& params)
00151 {
00152     // TODO: get compression level and other options out of params.
00153     fprintf(stderr, "Gzip: encoding...\n");
00154     int r;
00155     char buf[GZWRITE_BUFSIZE];
00156     int p[2];
00157     r = pipe(p);
00158     if(r < 0) {
00159         throw TypeChain::EncodeError("error creating pipe", "gzip");
00160     }
00161     int readMe = p[0];
00162     int writeMe = p[1];
00163     gzFile z = gzdopen(writeMe, "wb");
00164     if(z == NULL)
00165         throw TypeChain::EncodeError("error: zlib couldn't open the pipe", "gzip");
00166     gzwrite(z, (char*)data.c_str(), data.length());
00167     gzclose(z);
00168     close(writeMe);
00169     data = "";
00170     while((r = read(readMe, buf, GZWRITE_BUFSIZE))) {
00171         data.append(buf, r);
00172     }
00173     if(r < 0) {
00174         close(readMe);
00175         throw TypeChain::EncodeError("error reading gz data", "gzip");
00176     }
00177 
00178     close(readMe);
00179 
00180 /*
00181     int s = 0;
00182     int e = GZREAD_BUFSIZE;
00183     while(1) {
00184         fprintf("writing chunk from %d to %d to gzip...\n", s, e);
00185         r = gzwrite(z, data.substr(s, e), s - e);
00186         if(r <= 0)
00187             break;
00188         s = e;
00189         e += r;
00190     }
00191     gzclose(z);
00192 */
00193 }
00194 

Generated on Tue Aug 12 03:55:38 2003 for Interreality Project - VOS by doxygen 1.3.2