kar.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qfile.h>
00021 #include <qdir.h>
00022 #include <time.h>
00023 #include <kdebug.h>
00024 #include <qptrlist.h>
00025 #include <kmimetype.h>
00026 #include <qregexp.h>
00027
00028 #include "kfilterdev.h"
00029 #include "kar.h"
00030
00031
00035
00036 class KAr::KArPrivate
00037 {
00038 public:
00039 KArPrivate() {}
00040 };
00041
00042 KAr::KAr( const QString& filename )
00043 : KArchive( 0L )
00044 {
00045
00046 m_filename = filename;
00047 d = new KArPrivate;
00048 setDevice( new QFile( filename ) );
00049 }
00050
00051 KAr::KAr( QIODevice * dev )
00052 : KArchive( dev )
00053 {
00054
00055 d = new KArPrivate;
00056 }
00057
00058 KAr::~KAr()
00059 {
00060
00061
00062 if( isOpened() )
00063 close();
00064 if ( !m_filename.isEmpty() )
00065 delete device();
00066 delete d;
00067 }
00068
00069 bool KAr::openArchive( int mode )
00070 {
00071
00072
00073
00074
00075 if ( mode == IO_WriteOnly )
00076 return true;
00077 if ( mode != IO_ReadOnly && mode != IO_ReadWrite )
00078 {
00079 kdWarning(7042) << "Unsupported mode " << mode << endl;
00080 return false;
00081 }
00082
00083 QIODevice* dev = device();
00084
00085 char magic[8];
00086 dev->readBlock (magic, 8);
00087 if (qstrncmp(magic, "!<arch>", 7) != 0) {
00088 kdWarning(7042) << "Invalid main magic" << endl;
00089 return false;
00090 }
00091
00092 char *ar_longnames = 0;
00093 while (! dev->atEnd()) {
00094 QCString ar_header;
00095 ar_header.resize(61);
00096 QCString name;
00097 int date, uid, gid, mode, size;
00098
00099 dev->at( dev->at() + (2 - (dev->at() % 2)) % 2 );
00100
00101 if ( dev->readBlock (ar_header.data(), 60) != 60 ) {
00102 kdWarning(7042) << "Couldn't read header" << endl;
00103 if (ar_longnames) delete[] ar_longnames;
00104
00105 return true;
00106 }
00107
00108 if (ar_header.right(2) != "`\n") {
00109 kdWarning(7042) << "Invalid magic" << endl;
00110 if (ar_longnames) delete[] ar_longnames;
00111 return false;
00112 }
00113
00114 name = ar_header.mid( 0, 16 );
00115 date = ar_header.mid( 16, 12 ).toInt();
00116 uid = ar_header.mid( 28, 6 ).toInt();
00117 gid = ar_header.mid( 34, 6 ).toInt();
00118 mode = ar_header.mid( 40, 8 ).toInt();
00119 size = ar_header.mid( 48, 10 ).toInt();
00120
00121 bool skip_entry = false;
00122 if (name.mid(0, 1) == "/") {
00123 if (name.mid(1, 1) == "/") {
00124 if (ar_longnames) delete[] ar_longnames;
00125 ar_longnames = new char[size + 1];
00126 ar_longnames[size] = '\0';
00127 dev->readBlock (ar_longnames, size);
00128 skip_entry = true;
00129 kdDebug(7042) << "Read in longnames entry" << endl;
00130 } else if (name.mid(1, 1) == " ") {
00131 kdDebug(7042) << "Skipped symbol entry" << endl;
00132 dev->at( dev->at() + size );
00133 skip_entry = true;
00134 } else {
00135 kdDebug(7042) << "Longfilename #" << name.mid(1, 15).toInt() << endl;
00136 if (! ar_longnames) {
00137 kdWarning(7042) << "Invalid longfilename reference" << endl;
00138 return false;
00139 }
00140 name = &ar_longnames[name.mid(1, 15).toInt()];
00141 name = name.left(name.find("/"));
00142 }
00143 }
00144 if (skip_entry) continue;
00145
00146 name = name.stripWhiteSpace();
00147 name.replace( QRegExp("/"), "" );
00148 kdDebug(7042) << "Filename: " << name << " Size: " << size << endl;
00149
00150 KArchiveEntry* entry;
00151 entry = new KArchiveFile(this, name, mode, date, 0, 0, 0, dev->at(), size);
00152 rootDir()->addEntry(entry);
00153
00154 dev->at( dev->at() + size );
00155 }
00156 if (ar_longnames) delete[] ar_longnames;
00157
00158 return true;
00159 }
00160
00161 bool KAr::closeArchive()
00162 {
00163
00164 return true;
00165 }
00166
00167 void KAr::virtual_hook( int id, void* data )
00168 { KArchive::virtual_hook( id, data ); }
This file is part of the documentation for kdelibs Version 3.1.5.