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

strigi/src/streams

cpioinputstream.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 "cpioinputstream.h"
00021 #include <strigi/strigiconfig.h>
00022 #include "subinputstream.h"
00023 
00024 #include <list>
00025 #include <cstring>
00026 
00027 using namespace std;
00028 using namespace Strigi;
00029 
00030 const char unsigned* CpioInputStream::magic = (const char unsigned *)"070701";
00031 
00032 bool
00033 CpioInputStream::checkHeader(const char* data, int32_t datasize) {
00034     if (datasize < 6) return false;
00035     // this check could be more strict
00036     bool ok = memcmp(data, magic, 6) == 0;
00037     return ok;
00038 }
00039 CpioInputStream::CpioInputStream(InputStream* input)
00040         : SubStreamProvider(input) {
00041     m_entryinfo.type = EntryInfo::File;
00042 }
00043 CpioInputStream::~CpioInputStream() {
00044 }
00045 InputStream*
00046 CpioInputStream::nextEntry() {
00047     if (m_status) return 0;
00048     if (m_entrystream) {
00049         while (m_entrystream->status() == Ok) {
00050             m_entrystream->skip(m_entrystream->size());
00051         }
00052         delete m_entrystream;
00053         m_entrystream = 0;
00054         if (padding) {
00055             m_input->skip(padding);
00056         }
00057     }
00058     readHeader();
00059     m_entrystream = new SubInputStream(m_input, m_entryinfo.size);
00060     return (m_status) ?0 :m_entrystream;
00061 }
00062 void
00063 CpioInputStream::readHeader() {
00064     //const unsigned char *hb;
00065     const char* b;
00066     int32_t toread;
00067     int32_t nread;
00068 
00069     // read the first 110 characters
00070     toread = 110;
00071     nread = m_input->read(b, toread, toread);
00072     if (nread != toread) {
00073         m_status = m_input->status();
00074         if (m_status == Eof) {
00075             return;
00076         }
00077         m_error = "Error reading cpio entry: ";
00078         if (nread == -1) {
00079             m_error += m_input->error();
00080         } else {
00081             m_error += " premature end of file.";
00082         }
00083         return;
00084     }
00085     // check header
00086     if (memcmp(b, magic, 6) != 0) {
00087         m_status = Error;
00088         m_error = "CPIO Entry signature is unknown: ";
00089         m_error.append(b, 6);
00090         return;
00091     }
00092     m_entryinfo.size = readHexField(b+54);
00093     m_entryinfo.mtime = readHexField(b+46);
00094     int32_t filenamesize = readHexField(b+94);
00095     if (m_status) {
00096         m_error = "Error parsing entry field.";
00097         return;
00098     }
00099     char namepadding = (filenamesize+2) % 4;
00100     if (namepadding) namepadding = 4 - namepadding;
00101     padding = m_entryinfo.size % 4;
00102     if (padding) padding = 4 - padding;
00103 
00104     // read filename
00105     toread = filenamesize + namepadding;
00106     nread = m_input->read(b, toread, toread);
00107     if (nread != toread) {
00108         m_error = "Error reading cpio entry name.";
00109         m_status = Error;
00110         return;
00111     }
00112     int32_t len = filenamesize - 1;
00113     if (len > 2 && b[0] == '.' && b[1] == '/') {
00114         b += 2;
00115     }
00116     // check if the name is not shorter than specified
00117     len = 0;
00118     while (len < filenamesize && b[len] != '\0') len++;
00119     m_entryinfo.filename = std::string((const char*)b, len);
00120 
00121     // if an cpio has an entry 'TRAILER!!!' we are at the end
00122     if ("TRAILER!!!" == m_entryinfo.filename) {
00123         m_status = Eof;
00124     }
00125 }
00126 int32_t
00127 CpioInputStream::readHexField(const char *b) {
00128     int32_t val = 0;
00129     char c;
00130     for (unsigned char i=0; i<8; ++i) {
00131         val <<= 4;
00132         c = b[i];
00133         if (c > 'F') {
00134             val += c - 87;
00135         } else if (c > '9') {
00136             val += c - 55;
00137         } else {
00138             val += c - 48;
00139         }
00140     }
00141     return val;
00142 }

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