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.6.1