/usr/include/crystalspace-2.0/csutil/archive.h is in libcrystalspace-dev 2.0+dfsg-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | /*
ZIP archive support for Crystal Space 3D library
Copyright (C) 1998,1999 by Andrew Zabolotny <bit@eltech.ru>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CS_ARCHIVE_H__
#define __CS_ARCHIVE_H__
/**\file
* ZIP archive support
*/
#include "csextern.h"
#include "iutil/databuff.h"
#include "iutil/vfs.h"
#include "csutil/csstring.h"
#include "csutil/databuf.h"
#include "csutil/parray.h"
#include "csutil/ref.h"
#include "csutil/stringarray.h"
#include "csutil/zip.h"
struct csFileTime;
/**
* This class can be used to work with standard ZIP archives.
* Constructor accepts a file name - if such a file is not found, it is
* created. After this you can examine archive directory, read files,
* delete or write files in archive.
*
* Operations which changes archive file will be deferred until Flush()
* method is called. Before calling Flush() you can do any number of
* deletions and writes, but read operations will not be affected by
* these until Flush() will be called.
*
* Known quirks:
* - No CRC check is done on reading, although ZIP file format allows it.
* This design 'flaw' was allowed to achieve maximal speed. However, when
* a file is added to archive, its CRC is computed and updated correctly.
* - Several methods of the csArchive class requires approximatively 20K of
* stack space when invoked.
* - Doesn't like files >4GB.
*/
class CS_CRYSTALSPACE_EXPORT csArchive
{
public:
static const char hdr_central[4];
static const char hdr_local[4];
static const char hdr_endcentral[4];
static const char hdr_extlocal[4];
private:
/// csArchive entry class
class ArchiveEntry
{
public:
char *filename;
ZIP_central_directory_file_header info;
char *buffer;
size_t buffer_pos;
size_t buffer_size;
char *extrafield, *comment;
bool faked;
ArchiveEntry (const char *name, ZIP_central_directory_file_header &cdfh);
~ArchiveEntry ();
bool Append (const void *data, size_t size);
bool WriteLFH (iFile* file);
bool WriteCDFH (iFile* file);
bool ReadExtraField (iFile* file, size_t extra_field_length);
bool ReadFileComment (iFile* file, size_t file_comment_length);
bool WriteFile (iFile* file);
void FreeBuffer ();
};
friend class ArchiveEntry;
/// A vector of ArchiveEntries
class CS_CRYSTALSPACE_EXPORT ArchiveEntryVector
: public csPDelArray<ArchiveEntry, CS::Container::ArrayAllocDefault,
csArrayCapacityFixedGrow<256> >
{
public:
ArchiveEntryVector () : csPDelArray<ArchiveEntry,
CS::Container::ArrayAllocDefault, csArrayCapacityFixedGrow<256> > (256) {}
static int Compare (ArchiveEntry* const& Item1, ArchiveEntry* const& Item2)
{ return strcmp (Item1->filename, Item2->filename); }
static int CompareKey (ArchiveEntry* const& Item, char const* const& Key)
{ return strcmp (Item->filename, Key); }
};
ArchiveEntryVector dir; // Archive directory: chain head (sorted)
csStringArray del; // Files that should be deleted (sorted)
csArray<ArchiveEntry*> lazy; // Lazy operations (unsorted)
char *filename; // Archive file name
// Archive file pointer.
csRef<iFile> file;
size_t comment_length; // Archive comment length
char *comment; // Archive comment
void ReadDirectory ();
bool IsDeleted (const char *name) const;
void UnpackTime (ush zdate, ush ztime, csFileTime &rtime) const;
void PackTime (const csFileTime &ztime, ush &rdate, ush &rtime) const;
bool ReadArchiveComment (iFile* file, size_t zipfile_comment_length);
void LoadECDR (ZIP_end_central_dir_record &ecdr, char *buff);
bool ReadCDFH (ZIP_central_directory_file_header &cdfh, iFile* file);
bool ReadLFH (ZIP_local_file_header &lfh, iFile* file);
bool WriteECDR (ZIP_end_central_dir_record &ecdr, iFile* file);
bool WriteZipArchive ();
bool WriteCentralDirectory (iFile* temp);
void UpdateDirectory ();
void ReadZipDirectory (iFile *infile);
ArchiveEntry *InsertEntry (const char *name,
ZIP_central_directory_file_header &cdfh);
void ReadZipEntries (iFile* infile);
bool ReadEntry (iFile* infile, ArchiveEntry *f, char* buf);
ArchiveEntry *CreateArchiveEntry (const char *name,
size_t size = 0, bool pack = true);
void ResetArchiveEntry (ArchiveEntry *f, size_t size, bool pack);
public:
/// Open the archive.
csArchive (const char *filename);
/// Close the archive.
~csArchive ();
/// Type a directory listing of the archive to the console.
void Dir () const;
/**
* Create a new file in the archive. If the file already exists
* it will be overwritten.
*
* Returns 0 if not succesful. Otherwise it returns a pointer
* that can be passed to 'Write' routine. You won't see any changes
* to archive until 'Flush' will be called.
*
* 'size' is the _advisory_ file size. There is no problem if you will
* write more or less bytes, its just a matter of performance - if you
* set the right size, archive manager will have to allocate memory
* only once; however if you set size to zero and then write all the
* data in one call, it will have same performance.
*/
void *NewFile (const char *name, size_t size = 0, bool pack = true);
/**
* Delete a file from the archive. You won't see any changes
* to archive until 'Flush' will be called.
*/
bool DeleteFile (const char *name);
/**
* Return true if a path exists. Also return the
* size of the file if needed.
*/
bool FileExists (const char *name, size_t *size = 0) const;
/**
* Read a file completely. After finishing with the returned
* data you need to 'delete[]' it. If the file does not exists
* this function returns 0. If "size" is not null, it is set
* to unpacked size of the file.
*/
char *Read (const char *name, size_t *size = 0);
/**
* Read a file completely into a buffer allocated with the given
* allocator. If the file does not exists this function returns 0.
*/
template<typename Allocator>
csPtr<iDataBuffer> Read (const char *name, Allocator& alloc)
{
ArchiveEntry *f = (ArchiveEntry *) FindName (name);
if (!f)
return 0;
csRef<iDataBuffer> buf;
buf.AttachNew (new CS::DataBuffer<Allocator> (f->info.ucsize, alloc));
if (!ReadEntry (file, f, buf->GetData()))
return 0;
return csPtr<iDataBuffer> (buf);
}
/**
* Read a file completely. If the file does not exists
* this function returns 0.
*/
csPtr<iDataBuffer> Read (const char *name)
{
CS::Memory::AllocatorMalloc alloc;
return Read (name, alloc);
}
/**
* Write data to a file. Note that 'size' need not be
* the overall file size if this was given in 'NewFile',
* but this function will fail if the total size of written
* data exceeds the maximum size given to 'NewFile'.
*/
bool Write (void *entry, const char *data, size_t size);
/**
* Execute all pending operations involving writes to archive
* Neither DeleteFile or NewFile will have effect until this
* function will be called. Returns false if operation failed.
* If operation failed, postponed operations remains in the
* same state as before calling Flush(), i.e. for example
* user can be prompted to free some space on drive then retry
* Flush().
*/
bool Flush ();
/// Get Nth file in archive or 0
void *GetFile (size_t no)
{ return (no < dir.GetSize ()) ? dir.Get (no) : 0; }
/// Find a file in archive; returns a handle or 0
void *FindName (const char *name) const;
/// Query name from handle
char *GetFileName (void *entry) const
{ return ((ArchiveEntry*)entry)->filename; }
/// Query file size from handle
size_t GetFileSize (void *entry) const
{ return ((ArchiveEntry*)entry)->info.ucsize; }
/// Query filetime from handle
void GetFileTime (void *entry, csFileTime &ztime) const;
/// Set filetime for handle
void SetFileTime (void *entry, const csFileTime &ztime);
/// Query archive filename
char *GetName () const
{ return filename; }
/// Query archive comment
char *GetComment () const
{ return comment; }
};
inline void csArchive::GetFileTime (void *entry, csFileTime &ztime) const
{
if (entry)
{
UnpackTime (((ArchiveEntry*)entry)->info.last_mod_file_date,
((ArchiveEntry*)entry)->info.last_mod_file_time,
ztime);
}
}
inline void csArchive::SetFileTime (void *entry, const csFileTime &ztime)
{
if (entry)
{
PackTime (ztime,
((ArchiveEntry*)entry)->info.last_mod_file_date,
((ArchiveEntry*)entry)->info.last_mod_file_time);
}
}
#endif // __CS_ARCHIVE_H__
|