00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_ARCHIVE_H__
00021 #define __CS_ARCHIVE_H__
00022
00023 #include <stdio.h>
00024 #include "csutil/zip.h"
00025 #include "csutil/parray.h"
00026 #include "csutil/stringarray.h"
00027
00028 struct csFileTime;
00029
00050 class csArchive
00051 {
00052 public:
00053 static char hdr_central[4];
00054 static char hdr_local[4];
00055 static char hdr_endcentral[4];
00056 static char hdr_extlocal[4];
00057
00058 private:
00060 class ArchiveEntry
00061 {
00062 public:
00063 char *filename;
00064 ZIP_central_directory_file_header info;
00065 char *buffer;
00066 size_t buffer_pos;
00067 size_t buffer_size;
00068 char *extrafield, *comment;
00069
00070 ArchiveEntry (const char *name, ZIP_central_directory_file_header &cdfh);
00071 ~ArchiveEntry ();
00072 bool Append (const void *data, size_t size);
00073 bool WriteLFH (FILE *file);
00074 bool WriteCDFH (FILE *file);
00075 bool ReadExtraField (FILE *file, size_t extra_field_length);
00076 bool ReadFileComment (FILE *file, size_t file_comment_length);
00077 bool WriteFile (FILE *file);
00078 void FreeBuffer ();
00079 };
00080 friend class ArchiveEntry;
00081
00083 class ArchiveEntryVector : public csPDelArray<ArchiveEntry>
00084 {
00085 public:
00086 ArchiveEntryVector () : csPDelArray<ArchiveEntry> (256, 256) {}
00087 static int Compare (ArchiveEntry* const& Item1, ArchiveEntry* const& Item2)
00088 { return strcmp (Item1->filename, Item2->filename); }
00089 static int CompareKey (ArchiveEntry* const& Item, void* Key)
00090 { return strcmp (Item->filename, (char *)Key); }
00091 };
00092
00093 ArchiveEntryVector dir;
00094 csStringArray del;
00095 csArray<ArchiveEntry*> lazy;
00096
00097 char *filename;
00098 FILE *file;
00099
00100 size_t comment_length;
00101 char *comment;
00102
00103 void ReadDirectory ();
00104 bool IsDeleted (const char *name) const;
00105 void UnpackTime (ush zdate, ush ztime, csFileTime &rtime) const;
00106 void PackTime (const csFileTime &ztime, ush &rdate, ush &rtime) const;
00107 bool ReadArchiveComment (FILE *file, size_t zipfile_comment_length);
00108 void LoadECDR (ZIP_end_central_dir_record &ecdr, char *buff);
00109 bool ReadCDFH (ZIP_central_directory_file_header &cdfh, FILE *file);
00110 bool ReadLFH (ZIP_local_file_header &lfh, FILE *file);
00111 bool WriteECDR (ZIP_end_central_dir_record &ecdr, FILE *file);
00112 bool WriteZipArchive ();
00113 bool WriteCentralDirectory (FILE *temp);
00114 void UpdateDirectory ();
00115 void ReadZipDirectory (FILE *infile);
00116 ArchiveEntry *InsertEntry (const char *name,
00117 ZIP_central_directory_file_header &cdfh);
00118 void ReadZipEntries (FILE *infile);
00119 char *ReadEntry (FILE *infile, ArchiveEntry *f);
00120
00121 public:
00123 csArchive (const char *filename);
00125 ~csArchive ();
00126
00128 void Dir () const;
00129
00145 void *NewFile (const char *name, size_t size = 0, bool pack = true);
00146
00151 bool DeleteFile (const char *name);
00152
00157 bool FileExists (const char *name, size_t *size = 0) const;
00158
00165 char *Read (const char *name, size_t *size = 0);
00166
00173 bool Write (void *entry, const char *data, size_t size);
00174
00184 bool Flush ();
00185
00187 void *GetFile (int no)
00188 { return (no >= 0) && (no < dir.Length ()) ? dir.Get (no) : 0; }
00189
00191 void *FindName (const char *name) const;
00193 char *GetFileName (void *entry) const
00194 { return ((ArchiveEntry*)entry)->filename; }
00196 size_t GetFileSize (void *entry) const
00197 { return ((ArchiveEntry*)entry)->info.ucsize; }
00199 void GetFileTime (void *entry, csFileTime &ztime) const;
00201 void SetFileTime (void *entry, const csFileTime &ztime);
00202
00204 char *GetName () const
00205 { return filename; }
00207 char *GetComment () const
00208 { return comment; }
00209 };
00210
00211 inline void csArchive::GetFileTime (void *entry, csFileTime &ztime) const
00212 {
00213 if (entry)
00214 {
00215 UnpackTime (((ArchiveEntry*)entry)->info.last_mod_file_date,
00216 ((ArchiveEntry*)entry)->info.last_mod_file_time,
00217 ztime);
00218 }
00219 }
00220
00221 inline void csArchive::SetFileTime (void *entry, const csFileTime &ztime)
00222 {
00223 if (entry)
00224 {
00225 PackTime (ztime,
00226 ((ArchiveEntry*)entry)->info.last_mod_file_date,
00227 ((ArchiveEntry*)entry)->info.last_mod_file_time);
00228 }
00229 }
00230
00231 #endif // __CS_ARCHIVE_H__