• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

strigi/src/streams

bz2inputstream.cpp

Go to the documentation of this file.
00001 /* This file is part of Strigi Desktop Search
00002  *
00003  * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 #include "bz2inputstream.h"
00021 #include <bzlib.h>
00022 #include <stdlib.h>
00023 #include <cstring>
00024 
00025 using namespace Strigi;
00026 
00027 class BZ2InputStream::Private {
00028 public:
00029     BZ2InputStream* const p;
00030     InputStream *input;
00031     bz_stream* bzstream;
00032     bool allocatedBz;
00033 
00034     Private(BZ2InputStream* p, InputStream* i);
00035     ~Private();
00036     void dealloc();
00037     void readFromStream();
00038     bool checkMagic();
00039 };
00040 bool
00041 BZ2InputStream::checkHeader(const char* data, int32_t datasize) {
00042     static const char magic[] = {0x42, 0x5a};
00043     static const char compressed_magic[] = {0x31, 0x41, 0x59, 0x26, 0x53, 0x59};
00044     if (datasize < 10) return false;
00045     return (std::memcmp(data, magic, 2) == 0
00046             && (data[2] == 0x68 || data[2] == 0x30)
00047             && std::memcmp(data + 4, compressed_magic, 6) == 0);
00048 }
00049 BZ2InputStream::BZ2InputStream(InputStream* input) :p(new Private(this, input)){
00050 }
00051 BZ2InputStream::Private::Private(BZ2InputStream* bis, InputStream* i)
00052         :p(bis), input(i) {
00053     // initialize values that signal state
00054     this->input = input;
00055 
00056     // check first bytes of stream before allocating buffer
00057     if (!checkMagic()) {
00058         p->m_error = "Magic bytes for bz2 are wrong.";
00059         p->m_status = Error;
00060         allocatedBz = false;
00061         return;
00062     }
00063 
00064     bzstream = (bz_stream*)malloc(sizeof(bz_stream));
00065     bzstream->bzalloc = NULL;
00066     bzstream->bzfree = NULL;
00067     bzstream->opaque = NULL;
00068     bzstream->avail_in = 0;
00069     bzstream->next_in = NULL;
00070     int r;
00071     r = BZ2_bzDecompressInit(bzstream, 1, 0);
00072     if (r != BZ_OK) {
00073         p->m_error = "Error initializing BZ2InputStream.";
00074         fprintf(stderr, "Error initializing BZ2InputStream.\n");
00075         dealloc();
00076         p->m_status = Error;
00077         return;
00078     }
00079     allocatedBz = true;
00080     // signal that we need to read into the buffer
00081     bzstream->avail_out = 1;
00082 
00083     // set the minimum size for the output buffer
00084     p->setMinBufSize(262144);
00085 }
00086 BZ2InputStream::~BZ2InputStream() {
00087     delete p;
00088 }
00089 BZ2InputStream::Private::~Private() {
00090     dealloc();
00091 }
00092 void
00093 BZ2InputStream::Private::dealloc() {
00094     if (allocatedBz) {
00095         BZ2_bzDecompressEnd(bzstream);
00096         free(bzstream);
00097         bzstream = 0;
00098     }
00099 }
00100 bool
00101 BZ2InputStream::Private::checkMagic() {
00102     const char* begin;
00103     int32_t nread;
00104 
00105     int64_t pos = input->position();
00106     nread = input->read(begin, 10, 0);
00107     input->reset(pos);
00108     if (nread < 10) {
00109         return false;
00110     }
00111 
00112     return checkHeader(begin, 10);
00113 }
00114 void
00115 BZ2InputStream::Private::readFromStream() {
00116     // read data from the input stream
00117     const char* inStart;
00118     int32_t nread;
00119     nread = input->read(inStart, 1, 0);
00120     if (nread <= -1) {
00121         p->m_status = Error;
00122         p->m_error = input->error();
00123     } else if (nread < 1) {
00124         p->m_status = Error;
00125         p->m_error = "unexpected end of stream";
00126     } else {
00127         bzstream->next_in = (char*)inStart;
00128         bzstream->avail_in = nread;
00129     }
00130 }
00131 int32_t
00132 BZ2InputStream::fillBuffer(char* start, int32_t space) {
00133     bz_stream* bzstream = p->bzstream;
00134     if (bzstream == 0) return -1;
00135     // make sure there is data to decompress
00136     if (bzstream->avail_out != 0) {
00137         p->readFromStream();
00138         if (m_status != Ok) {
00139             // no data was read
00140             return -1;
00141         }
00142     }
00143     // make sure we can write into the buffer
00144     bzstream->avail_out = space;
00145     bzstream->next_out = start;
00146     // decompress
00147     int r = BZ2_bzDecompress(bzstream);
00148     // inform the buffer of the number of bytes that was read
00149     int32_t nwritten = space - bzstream->avail_out;
00150     switch (r) {
00151     case BZ_PARAM_ERROR:
00152         m_error = "BZ_PARAM_ERROR";
00153         m_status = Error;
00154         return -1;
00155     case BZ_DATA_ERROR:
00156         m_error = "BZ_DATA_ERROR";
00157         m_status = Error;
00158         return -1;
00159     case BZ_DATA_ERROR_MAGIC:
00160         m_error = "BZ_DATA_ERROR_MAGIC";
00161         m_status = Error;
00162         return -1;
00163     case BZ_MEM_ERROR:
00164         m_error = "BZ_MEM_ERROR";
00165         m_status = Error;
00166         return -1;
00167     case BZ_STREAM_END:
00168         if (bzstream->avail_in) {
00169             p->input->reset(p->input->position()-bzstream->avail_in);
00170         }
00171         // we are finished decompressing,
00172         // (but this stream is not yet finished)
00173         p->dealloc();
00174     }
00175     return nwritten;
00176 }

strigi/src/streams

Skip menu "strigi/src/streams"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal