ZipFile.h
//
#ifndef Zipfile_h
#define Zipfile_h
#include <string>
#include <vector>
#define ZIP_OK 0
#define Zip_err_open 1
#define Zip_err_wrong_file 2
#define Zip_err_wrong_header 3
#define BYTE unsigned char
#define UI32 unsigned int
#define UI16 unsigned short
struct Fileheader
{
UI32 signature;
Ui16 version_made_by;
Ui16 version_needed;
Ui16 bitflags;
Ui16 Comp_method;
Ui16 Lastmodfiletime;
Ui16 lastmodfiledate;
UI32 crc_32;
UI32 comp_size;
UI32 uncompr_size;
Ui16 Fname_len;
Ui16 Extra_field_len;
Ui16 Fcomment_len;
Ui16 Disk_num_start;
Ui16 Internal_fattribute;
UI32 External_fattribute;
UI32 Relative_offset;
char* file_name;
char* Extra_field;
char* file_comment;
};
Class Czipfile
{
Private
Public
Czipfile ();
Czipfile (std::string);
Virtual ~czipfile ();
void resetcontent (void);
std::string getfilename (void);
void Setfilename (std::string);
BOOL OpenFile (void);
int getfilesnumber (void);
Fileheader * getfileattributes (int);
Private
void Readcentraldirectory (BYTE * Data,long len);
int Readfileheader (BYTE * data, Fileheader * HDR);
UI32 readvalue (unsigned char * buf, int nbits);
Std::string M_filename;
Std::vector<void*> m_fileattributes;
};
#endif/*zipfile_h * *
//
ZipFile.cpp:implementation file
//
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "ZipFile.h"
using namespace Std;
/////////////////////////////////////////////////////////////////////////////
Czipfile
Czipfile::czipfile ()
{
M_filename= "";
}
Czipfile::czipfile (string fn)
{
M_filename = fn;
}
Czipfile::~czipfile ()
{
Resetcontent ();
}
void Czipfile::resetcontent (void)
{
for (int i=0;i<getfilesnumber (); i++)
Delete (GetFileAttributes (i));
M_fileattributes.clear ();
M_filename= "";
}
String Czipfile::getfilename (void)
{
return m_filename;
}
void Czipfile::setfilename (string fn)
{
M_filename = fn;
}
int Czipfile::getfilesnumber (void)
{
Return (M_fileattributes.size ());
}
BOOL Czipfile::openfile (void)
{
if (m_filename== "")
return zip_err_open;
Read all the file data
FILE * FP;
Fp=fopen (M_filename.c_str (), "RB");
if (fp==null)
return zip_err_open;
Fseek (Fp,0,seek_end);
Long Siz=ftell (FP);
Fseek (Fp,0,seek_set);
BYTE *buf=new Byte[siz];
UI32 n= fread ((void*) buf, (unsigned int) SIZ,1,FP);
Fclose (FP);
Local file header signature control to check the file correctiveness
if (* (ui32*) buf)!=0x04034b50)
return zip_err_wrong_file;
Readcentraldirectory (Buf,siz);
return ZIP_OK;
}
void Czipfile::readcentraldirectory (BYTE * Data,long len)
{
/*read the "the" "The" "Directory Data Structure;
Data contains the zipped archive;
Return the number of files read*/
BYTE * TMP;
Search the signature
Tmp=data;
UI32 * TMP2;
Tmp2= (UI32 *) tmp;
len-=4;
while ((*TMP2)!=0x02014b50 && len)
{
tmp++;
Tmp2= (UI32 *) tmp;
len--;
}
Retrieve the Fileheader for each file
int siz;
Todo
{
Fileheader Fhdr;
Siz = Readfileheader (tmp, &FHDR);
if (siz)
{
Fileheader *PFHDR = new (Fileheader);
*PFHDR=FHDR;
M_fileattributes.push_back (PFHDR);
}
Tmp+=siz;
}while (siz!=0);
}
int Czipfile::readfileheader (BYTE * data, Fileheader * HDR)
{
/*name:int Czipfile::readfileheader (BYTE data, cstring* stdata)
/*it read the file header in the Structure
Return the number of bytes read; If the stream does not contain
A valid Local_file_header 0 is returned and the stream pointer (f)
is not modified
St is filled with the data;
*/
BYTE * ORIGDATA=DATA;
Fileheader HDR;
Fill the values into the File_header structure
Hdr->signature = (UI32) readvalue (data, 32);
if (HDR->SIGNATURE!=0X02014B50)
return 0; No further file
hdr->version_made_by = (ui16) readvalue (data+4, 16);
hdr->version_needed = (ui16) readvalue (data+6, 16);
Hdr->bitflags = (ui16) readvalue (data+8, 16);
Hdr->comp_method = (ui16) readvalue (data+10,16);
Hdr->lastmodfiletime = (ui16) readvalue (data+12,16);
Hdr->lastmodfiledate = (ui16) readvalue (data+14,16);
Hdr->crc_32 = (ui32) readvalue (data+16,32);
Hdr->comp_size = (ui32) readvalue (data+20,32);
Hdr->uncompr_size = (ui32) readvalue (data+24,32);
Hdr->fname_len = (ui16) readvalue (data+28,16);
Hdr->extra_field_len = (ui16) readvalue (data+30,16);
Hdr->fcomment_len = (ui16) readvalue (data+32,16);
Hdr->disk_num_start = (ui16) readvalue (data+34,16);
Hdr->internal_fattribute = (ui16) readvalue (data+36,16);
Hdr->external_fattribute = (ui32) readvalue (data+38,32);
Hdr->relative_offset = (ui32) readvalue (data+42,32);
data+=46;
if (hdr->fname_len>0)
{
Char *fn;
Fn=new (char[hdr->fname_len+1]);
strncpy (FN, (char*) data,hdr->fname_len);
Fn[hdr->fname_len]= ' ";
Hdr->file_name = fn;
data+=hdr->fname_len;
}
if (hdr->extra_field_len>0)
{
Char *fn;
Fn=new (char[hdr->extra_field_len+1]);
strncpy (FN, (char*) data,hdr->extra_field_len);
Fn[hdr->extra_field_len]= ' ";
Hdr->extra_field = fn;
Data + + hdr->extra_field_len;
}
File Comment
if (hdr->fcomment_len>0)
{
Char *fn;
Fn=new (char[hdr->fcomment_len+1]);
strncpy (FN, (char*) data,hdr->fcomment_len);
Fn[hdr->fcomment_len]= ' ";
Hdr->file_comment = fn;
Data + + hdr->extra_field_len;
}
return (Data-origdata);
}
UI32 czipfile::readvalue (unsigned char * buf, int nbits)
{
/*name:void readvalue (char*buf, int nbits)
/*return the value read from the buffer of size nbits;
*/
UI32 value = 0;
Switch (nbits)
{
Case (8):
Value = (ui32) * (BUF);
Break
Case (16):
Value = ((UI32) * (buf+1)) <<8) + (UI32) * (BUF);
Break
Case (24):
Value = (((UI32) * (buf+2)) <<16) + ((UI32) * (buf+1)) <<8) + ((UI32) * (BUF));
Break
Case (32):
Value = (((UI32) * (buf+3)) <<24) + ((UI32) * (buf+2)) <<16) + (((UI32) * (buf+1)) <<8) + ((UI32) * (BUF));
Break
Default
ASSERT (1);
Break
}
return (value);
}
Fileheader *czipfile::getfileattributes (int index)
{
if (index<0 | | | index >m_fileattributes.size ())
return NULL;
Else
Return ((Fileheader *) m_fileattributes.at (index));
}
Main.cpp
#include <stdio.h>
#include "ZipFile.h"
int main (int argc, char* argv[])
{
if (2!= argc)
{
printf ("ZipFile must provide.\n");
return 0;
}
Czipfile ziptest;
Ziptest.setfilename (argv[1]);
Ziptest.openfile ();
for (int i = 0;i< ziptest.getfilesnumber (); i++)
{
printf ("%s\n", Ziptest.getfileattributes (i)->file_name);
}
return 0;
}