1 // Pak.cpp: implementation of the CPak class.
3 //////////////////////////////////////////////////////////////////////
8 //////////////////////////////////////////////////////////////////////
9 // Construction/Destruction
10 //////////////////////////////////////////////////////////////////////
24 bool CPak::Open(const char *filename)
30 uf = unzOpen(filename);
35 int err = unzGetGlobalInfo (uf,&gi);
44 // ok, now build the internal list of entries
53 pe.pakname=m_filename;
56 char filename_inzip[256];
57 unz_file_info file_info;
59 // const char *string_method;
60 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
66 pe.filename=filename_inzip;
67 pe.compressed=file_info.compressed_size;
68 pe.uncompressed=file_info.uncompressed_size;
70 entries.push_back(pe);
72 } while (unzGoToNextFile(uf)==UNZ_OK);
81 bool CPak::Save(const char *path)
94 for ( std::list<pak_entry>::const_iterator iEntry = entries.begin() ; iEntry != entries.end() ; iEntry++)
100 if (pe.pakname.compare(m_filename)==0)
104 unsigned char *buf=Extract(pe.filename.c_str(),size);
111 std::string name=pe.filename;
115 zipOpenNewFileInZip(zf,name.c_str(),&zipfi,NULL,0,NULL,0,NULL,Z_DEFLATED,Z_DEFAULT_COMPRESSION);
116 zipWriteInFileInZip(zf,buf,size);
117 zipCloseFileInZip(zf);
123 // its in another pack
126 if (!p.Open(pe.pakname.c_str()))
130 unsigned char *buf=p.Extract(pe.filename.c_str(),size);
137 std::string name=pe.filename;
141 zipOpenNewFileInZip(zf,name.c_str(),&zipfi,NULL,0,NULL,0,NULL,Z_DEFLATED,Z_DEFAULT_COMPRESSION);
142 zipWriteInFileInZip(zf,buf,size);
143 zipCloseFileInZip(zf);
151 // its an external file
154 fp=fopen(pe.pathname.c_str(),"rb");
159 fseek(fp,0,SEEK_END);
162 unsigned char *buf=new unsigned char[size];
163 fread(buf,sizeof(unsigned char),size,fp);
171 std::string name=pe.filename;
175 zipOpenNewFileInZip(zf,name.c_str(),&zipfi,NULL,0,NULL,0,NULL,Z_DEFLATED,Z_DEFAULT_COMPRESSION);
176 zipWriteInFileInZip(zf,buf,size);
177 zipCloseFileInZip(zf);
185 zipClose(zf,"Created by Pk3man - http://pk3man.sourceforge.net");
200 bool CPak::IsModified()
205 pak_entry CPak::FindPE(const char *path)
209 for ( std::list<pak_entry>::const_iterator iEntry = entries.begin() ; iEntry != entries.end() ; iEntry++)
213 if (!pe.rename && pe.filename.compare(path)==0)
216 if (pe.rename && pe.newname.compare(path)==0)
228 return entries.empty();
231 unsigned char *CPak::Extract(const char *path, long &size)
235 uf = unzOpen(m_filename.GetBuffer());
240 int err = unzGetGlobalInfo (uf,&gi);
247 unzGoToFirstFile(uf);
251 char filename_inzip[256];
252 unz_file_info file_info;
254 err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
262 size=file_info.uncompressed_size;
264 if (strcmp(path,filename_inzip)==0)
269 if (unzOpenCurrentFile(uf)!=UNZ_OK)
275 unsigned char *buf=new unsigned char[size];
276 unzReadCurrentFile(uf,buf,size);
277 unzCloseCurrentFile(uf);
282 } while (unzGoToNextFile(uf)==UNZ_OK);
289 bool CPak::ExtractTo(const char *path, char *pathto)
292 unsigned char *buf=Extract(path,size);
297 FILE *f=fopen(pathto,"wb");
300 fwrite(buf,sizeof(unsigned char),size,f);
310 bool CPak::IsInPak(const char *path)
314 for ( std::list<pak_entry>::const_iterator iEntry = entries.begin() ; iEntry != entries.end() ; iEntry++)
318 if (!pe.rename && pe.filename.compare(path)==0)
321 if (pe.rename && pe.newname.compare(path)==0)
328 bool CPak::AddExternalFile(const char *name,const char *path)
337 fseek(fp,0,SEEK_END);
348 pe.uncompressed=size;
350 entries.push_back(pe);
358 bool CPak::AddPakFile(const char *name,const char *pakname,long comp, long uncomp)
370 pe.uncompressed=uncomp;
372 entries.push_back(pe);
379 bool CPak::Delete(const char *path)
383 for ( std::list<pak_entry>::iterator iEntry = entries.begin() ; iEntry != entries.end() ; iEntry++)
387 if ((!pe.rename && pe.filename.compare(path)==0) || (pe.rename && pe.newname.compare(path)==0))
389 entries.erase(iEntry);
398 bool CPak::Rename(const char *path,const char *newname)
402 for ( std::list<pak_entry>::iterator iEntry = entries.begin() ; iEntry != entries.end() ; iEntry++)
406 if ((!pe.rename && pe.filename.compare(path)==0) || (pe.rename && pe.newname.compare(path)==0))
408 entries.erase(iEntry);
413 entries.push_back(pe);