C/C++ Reference
ZipFileIterator.h
00001 /*
00002  *     ____             _________                __                _     
00003  *    / __ \___  ____ _/ /_  __(_)___ ___  ___  / /   ____  ____ _(_)____
00004  *   / /_/ / _ \/ __ `/ / / / / / __ `__ \/ _ \/ /   / __ \/ __ `/ / ___/
00005  *  / _, _/  __/ /_/ / / / / / / / / / / /  __/ /___/ /_/ / /_/ / / /__  
00006  * /_/ |_|\___/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_____/\____/\__, /_/\___/  
00007  *                                                       /____/          
00008  *
00009  *                  Barracuda Embedded Web-Server
00010  *
00011  ****************************************************************************
00012  *                            HEADER
00013  *
00014  *   $Id: ZipFileIterator.h 2316 2011-01-29 00:49:18Z wini $
00015  *
00016  *   COPYRIGHT:  Real Time Logic LLC, 2003-2008
00017  *               http://www.realtimelogic.com
00018  *
00019  *   The copyright to the program herein is the property of
00020  *   Real Time Logic. The program may be used or copied only
00021  *   with the written permission from Real Time Logic LLC or
00022  *   in accordance with the terms and conditions stipulated in
00023  *   the agreement under which the program has been supplied.
00024  ****************************************************************************
00025  *
00026  *
00027  */
00028 #ifndef __ZipFileIterator_h
00029 #define __ZipFileIterator_h
00030 
00031 #include <HttpServer.h>
00032 #include <CspRunTm.h>
00033 
00034 #ifndef __DOXYGEN__
00035 struct ZipContainer;
00036 struct ZipFileHeaderData;
00037 #endif
00038 
00049 typedef struct ZipReader
00050 #ifdef __cplusplus
00051 : public CspReader
00052 {
00053       ZipReader() {}
00054       ZipReader(CspReader_Read r, U32 zipFileSize);
00055 #else
00056 { 
00057       CspReader super; /* As if inherited. */
00058 #endif
00059       U32 size;
00060 } ZipReader;
00061 
00062 #ifdef __cplusplus
00063 extern "C" {
00064 #endif
00065 BA_API void ZipReader_constructor(ZipReader* o, CspReader_Read r, U32 zipFileSize);
00066 #ifdef __cplusplus
00067 }
00068 inline ZipReader::ZipReader(CspReader_Read r, U32 zipFileSize) {
00069    ZipReader_constructor(this, r, zipFileSize); }
00070 #endif
00071 
00072 
00073 typedef enum {
00074    ZipErr_Buf = -2000, /* The buffer is too small. */
00075    ZipErr_Reading, /* Reading failed. */
00076    ZipErr_Spanned,  /* Spanned/Split archives not supported. */
00077    ZipErr_Compression, /* Unsupported compr. Can be one of Stored or Deflated */
00078    ZipErr_Incompatible, /* Unknown ZIP Central Directory Structure. */
00079    ZipErr_NoError = 0
00080 } ZipErr;
00081 
00082 
00083 typedef enum {
00084    ZipComprMethod_Stored=0,
00085    ZipComprMethod_Deflated=8,
00086    ZipComprMethod_AES=99       /* Gianluca 9/22 */
00087 } ZipComprMethod;
00088 
00089 
00090 #ifndef __DOXYGEN__
00091 
00092 typedef struct ZipFileHeader
00093 {
00094 #ifdef __cplusplus
00095       const char* getFn();
00096       const char* getEf();
00097           const char* getAESef();
00098       bool isDirectory();
00099       U16 getFnLen();
00100       U16 getEfLen();
00101       U16 getFcLen();
00102       ZipComprMethod getComprMethod();
00103       U32 getUncompressedSizeLittleEndian();
00104       U32 getCrc32LittleEndian();
00105       U32 getCompressedSize();
00106       U32 getUncompressedSize();
00107       U32 getCrc32();
00108       static const char* e2str(ZipErr e);
00109       U16 getVersionMade();
00110       U16 getFlag();
00111       U32 getDataOffset();
00112       U32 getTime();
00113       CspReader* getReader();
00114    private:
00115 #endif
00116       struct ZipFileHeaderData* data;
00117       char* fn;  /* File name. Not null terminated. */
00118       U8* ef;    /* Extra field - GV 9/28 */
00119       U8* AESef; /* AES extra field - GV 11/30/2010 */
00120       ZipReader* reader;
00121       U8* buf;
00122       U32 bufSize;
00123       U32 fileHeaderOffs;
00124       ZipComprMethod comprMethod;
00125       U16 fnLen;
00126       U16 efLen;
00127       U16 fcLen;
00128 } ZipFileHeader;
00129 
00130 #ifdef __cplusplus
00131 extern "C" {
00132 #endif
00133 #define ZipFileHeader_getFn(o) (o)->fn
00134 #define ZipFileHeader_getEf(o) (o)->ef
00135 #define ZipFileHeader_getAESef(o) (o)->AESef
00136 #define ZipFileHeader_isDirectory(o) ((o)->fn[(o)->fnLen-1] == '/')
00137 #define ZipFileHeader_getFnLen(o) (o)->fnLen
00138 #define ZipFileHeader_getEfLen(o) (o)->efLen
00139 #define ZipFileHeader_getFcLen(o) (o)->fcLen
00140 #define ZipFileHeader_getComprMethod(o) (o)->comprMethod
00141 #define ZipFileHeader_getReader(o) (CspReader*)(o)->reader
00142 BA_API U32 ZipFileHeader_getUncompressedSizeLittleEndian(ZipFileHeader* o);
00143 BA_API U32 ZipFileHeader_getCrc32LittleEndian(ZipFileHeader* o);
00144 BA_API U32 ZipFileHeader_getCompressedSize(ZipFileHeader* o);
00145 BA_API U32 ZipFileHeader_getUncompressedSize(ZipFileHeader* o);
00146 BA_API U32 ZipFileHeader_getCrc32(ZipFileHeader* o);
00147 BA_API const char* ZipFileHeader_e2str(ZipErr e);
00148 
00149 /* Return: The operating system that compressed the file. */
00150 BA_API U16 ZipFileHeader_getVersionMade(ZipFileHeader* o);
00151 
00152 /*  ZipFileHeader_getFlag
00153      Bit 0: If set, indicates that the file is encrypted.
00154      Bit 2  Bit 1
00155      0      0    Normal (-en) compression option was used.
00156      0      1    Maximum (-exx/-ex) compression option was used.
00157      1      0    Fast (-ef) compression option was used.
00158      1      1    Super Fast (-es) compression option was used.
00159 */
00160 BA_API U16 ZipFileHeader_getFlag(ZipFileHeader* o);
00161 
00162 BA_API U32 ZipFileHeader_getDataOffset(ZipFileHeader* o);
00163 BA_API U32 ZipFileHeader_getTime(ZipFileHeader* o);
00164 
00165 #ifdef __cplusplus
00166 }
00167 inline const char* ZipFileHeader::getFn() {
00168    return ZipFileHeader_getFn(this);
00169 }
00170 inline const char* ZipFileHeader::getEf() {
00171    return (char*)ZipFileHeader_getEf(this);
00172 }
00173 inline const char* ZipFileHeader::getAESef() {
00174    return (char*)ZipFileHeader_getAESef(this);
00175 }
00176 inline bool ZipFileHeader::isDirectory() {
00177    return ZipFileHeader_isDirectory(this) ? true : false;
00178 }
00179 inline U16 ZipFileHeader::getFnLen() {
00180    return ZipFileHeader_getFnLen(this);
00181 }
00182 inline U16 ZipFileHeader::getEfLen() {
00183    return ZipFileHeader_getEfLen(this);
00184 }
00185 inline U16 ZipFileHeader::getFcLen() {
00186    return ZipFileHeader_getFcLen(this);
00187 }
00188 inline ZipComprMethod ZipFileHeader::getComprMethod() {
00189    return ZipFileHeader_getComprMethod(this);
00190 }
00191 inline CspReader* ZipFileHeader::getReader() {
00192    return ZipFileHeader_getReader(this);
00193 }
00194 inline U32 ZipFileHeader::getUncompressedSizeLittleEndian() {
00195    return ZipFileHeader_getUncompressedSizeLittleEndian(this);
00196 }
00197 inline U32 ZipFileHeader::getCrc32LittleEndian() {
00198    return ZipFileHeader_getCrc32LittleEndian(this);
00199 }
00200 inline U32 ZipFileHeader::getCompressedSize() {
00201    return ZipFileHeader_getCompressedSize(this);
00202 }
00203 inline U32 ZipFileHeader::getUncompressedSize() {
00204    return ZipFileHeader_getUncompressedSize(this);
00205 }
00206 inline U32 ZipFileHeader::getCrc32() {
00207    return ZipFileHeader_getCrc32(this);
00208 }
00209 inline const char* ZipFileHeader::e2str(ZipErr e) {
00210    return ZipFileHeader_e2str(e);
00211 }
00212 inline U16 ZipFileHeader::getVersionMade() {
00213    return ZipFileHeader_getVersionMade(this);
00214 }
00215 inline U16 ZipFileHeader::getFlag() {
00216    return ZipFileHeader_getFlag(this);
00217 }
00218 inline U32 ZipFileHeader::getDataOffset() {
00219    return ZipFileHeader_getDataOffset(this);
00220 }
00221 inline U32 ZipFileHeader::getTime() {
00222    return ZipFileHeader_getTime(this);
00223 }
00224 #endif
00225 
00226 #endif /* __DOXYGEN__ */
00227 
00228 
00229 #ifndef __DOXYGEN__
00230 typedef struct ZipFileInfo
00231 {
00232       U32 crc32;
00233       U32 dataOffset;
00234       U32 uncompressedSize;
00235       U32 compressedSize;
00236       U32 time;
00237       ZipComprMethod comprMethod;
00238       U16 flag;
00239       U8  *ef;  /* GV 9/28 */
00240       U8  *AESef; /* GV 11/30/2010 */
00241 } ZipFileInfo;
00242 #endif
00243 
00244 #if defined(B_LITTLE_ENDIAN)
00245 #define ZipFileInfo_makeLittleEndianU32(x) x
00246 #elif defined(B_BIG_ENDIAN)
00247 #define ZipFileInfo_makeLittleEndianU32(x) \
00248  ((U32)((((U32)(x) & 0x000000ffU) << 24) | \
00249  (((U32)(x) & 0x0000ff00U) <<  8) | \
00250  (((U32)(x) & 0x00ff0000U) >>  8) | \
00251  (((U32)(x) & 0xff000000U) >> 24))) 
00252 #else
00253 #error in config/make file, you must define one of B_LITTLE_ENDIAN or B_BIG_ENDIAN
00254 #endif
00255 
00256 #define ZipFileInfo_getCrc32LittleEndian(o) \
00257   ZipFileInfo_makeLittleEndianU32((o)->crc32);
00258 #define ZipFileInfo_getUncompressedSizeLittleEndian(o) \
00259   ZipFileInfo_makeLittleEndianU32((o)->uncompressedSize);
00260 
00261 
00262 #define ZipFileInfo_constructor(o, fileHeader, EfPtr) \
00263 do { \
00264    (o)->crc32 = ZipFileHeader_getCrc32(fileHeader); \
00265    (o)->dataOffset = ZipFileHeader_getDataOffset(fileHeader); \
00266    (o)->uncompressedSize = ZipFileHeader_getUncompressedSize(fileHeader); \
00267    (o)->compressedSize = ZipFileHeader_getCompressedSize(fileHeader); \
00268    (o)->time = ZipFileHeader_getTime(fileHeader); \
00269    (o)->comprMethod = ZipFileHeader_getComprMethod(fileHeader); \
00270    (o)->flag = ZipFileHeader_getFlag(fileHeader); \
00271    (o)->ef = EfPtr; \
00272    (o)->AESef = (EfPtr + (ZipFileHeader_getAESef(fileHeader) - ZipFileHeader_getEf(fileHeader))); \
00273 }while(0)
00274 
00275 
00276 #ifndef __DOXYGEN__
00277 typedef struct
00278 {
00279       U32 dataOffset;
00280       U32 uncompressedSize;
00281       U32 compressedSize;
00282       ZipComprMethod comprMethod;
00283 } MiniZipFileInfo;
00284 #endif
00285 
00286 #define MiniZipFileInfo_constructor(o, fileHeader) \
00287 do { \
00288    (o)->dataOffset = ZipFileHeader_getDataOffset(fileHeader); \
00289    (o)->uncompressedSize = ZipFileHeader_getUncompressedSize(fileHeader); \
00290    (o)->compressedSize = ZipFileHeader_getCompressedSize(fileHeader); \
00291    (o)->comprMethod = ZipFileHeader_getComprMethod(fileHeader); \
00292 }while(0)
00293 
00294 
00295 #ifndef __DOXYGEN__
00296 
00297 typedef struct CentralDirIterator
00298 {
00299 #ifdef __cplusplus
00300       CentralDirIterator(ZipContainer* container);
00301       CentralDirIterator(ZipContainer* container, U8* buf, U32 bufSize);
00302       ZipErr getECode();
00303       ZipFileHeader* getElement();
00304       bool nextElement();
00305    private:
00306 #endif
00307       ZipFileHeader fileHeader;
00308       U32 curFileHeaderOffs;
00309       ZipErr err;
00310       U16 entriesInCd;
00311       U16 curEntry;
00312 } CentralDirIterator;
00313 
00314 #ifdef __cplusplus
00315 extern "C" {
00316 #endif
00317 #define CentralDirIterator_getECode(o) (o)->err
00318 BA_API void CentralDirIterator_constructor(CentralDirIterator* o,
00319                                     struct ZipContainer* container);
00320 /* Re-entrant version,
00321  * minimum size for buffer is 256
00322  */
00323 BA_API void CentralDirIterator_constructorR(CentralDirIterator* o,
00324                                      struct ZipContainer* container,
00325                                      U8* buf, U32 bufSize);
00326 BA_API ZipFileHeader* CentralDirIterator_getElement(CentralDirIterator* o);
00327 BA_API BaBool CentralDirIterator_nextElement(CentralDirIterator* o);
00328 #ifdef __cplusplus
00329 }
00330 inline CentralDirIterator::CentralDirIterator(ZipContainer* container) {
00331    CentralDirIterator_constructor(this, container);
00332 }
00333 inline CentralDirIterator::CentralDirIterator(
00334    ZipContainer* container, U8* buf, U32 bufSize) {
00335    CentralDirIterator_constructorR(this, container, buf, bufSize);
00336 }
00337 inline ZipErr CentralDirIterator::getECode() {
00338    return CentralDirIterator_getECode(this);
00339 }
00340 inline ZipFileHeader* CentralDirIterator::getElement() {
00341    return CentralDirIterator_getElement(this);
00342 }
00343 inline bool CentralDirIterator::nextElement() {
00344    return CentralDirIterator_nextElement(this) ? true : false;
00345 }
00346 #endif
00347 
00348 #endif /* __DOXYGEN__ */
00349 
00350 
00351 
00357 typedef struct ZipContainer
00358 {
00359 #ifdef __cplusplus
00360       ZipContainer(){}
00361       void *operator new(size_t s) { return ::baMalloc(s); }
00362       void operator delete(void* d) { if(d) ::baFree(d); }
00363       void *operator new(size_t, void *place) { return place; }
00364       void operator delete(void*, void *) { }
00365  
00373       ZipContainer(ZipReader* reader, U8* buf, U32 bufSize);
00374       ZipErr getECode();
00375    private:
00376 #endif
00377       ZipReader* reader;
00378       U8* buf;
00379       U32 bufSize;
00380       U32 cdOffset;
00381       ZipErr errCode;
00382       U16 entriesInCd;
00383 } ZipContainer;
00384 
00385 #ifdef __cplusplus
00386 extern "C" {
00387 #endif
00388 BA_API void ZipContainer_constructor(ZipContainer* o,
00389                               ZipReader* reader,
00390                               U8* buf,
00391                               U32 bufSize);
00392 #define ZipContainer_getECode(o) (o)->errCode
00393 #ifdef __cplusplus
00394 }
00395 inline ZipContainer::ZipContainer(ZipReader* reader, U8* buf, U32 bufSize) {
00396    ZipContainer_constructor(this,reader,buf,bufSize); }
00397 inline ZipErr ZipContainer::getECode() {
00398    return ZipContainer_getECode(this); }
00399 #endif
00400 
00401  /* end of IO */ 
00403 
00404 
00405 #endif