Back to index

lightning-sunbird  0.9+nobinonly
nsZipArchive.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Daniel Veditz <dveditz@netscape.com>
00025  *   Samir Gehani <sgehani@netscape.com>
00026  *   Mitch Stoltz <mstoltz@netscape.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #ifndef nsZipArchive_h_
00043 #define nsZipArchive_h_
00044 
00045 #define ZIP_MAGIC     0x5A49505FL   /* "ZIP_" */
00046 #define ZIPFIND_MAGIC 0x5A495046L   /* "ZIPF" */
00047 #define ZIP_TABSIZE   256
00048 // Keep this odd. The -1 is significant.
00049 #define ZIP_BUFLEN    (4 * 1024 - 1)
00050 
00051 #ifdef STANDALONE
00052 #define nsZipArchive nsZipArchiveStandalone
00053 
00054 #define ZIP_Seek(fd,p,m) (fseek((fd),(p),(m))==0)
00055 
00056 #else
00057 
00058 #define PL_ARENA_CONST_ALIGN_MASK 7
00059 #include "plarena.h"
00060 #define ZIP_Seek(fd,p,m) (PR_Seek((fd),((PROffset32)p),(m))==((PROffset32)p))
00061 
00062 #endif
00063 
00064 #include "zlib.h"
00065 
00066 class nsZipFind;
00067 class nsZipReadState;
00068 class nsZipItemMetadata;
00069 
00070 #ifndef STANDALONE
00071 struct PRFileDesc;
00072 #endif
00073 
00111 class nsZipItem
00112 {
00113 public:
00114   char*       name; /* '\0' terminated */
00115 
00116   PRUint32    headerOffset;
00117   PRUint32    dataOffset;
00118   PRUint32    size;             /* size in original file */
00119   PRUint32    realsize;         /* inflated size */
00120   PRUint32    crc32;
00121 
00122   nsZipItem*  next;
00123 
00124   /*
00125    * Keep small items together, to avoid overhead.
00126    */
00127   PRUint16    mode;
00128   PRUint16    time;
00129   PRUint16    date;
00130 
00131   /*
00132    * Keep small items together, to avoid overhead.
00133    */
00134   PRUint8      compression;
00135   PRPackedBool hasDataOffset : 1;
00136   PRPackedBool isSymlink : 1;
00137 
00138 #ifndef STANDALONE
00139 
00147   PRTime GetModTime();
00148 #endif
00149 
00150   nsZipItem();
00151   ~nsZipItem();
00152 
00153 
00154 private:
00155   //-- prevent copies and assignments
00156   nsZipItem& operator=(const nsZipItem& rhs);
00157   nsZipItem(const nsZipItem& rhs);
00158 
00159 };
00160 
00165 class nsZipArchive 
00166 {
00167 public:
00169   const PRInt32 kMagic;
00170 
00172   const PRUint32 kArenaBlockSize;
00173 
00175   nsZipArchive();
00176 
00178   ~nsZipArchive();
00179 
00180 #ifdef STANDALONE
00181 
00183   PRFileDesc* GetFd() { return mFd; }
00184 #endif
00185   
00196 #ifdef STANDALONE
00197   PRInt32 OpenArchive(const char * aArchiveName);
00198 #else
00199   PRInt32 OpenArchiveWithFileDesc(PRFileDesc* fd);
00200 #endif
00201 
00211   PRInt32 Test(const char *aEntryName, PRFileDesc* aFd);
00212 
00216   PRInt32 CloseArchive();
00217 
00224   PRInt32 GetItem(const char * aFilename, nsZipItem** result);
00225   
00237   PRInt32 ReadInit(const char* zipEntry, nsZipReadState* aRead, PRFileDesc* aFd);
00238 
00239 
00247   PRInt32 ExtractFile(const char * zipEntry, const char * aOutname,
00248                       PRFileDesc* aFd);
00249 
00250   PRInt32 ExtractItemToFileDesc(nsZipItem* item, PRFileDesc* outFD,
00251                                 PRFileDesc* aFd);
00252 
00263   nsZipFind* FindInit(const char * aPattern);
00264 
00271   PRInt32 FindNext(nsZipFind* aFind, nsZipItem** aResult);
00272 
00273   PRInt32 FindFree(nsZipFind *aFind);
00274 
00275 #ifdef XP_UNIX
00276 
00281   PRInt32  ResolveSymlink(const char *path, nsZipItem *zipItem);
00282 #endif
00283 
00284 private:
00285   //--- private members ---
00286 
00287   nsZipItem*    mFiles[ZIP_TABSIZE];
00288 #ifndef STANDALONE
00289   PLArenaPool   mArena;
00290 #else
00291   // in standalone, each nsZipArchive has its own mFd
00292   PRFileDesc    *mFd;
00293 #endif
00294 
00295   //--- private methods ---
00296   
00297   nsZipArchive& operator=(const nsZipArchive& rhs); // prevent assignments
00298   nsZipArchive(const nsZipArchive& rhs);            // prevent copies
00299 
00300   PRInt32           BuildFileList(PRFileDesc* aFd);
00301   nsZipItem*        GetFileItem(const char * zipEntry);
00302   PRUint32          HashName(const char* aName);
00303 
00304   PRInt32           SeekToItem(const nsZipItem* aItem,
00305                                PRFileDesc* aFd);
00306   PRInt32           CopyItemToDisk(const nsZipItem* aItem, PRFileDesc* outFD,
00307                                    PRFileDesc* aFd);
00308   PRInt32           InflateItem(const nsZipItem* aItem, PRFileDesc* outFD,
00309                                 PRFileDesc* aFd);
00310   PRInt32           TestItem(const nsZipItem *aItem,
00311                              PRFileDesc* aFd);
00312 
00313 };
00314 
00321 class nsZipReadState
00322 {
00323 public:
00324 
00325   nsZipReadState() :
00326 #ifndef STANDALONE
00327     mFd(0),
00328 #endif
00329     mCurPos(0)
00330   { MOZ_COUNT_CTOR(nsZipReadState); }
00331   ~nsZipReadState()
00332   {
00333 #ifndef STANDALONE
00334     if (mFd)
00335       PR_Close(mFd);
00336 #endif
00337     MOZ_COUNT_DTOR(nsZipReadState);
00338   }
00339 
00340   void Init(nsZipItem* aZipItem, PRFileDesc* aFd);
00341 
00342 #ifndef STANDALONE
00343 
00355   PRInt32 Read(char* buf, PRUint32 count, PRUint32* actual);
00356 #endif
00357   
00367    PRUint32 Available();
00368 
00369 #ifndef STANDALONE
00370   PRFileDesc*   mFd;
00371 #endif
00372 
00373   nsZipItem*    mItem;
00374   PRUint32      mCurPos;
00375   unsigned char mReadBuf[ZIP_BUFLEN];
00376   z_stream      mZs;
00377   PRUint32      mCrc;
00378 
00379 private:
00380 #ifndef STANDALONE
00381   PRInt32 ContinueInflate(char* aBuf,
00382                           PRUint32 aCount,
00383                           PRUint32* aBytesRead);
00384   PRInt32 ContinueCopy(char* aBuf,
00385                        PRUint32 aCount,
00386                        PRUint32* aBytesRead);
00387 #endif
00388   
00389   //-- prevent copies and assignments
00390   nsZipReadState& operator=(const nsZipReadState& rhs);
00391   nsZipReadState(const nsZipFind& rhs);
00392 };
00393 
00399 class nsZipFind
00400 {
00401   friend class nsZipArchive;
00402 
00403 public:
00404   const PRInt32       kMagic;
00405 
00406   nsZipFind(nsZipArchive* aZip, char* aPattern, PRBool regExp);
00407   ~nsZipFind();
00408 
00409   nsZipArchive* GetArchive();
00410 
00411 private:
00412   nsZipArchive* mArchive;
00413   char*         mPattern;
00414   PRUint16      mSlot;
00415   nsZipItem*    mItem;
00416   PRBool        mRegExp;
00417 
00418   //-- prevent copies and assignments
00419   nsZipFind& operator=(const nsZipFind& rhs);
00420   nsZipFind(const nsZipFind& rhs);
00421 };
00422 
00423 #endif /* nsZipArchive_h_ */