CrystalSpace

Public API Reference

csutil/archive.h
Go to the documentation of this file.
00001 /*
00002     ZIP archive support for Crystal Space 3D library
00003     Copyright (C) 1998,1999 by Andrew Zabolotny <bit@eltech.ru>
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
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #ifndef __CS_ARCHIVE_H__
00021 #define __CS_ARCHIVE_H__
00022 
00027 #include "csextern.h"
00028 
00029 #include "iutil/databuff.h"
00030 #include "iutil/vfs.h"
00031 #include "csutil/csstring.h"
00032 #include "csutil/databuf.h"
00033 #include "csutil/parray.h"
00034 #include "csutil/ref.h"
00035 #include "csutil/stringarray.h"
00036 #include "csutil/zip.h"
00037 
00038 struct csFileTime;
00039 
00059 class CS_CRYSTALSPACE_EXPORT csArchive
00060 {
00061 public:
00062   static const char hdr_central[4];
00063   static const char hdr_local[4];
00064   static const char hdr_endcentral[4];
00065   static const char hdr_extlocal[4];
00066 
00067 private:
00069   class ArchiveEntry
00070   {
00071   public:
00072     char *filename;
00073     ZIP_central_directory_file_header info;
00074     char *buffer;
00075     size_t buffer_pos;
00076     size_t buffer_size;
00077     char *extrafield, *comment;
00078     bool faked;
00079 
00080     ArchiveEntry (const char *name, ZIP_central_directory_file_header &cdfh);
00081     ~ArchiveEntry ();
00082     bool Append (const void *data, size_t size);
00083     bool WriteLFH (iFile* file);
00084     bool WriteCDFH (iFile* file);
00085     bool ReadExtraField (iFile* file, size_t extra_field_length);
00086     bool ReadFileComment (iFile* file, size_t file_comment_length);
00087     bool WriteFile (iFile* file);
00088     void FreeBuffer ();
00089   };
00090   friend class ArchiveEntry;
00091 
00093   class CS_CRYSTALSPACE_EXPORT ArchiveEntryVector
00094         : public csPDelArray<ArchiveEntry, CS::Container::ArrayAllocDefault,
00095                              csArrayCapacityFixedGrow<256> >
00096   {
00097   public:
00098     ArchiveEntryVector () : csPDelArray<ArchiveEntry, 
00099       CS::Container::ArrayAllocDefault, csArrayCapacityFixedGrow<256> > (256) {}
00100     static int Compare (ArchiveEntry* const& Item1, ArchiveEntry* const& Item2)
00101     { return strcmp (Item1->filename, Item2->filename); }
00102     static int CompareKey (ArchiveEntry* const& Item, char const* const& Key)
00103     { return strcmp (Item->filename, Key); }
00104   };
00105 
00106   ArchiveEntryVector dir;       // Archive directory: chain head (sorted)
00107   csStringArray del;            // Files that should be deleted (sorted)
00108   csArray<ArchiveEntry*> lazy;  // Lazy operations (unsorted)
00109 
00110   char *filename;               // Archive file name
00111   // Archive file pointer.
00112   csRef<iFile> file;
00113 
00114   size_t comment_length;        // Archive comment length
00115   char *comment;                // Archive comment
00116 
00117   void ReadDirectory ();
00118   bool IsDeleted (const char *name) const;
00119   void UnpackTime (ush zdate, ush ztime, csFileTime &rtime) const;
00120   void PackTime (const csFileTime &ztime, ush &rdate, ush &rtime) const;
00121   bool ReadArchiveComment (iFile* file, size_t zipfile_comment_length);
00122   void LoadECDR (ZIP_end_central_dir_record &ecdr, char *buff);
00123   bool ReadCDFH (ZIP_central_directory_file_header &cdfh, iFile* file);
00124   bool ReadLFH (ZIP_local_file_header &lfh, iFile* file);
00125   bool WriteECDR (ZIP_end_central_dir_record &ecdr, iFile* file);
00126   bool WriteZipArchive ();
00127   bool WriteCentralDirectory (iFile* temp);
00128   void UpdateDirectory ();
00129   void ReadZipDirectory (iFile *infile);
00130   ArchiveEntry *InsertEntry (const char *name,
00131     ZIP_central_directory_file_header &cdfh);
00132   void ReadZipEntries (iFile* infile);
00133   bool ReadEntry (iFile* infile, ArchiveEntry *f, char* buf);
00134   ArchiveEntry *CreateArchiveEntry (const char *name,
00135     size_t size = 0, bool pack = true);
00136   void ResetArchiveEntry (ArchiveEntry *f, size_t size, bool pack);
00137 
00138 public:
00140   csArchive (const char *filename);
00142   ~csArchive ();
00143 
00145   void Dir () const;
00146 
00161   void *NewFile (const char *name, size_t size = 0, bool pack = true);
00162 
00167   bool DeleteFile (const char *name);
00168 
00173   bool FileExists (const char *name, size_t *size = 0) const;
00174 
00181   char *Read (const char *name, size_t *size = 0);
00182 
00187   template<typename Allocator>
00188   csPtr<iDataBuffer> Read (const char *name, Allocator& alloc)
00189   {
00190     ArchiveEntry *f = (ArchiveEntry *) FindName (name);
00191   
00192     if (!f)
00193       return 0;
00194 
00195     csRef<iDataBuffer> buf;
00196     buf.AttachNew (new CS::DataBuffer<Allocator> (f->info.ucsize, alloc));
00197     if (!ReadEntry (file, f, buf->GetData()))
00198       return 0;
00199     return csPtr<iDataBuffer> (buf);
00200   }
00201 
00206   csPtr<iDataBuffer> Read (const char *name)
00207   {
00208     CS::Memory::AllocatorMalloc alloc;
00209     return Read (name, alloc);
00210   }
00211 
00218   bool Write (void *entry, const char *data, size_t size);
00219 
00229   bool Flush ();
00230 
00232   void *GetFile (size_t no)
00233   { return (no < dir.GetSize ()) ? dir.Get (no) : 0; }
00234 
00236   void *FindName (const char *name) const;
00238   char *GetFileName (void *entry) const
00239   { return ((ArchiveEntry*)entry)->filename; }
00241   size_t GetFileSize (void *entry) const
00242   { return ((ArchiveEntry*)entry)->info.ucsize; }
00244   void GetFileTime (void *entry, csFileTime &ztime) const;
00246   void SetFileTime (void *entry, const csFileTime &ztime);
00247 
00249   char *GetName () const
00250   { return filename; }
00252   char *GetComment () const
00253   { return comment; }
00254 };
00255 
00256 inline void csArchive::GetFileTime (void *entry, csFileTime &ztime) const
00257 {
00258   if (entry)
00259   {
00260     UnpackTime (((ArchiveEntry*)entry)->info.last_mod_file_date,
00261                 ((ArchiveEntry*)entry)->info.last_mod_file_time,
00262                 ztime);
00263   }
00264 }
00265 
00266 inline void csArchive::SetFileTime (void *entry, const csFileTime &ztime)
00267 {
00268   if (entry)
00269   {
00270     PackTime (ztime,
00271               ((ArchiveEntry*)entry)->info.last_mod_file_date,
00272               ((ArchiveEntry*)entry)->info.last_mod_file_time);
00273   }
00274 }
00275 
00276 #endif // __CS_ARCHIVE_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1