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