Code rewrite week 2 Notes
Code rewrite week 2 Notes
Completed new HPI File handling, requires a slight change to TA3D_Platfrom, specifically in stl includes, need to add a #include <list>, this should be all thats needed to get it to work, main changes from last week include no longer needs a global HPIInfo variable to the class, as well as fixed several memory leaks, and tracks hpi files it works with so it can close them when the hpi file manager class object is destoryed.
Also added quite a few notes throughout the code to make it easier to read and follow along.
I am not going to 'paste' code here form now on, instead I will upload all code changes I've made to my website on fridays and zuf can then download and implement them.
++Cire.
Also added quite a few notes throughout the code to make it easier to read and follow along.
I am not going to 'paste' code here form now on, instead I will upload all code changes I've made to my website on fridays and zuf can then download and implement them.
++Cire.
Ok i've started to work through the remaining files to get the complete project to compile under VC 2005 without any serious issues, however that said i've run into quite a few issues.
First and formost is with the configuration file, which is a good thing but in alot of cases it uses #define blah 1 or #define blah true, now you don't need to declare things like this simply #define blah will do the trick, if you don't want the use of it set it to #undef blah, to check use #if defined blah or #ifdef blah, in many cases i find most of your checks as #if blah which is throwing compiler issues on my end. This is also the more 'standarized' way of doing things.
Next remember that we MUST include stdafx.h at the top of every cpp file and before we include anything else, that said everything included in stdafx and ta3d_platfrom will be aviliable to all .h files as well as that cpp file, thus no need of including string/lib/stdio ect throughout all .h, .cpp files.
Next running into macro redifincations on language in ta3dbase, for these:
are also defined in winnt, i havn't checked how they are used throughout the package but one probably could simply undef them if already defined, then redefine them to 'quite' compling.
++Cire.
First and formost is with the configuration file, which is a good thing but in alot of cases it uses #define blah 1 or #define blah true, now you don't need to declare things like this simply #define blah will do the trick, if you don't want the use of it set it to #undef blah, to check use #if defined blah or #ifdef blah, in many cases i find most of your checks as #if blah which is throwing compiler issues on my end. This is also the more 'standarized' way of doing things.
Next remember that we MUST include stdafx.h at the top of every cpp file and before we include anything else, that said everything included in stdafx and ta3d_platfrom will be aviliable to all .h files as well as that cpp file, thus no need of including string/lib/stdio ect throughout all .h, .cpp files.
Next running into macro redifincations on language in ta3dbase, for these:
Code: Select all
#define LANG_ENGLISH 0x0
#define LANG_FRENCH 0x1
#define LANG_GERMAN 0x2
#define LANG_SPANISH 0x3
#define LANG_ITALIAN 0x4
++Cire.
This ...
Can be removed from ta3d.h, they are now in platforms.h as macros. for the record when writting multiple instances of a function like this its better to use a template function. You coulda written these as 1 function using template instead of multiple. However that said the macros should do the same trick.
++Cire.
Code: Select all
#ifndef ALLEGRO_WINDOWS
int min(int a,int b)
{
return (a<b ? a : b);
}
float min(float a,float b)
{
return (a<b ? a : b);
}
int max(int a,int b)
{
return (a<b ? b : a);
}
float max(float a,float b)
{
return (a<b ? b : a);
}
#endif
++Cire.
While working with gaf, I found another serious issue, that i'am not sure how you got to compile. Again it was the dynamic size of an array, which is located in the function [get_gaf_entry_name], the line is:
I'am totally bewildered on how you get this to compile, as its against most C/C++ rules, this allocates a dynamic array, which C does not support, so either your compile is adjusting by inserting some code to handle this, or something, in either case thier is seriious chances of causing crashers with this type of allocation, i strongly suggest that we try to get outa the habbit of doing this.
Zuff: Using the new hpi system. After attaining the newest code from me on friday i'am hoping we can get this into play, I do realize that it will break lots of code but it shouln't take too long to search through and quickly fix everything, I believe the benifits of using it will outweight its troubles...Anyhow to use it is rather simple
First you will need to do something similar to..
Do this at the top of ta3d.cpp, then assign a global hpi file object suchas...
Now as I suggested while intro is playing in another thread, create the hpihandler and it should build the directory structure pretty fast, something like...
This requires that the exception code that I gave eariler in another thread be included. You do not need to put stuff between () in the guard call in quotes. this should catch any errors thou problem is it will continue reguardless of any seirous issues, u could use other guard functions to catch errors and display a message as well.
Anyhow after the directory structure is built it simply a matter of calling to the hpi handler to retreive data in byte * format such as...
I noticed while starting to dig deeper into code that you need to be able to read directory structures and search for stuff. I'am going to expand the hpi handler to be able to do this later this week.
I'am currently rewritting gaf handler as the code also needs rewritten, and I will use a system similar to the hpi handler.
++Cire.
Code: Select all
int pointers[header.Entries];
Zuff: Using the new hpi system. After attaining the newest code from me on friday i'am hoping we can get this into play, I do realize that it will break lots of code but it shouln't take too long to search through and quickly fix everything, I believe the benifits of using it will outweight its troubles...Anyhow to use it is rather simple
First you will need to do something similar to..
Code: Select all
using namespace TA3D::UTILS::HPI;
Code: Select all
cHPIHandler *g_HPIHandler;
Code: Select all
guard( Starting HPI Handler and building directory structures );
g_HPIHandler = new cHPIHandler( "" );
unguard;
Anyhow after the directory structure is built it simply a matter of calling to the hpi handler to retreive data in byte * format such as...
Code: Select all
byte *blah;
blah = g_HPIHandler->PullFromHPI( "blah.ext" );
if( blah )
// call went good and data retreived.
else
// file not found
I'am currently rewritting gaf handler as the code also needs rewritten, and I will use a system similar to the hpi handler.
++Cire.
I havn't had much time today do to much, but I have been thinking about how to further improve the engine and what not with what I have done so far.
I did get around to doing a bit more research on gaf's and, to laying framework for searching for files using a signal * wildcard from within hpi directories.
One idea I"am kicking around is rather then having a load function on 3do/texturs/gaf's ect I think what I will do is place a function within the hpi manager class that will construct and return a class for whatever you want to load, so for example we would have..
gaf = hpimanager->loadgaf( "blah.gaf" );
If anyone has any other ideas that they would like to see implement in respects to hpi manager and what not i'd like to hear them.
++Cire.
I did get around to doing a bit more research on gaf's and, to laying framework for searching for files using a signal * wildcard from within hpi directories.
One idea I"am kicking around is rather then having a load function on 3do/texturs/gaf's ect I think what I will do is place a function within the hpi manager class that will construct and return a class for whatever you want to load, so for example we would have..
gaf = hpimanager->loadgaf( "blah.gaf" );
If anyone has any other ideas that they would like to see implement in respects to hpi manager and what not i'd like to hear them.
++Cire.
I finished the search algorithim required to do lookups in hpi files. Basically you pass it a std::string that contains the search pattern, and a pointer to a list object, and it will populate the list with whatever files are found. It only supports the '*' wildcard which is all we should need.
I also fully tested the code using current variable definations and all is good. I think thats all we need from the hpi file manager.
Now i'am going to move on to handling gafs. Anyhow, I need to get something off my chest, I seem to be about the only one active throughout the week yet we are supposed to have a sizeable team, perhaps its just my need to 'blog' things, and it certinaly would be nice to see others making entries about thier progress as well so that others know we are moving along. Hate to say it but anyone looking in on this would feel its a one man show, which its not, so i'd like to encourage other developers/staff to post thier progress.
++Cire.
I also fully tested the code using current variable definations and all is good. I think thats all we need from the hpi file manager.
Now i'am going to move on to handling gafs. Anyhow, I need to get something off my chest, I seem to be about the only one active throughout the week yet we are supposed to have a sizeable team, perhaps its just my need to 'blog' things, and it certinaly would be nice to see others making entries about thier progress as well so that others know we are moving along. Hate to say it but anyone looking in on this would feel its a one man show, which its not, so i'd like to encourage other developers/staff to post thier progress.
++Cire.
I had to put a halt on gaf handling mainly because i'am not entirely sure how zuff would like to use them in, weather or not he watns access to a bitmap or something direct byte ect...
I'll confer with him over the weekend and see how it stands, untill then I will ocntinue working on the new website.
++Cire.
I'll confer with him over the weekend and see how it stands, untill then I will ocntinue working on the new website.
++Cire.
- zuzuf
- Administrateur - Site Admin
- Posts: 3281
- Joined: Mon Oct 30, 2006 8:49 pm
- Location: Toulouse, France
- Contact:
okay I am currently fixing a few things in the code and adding your HPI handler to read files from HPI files. I am sorry for not posting very often but I am home only the weekend so...
as far as config.h is concerned, I didn't write this file, it's done automatically by a script which configure the build process on linux by auto detecting the compiler, the linker, needed paths, etc... and I can't remove it because it's needed to build on linux but you can add a windows version of it.
PS: I will need your updated version of the HPI code
as far as config.h is concerned, I didn't write this file, it's done automatically by a script which configure the build process on linux by auto detecting the compiler, the linker, needed paths, etc... and I can't remove it because it's needed to build on linux but you can add a windows version of it.
PS: I will need your updated version of the HPI code
=>;-D Penguin Powered
ok new hpi code:
and the cpp file
Code: Select all
/*
** File: TA3D_hpi.h
** Notes:
** Cire: The original author of most of this code is Joe D, aka Kingbot
** I modified it to be more complain with C++ as it was mostly
** C based. I wrapped it neatly in a class, and exposed only
** those methods that the game engine need to access.
** TODO: If this is to be accessed by multiple threads it should be
** rewritten as it currently can not handle multiple calls.
** HPIITEM might be expanded to keep a reference track of
** how many times it gets asked to decode some file, if it
** reaches some point it might just keep that 'data' in its
** self and return it instead of having to decode each time.
*/
#pragma once
namespace TA3D
{
namespace UTILS
{
namespace HPI
{
#define HEX_HAPI 0x49504148
#define HPI_V1 0x00010000
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
class cHPIHandler
{
// Member Declarations:
private:
#pragma pack(1) // Byte alignment.
struct HPIVERSION
{
sint32 HPIMarker; /* Must be HEX_HAPI */
sint32 Version; /* Must be HPI_V1 */
};
struct HPIHEADER
{
sint32 DirectorySize; /* Directory size */
sint32 Key; /* Decode key */
sint32 Start; /* Directory offset */
};
struct HPIENTRY
{
sint32 NameOffset;
sint32 CountOffset;
sint8 Flag;
};
struct HPICHUNK
{
sint32 Marker; /* always 0x48535153 (SQSH) */
sint8 Unknown1; /* I have no idea what these mean */
sint8 CompMethod; /* 1 = lz77, 2 = zlib */
sint8 Encrypt; /* Is the chunk encrypted? */
sint32 CompressedSize; /* the length of the compressed data */
sint32 DecompressedSize; /* the length of the decompressed data */
sint32 Checksum; /* check sum */
};
struct HPIFILEDATA
{
HPIHEADER H1;
sint8 Key;
std::string HPIFileName;
sint8 *Directory;
FILE *HPIFile;
};
struct HPIITEM
{
HPIFILEDATA *hfd;
HPIENTRY *E1;
sint32 IsDir;
sint8 *Name;
sint32 Size;
};
#pragma pack()
// Member Functions:
private:
void AddArchive( const std::string &FileName );
void LocateAndReadFiles( const std::string &Path, const std::string &FileSearch );
void ProcessRoot( HPIFILEDATA *hfd, const std::string &StartPath, sint32 offset );
void ProcessSubDir( HPIITEM *hi );
sint32 ReadAndDecrypt( sint32 fpos, byte *buff, sint32 buffsize, HPIFILEDATA *HPIInfo );
sint32 ZLibDecompress( byte *out, byte *in, HPICHUNK *Chunk );
sint32 LZ77Decompress( byte *out, byte *in, HPICHUNK *Chunk );
sint32 Decompress( byte *out, byte *in, HPICHUNK *Chunk );
void CloseHPIFile( HPIFILEDATA *hfd );
// void cHPIHandler::CloseCurrentFile( void );
byte *DecodeFileToMem( HPIITEM *hi );
public:
void SearchDirForArchives( const std::string &Path );
// constructor:
cHPIHandler::cHPIHandler( const std::string &Path )
{
SearchDirForArchives( Path );
}
sint32 cHPIHandler::GetFilelist( const std::string &Search, std::list<std::string> *li );
// DeConstructor
~cHPIHandler();
#if defined( DEBUG )
void ShowArchive(); // for debug only we don't need it.
#endif
byte *PullFromHPI( const std::string &FileName );
// Member Variables:
private:
std::string m_cDir; // used when building dir structurs.
// A map of dir/filenames for key, while value is a HPIITEM;
typedef std::map< std::string, HPIITEM *> HPIARCHIVE;
HPIARCHIVE m_Archive;
// A list of HPIFILEDATA, needed only for cleanup.
std::list< HPIFILEDATA * > m_HPIFiles;
}; // class cHPIHandler;
} // namespace HPI
} // namespace utils
} // namespace TA3D
Code: Select all
/*
** File: TA3D_hpi.cpp
** Notes:
** Cire: See notes in TA3D_hpp.h
*/
#include "stdafx.h"
#include "TA3D_hpi.h"
#include <algorithm>
#if defined TA3D_PLATFORM_WINDOWS
#include "tools/win32/include/zlib.h"
#pragma comment(lib, "tools/win32/libs/zlib.lib")
#elif
#include <zlib.h>
#endif
using namespace std;
using namespace TA3D::UTILS::HPI;
sint32 cHPIHandler::ReadAndDecrypt( sint32 fpos, byte *buff, sint32 buffsize, HPIFILEDATA *HPIInfo)
{
sint32 count, tkey, result;
fseek(HPIInfo->HPIFile, fpos, SEEK_SET);
result = (sint32)fread(buff, buffsize, 1, HPIInfo->HPIFile);
if (HPIInfo->Key)
{
for (count = 0; count < buffsize; count++)
{
tkey = (fpos + count) ^ HPIInfo->Key;
buff[count] = tkey ^ ~buff[count];
}
}
return result;
}
sint32 cHPIHandler::ZLibDecompress( byte *out, byte *in, HPICHUNK *Chunk)
{
z_stream zs;
sint32 result;
zs.next_in = in;
zs.avail_in = Chunk->CompressedSize;
zs.total_in = 0;
zs.next_out = out;
zs.avail_out = Chunk->DecompressedSize;
zs.total_out = 0;
zs.msg = NULL;
zs.state = NULL;
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = NULL;
zs.data_type = Z_BINARY;
zs.adler = 0;
zs.reserved = 0;
result = inflateInit(&zs);
if (result != Z_OK) {
//printf("Error on inflateInit %d\nMessage: %s\n", result, zs.msg);
return 0;
}
result = inflate(&zs, Z_FINISH);
if (result != Z_STREAM_END) {
//printf("Error on inflate %d\nMessage: %s\n", result, zs.msg);
zs.total_out = 0;
}
result = inflateEnd(&zs);
if (result != Z_OK) {
//printf("Error on inflateEnd %d\nMessage: %s\n", result, zs.msg);
return 0;
}
return zs.total_out;
}
sint32 cHPIHandler::LZ77Decompress( byte *out, byte *in, HPICHUNK *Chunk)
{
sint32 x, work1, work2, work3, inptr, outptr, done, DPtr;
schar DBuff[4096];
done = 0;
inptr = 0;
outptr = 0;
work1 = 1;
work2 = 1;
work3 = in[inptr++];
while (!done)
{
if ((work2 & work3) == 0)
{
out[outptr++] = in[inptr];
DBuff[work1] = in[inptr];
work1 = (work1 + 1) & 0xFFF;
inptr++;
}
else
{ int
count = *((uint16 *) (in+inptr));
inptr += 2;
DPtr = count >> 4;
if (DPtr == 0)
return outptr;
else
{
count = (count & 0x0f) + 2;
if (count >= 0)
{
for (x = 0; x < count; x++)
{
out[outptr++] = DBuff[DPtr];
DBuff[work1] = DBuff[DPtr];
DPtr = (DPtr + 1) & 0xFFF;
work1 = (work1 + 1) & 0xFFF;
}
}
}
}
work2 *= 2;
if (work2 & 0x0100)
{
work2 = 1;
work3 = in[inptr++];
}
}
return outptr;
}
sint32 cHPIHandler::Decompress( byte *out, byte *in, HPICHUNK *Chunk )
{
sint32 x, Checksum;
Checksum = 0;
for (x = 0; x < Chunk->CompressedSize; x++) {
Checksum += (byte) in[x];
if (Chunk->Encrypt)
in[x] = (in[x] - x) ^ x;
}
if (Chunk->Checksum != Checksum)
{
// GlobalDebugger-> Checksum error! Calculated: 0x%X Actual: 0x%X\n", Checksum, Chunk->Checksum);
return 0;
}
switch (Chunk->CompMethod) {
case 1 : return LZ77Decompress(out, in, Chunk);
case 2 : return ZLibDecompress(out, in, Chunk);
default : return 0;
}
}
byte *cHPIHandler::DecodeFileToMem(HPIITEM *hi)
{
sint32 DeCount,DeLen, x, WriteSize, WritePtr, Offset, Length, FileFlag, *DeSize;
byte *DeBuff, *WriteBuff;
HPIENTRY *Entry;
HPICHUNK *Chunk;
if (!hi)
return NULL;
Entry = hi->E1;
Offset = *((sint32 *) (hi->hfd->Directory + Entry->CountOffset));
Length = *((sint32 *) (hi->hfd->Directory + Entry->CountOffset + 4));
FileFlag = *(hi->hfd->Directory + Entry->CountOffset + 8);
WriteBuff = (byte *)GetMem(Length+1, 0);
if (!WriteBuff)
{
// NO NEED to global deubber this, get meme shoulda done it for us.
return NULL;
}
WriteBuff[Length] = 0;
if (FileFlag) {
DeCount = Length / 65536;
if (Length % 65536)
DeCount++;
DeLen = DeCount * sizeof(sint32);
DeSize = (sint32 *)GetMem(DeLen, 0);
ReadAndDecrypt(Offset, (byte *) DeSize, DeLen, hi->hfd );
Offset += DeLen;
WritePtr = 0;
for (x = 0; x < DeCount; x++) {
Chunk = (HPICHUNK *)GetMem(DeSize[x], 0);
ReadAndDecrypt(Offset, (byte *) Chunk, DeSize[x], hi->hfd);
Offset += DeSize[x];
DeBuff = (byte *) (Chunk+1);
WriteSize = Decompress(WriteBuff+WritePtr, DeBuff, Chunk);
WritePtr += WriteSize;
free(Chunk);
}
free(DeSize);
}
else {
// file not compressed
ReadAndDecrypt(Offset, WriteBuff, Length, hi->hfd );
}
return WriteBuff;
}
void cHPIHandler::CloseHPIFile(HPIFILEDATA *hfd)
{
if (!hfd)
return;
if (hfd->Directory)
{
free(hfd->Directory);
hfd->Directory = NULL;
}
if (hfd->HPIFile)
fclose(hfd->HPIFile);
hfd->HPIFile = NULL;
}
void cHPIHandler::ProcessSubDir( HPIITEM *hi )
{
sint32 *FileCount, *FileLength, *EntryOffset, *Entries, count;
schar *Name;
HPIENTRY *Base, *Entry;
HPIITEM *li;
Base = hi->E1;
if (Base)
Entries = (sint32 *) (hi->hfd->Directory + Base->CountOffset);
else
Entries = (sint32 *) (hi->hfd->Directory + hi->hfd->H1.Start);
EntryOffset = Entries + 1;
Entry = (HPIENTRY *) (hi->hfd->Directory + *EntryOffset);
for (count = 0; count < *Entries; count++) {
Name = hi->hfd->Directory + Entry->NameOffset;
FileCount = (sint32 *) (hi->hfd->Directory + Entry->CountOffset);
FileLength = FileCount + 1;
li = (HPIITEM *)GetMem(sizeof(HPIITEM), 1);
li->hfd = hi->hfd;
li->Name = Name;
li->E1 = Entry;
if (Entry->Flag == 1)
{
std::string sDir = m_cDir; // save directory
m_cDir += (char *)Name; // add new path to directory.
m_cDir += "\\"; // don't forget to end path with /
ProcessSubDir( li ); // process new directory
free( li ); // free the item.
li = NULL; // really free the item.
m_cDir = sDir; // restore dir with saved dir
} else {
std::string f = Lowercase( m_cDir + (char *)Name );
HPIARCHIVE::iterator iterFind = m_Archive.find( f );
if( iterFind != m_Archive.end() )
{ // its in our map, free the memory, erase it, add new one.
HPIITEM *hi = iterFind->second;
iterFind->second = NULL;
m_Archive.erase( iterFind );
free( hi );
hi = NULL;
}
li->Size = *FileLength;
m_Archive[f] = li;
}
Entry++;
}
}
void cHPIHandler::ProcessRoot(HPIFILEDATA *hfd, const std::string &StartPath, sint32 offset )
{
sint32 *Entries, *FileCount, *EntryOffset;
schar *Name;
std::string MyPath;
Entries = (sint32 *)(hfd->Directory + offset);
EntryOffset = Entries + 1;
HPIENTRY *Entry = (HPIENTRY *)(hfd->Directory + *EntryOffset);
for( sint32 count = 0; count < *Entries; count++ )
{
Name = hfd->Directory + Entry->NameOffset;
FileCount = (sint32 *) (hfd->Directory + Entry->CountOffset);
if (Entry->Flag == 1)
{
MyPath = StartPath;
if( MyPath.length() )
MyPath += "\\";
MyPath += (char *)Name;
m_cDir = MyPath + "\\";
HPIITEM *hi = (HPIITEM *)GetMem(sizeof(HPIITEM), 1);
hi->hfd = hfd;
hi->IsDir = 1;
hi->Size = 0;
hi->Name = Name;
hi->E1 = Entry;
ProcessSubDir( hi );
free( hi );
hi = NULL;
}
Entry++;
}
}
void cHPIHandler::AddArchive( const std::string &FileName )
{
HPIFILEDATA *hfd = (HPIFILEDATA *)GetMem(sizeof(HPIFILEDATA), 1);
if (!hfd)
return; // No Need to generate error here as getmem already did it.
hfd->HPIFileName = FileName;
#if defined TA3D_PLATFORM_WINDOWS
errno_t err;
if( ( err = fopen_s( &hfd->HPIFile, hfd->HPIFileName.c_str(), "rb" )) != 0 )
#else
hfd->HPIFile=fopen( hfd->HPIFileName.c_str(), "rb" );
if( !hfd->HPIFile )
#endif
{
CloseHPIFile(hfd);
free(hfd);
// GlobalDebugger-> Failed to open hpi file for reading.
return;
}
HPIVERSION hv;
fread(&hv, sizeof(HPIVERSION), 1, hfd->HPIFile);
if( hv.Version != HPI_V1 || hv.HPIMarker != HEX_HAPI )
{
CloseHPIFile(hfd);
free(hfd);
hfd = NULL;
return;
}
fread(&hfd->H1, sizeof(HPIHEADER), 1, hfd->HPIFile);
if (hfd->H1.Key)
hfd->Key = ~((hfd->H1.Key * 4) | (hfd->H1.Key >> 6));
else
hfd->Key = 0;
int start = hfd->H1.Start;
int size = hfd->H1.DirectorySize;
hfd->Directory = (sint8 *)GetMem(size, 1);
ReadAndDecrypt(start, (byte *)hfd->Directory + start, size - start, hfd );
m_cDir = "";
m_HPIFiles.push_front( hfd );
ProcessRoot(hfd, "", start);
}
void cHPIHandler::LocateAndReadFiles( const std::string &Path, const std::string &FileSearch )
{
al_ffblk search;
if( al_findfirst(FileSearch.c_str(), &search, FA_RDONLY | FA_ARCH ) ==0 )
{
do
{
AddArchive( Path + search.name );
} while( al_findnext( &search ) == 0 );
al_findclose(&search);
}
}
void cHPIHandler::SearchDirForArchives( const std::string &Path )
{
schar ext[4][6] = { "*.ufo", "*.hpi", "*.ccx", "*.gp3" };
for( uint32 i = 0; i < 4; i++ )
LocateAndReadFiles( Path, Path + (char *)ext[i] );
}
cHPIHandler::~cHPIHandler()
{
// Cleanup:
// Walk the map, setting value to NULL, and freeing HPIITEMS.
for( HPIARCHIVE::iterator iter = m_Archive.begin(); iter != m_Archive.end(); ++iter )
{
HPIITEM *hi = iter->second;
iter->second = NULL;
free( hi );
hi = NULL;
}
m_Archive.clear(); // Now do a clear which will purge keys.
// Now close and free hpi files.
if( m_HPIFiles.size() == 0 )
return;
std::list< HPIFILEDATA * >::iterator cur;
HPIFILEDATA *hfd;
do
{
cur = m_HPIFiles.begin();
hfd = (*cur);
m_HPIFiles.pop_front();
CloseHPIFile( hfd );
free( hfd );
hfd = NULL;
} while( m_HPIFiles.size() != 0 );
}
#if defined( DEBUG ) // no need for bloating in release builds.
void cHPIHandler::ShowArchive()
{
for(HPIARCHIVE::iterator iter = m_Archive.begin(); iter != m_Archive.end(); iter++)
printf( "(arch)%s\n", (*iter).first.c_str() );
}
#endif
byte *cHPIHandler::PullFromHPI( const std::string &FileName )
{
HPIARCHIVE::const_iterator iterFind = m_Archive.find( Lowercase( FileName ) );
return ( (iterFind != m_Archive.end()) ?
DecodeFileToMem( (HPIITEM *)iterFind->second ) : NULL );
}
sint32 cHPIHandler::GetFilelist( const std::string &Search, std::list<std::string> *li )
{
std::string first, last;
std::basic_string <char>::size_type iFind;
static const std::basic_string <char>::size_type NotFound = -1;
iFind = Search.find( "*" );
if( iFind != NotFound )
{
first = Lowercase( Search.substr(0,(iFind)) );
last = Lowercase( Search.substr( iFind+1) );
}
else
{
first = Lowercase( Search );
last = "";
}
for( HPIARCHIVE::iterator iter = m_Archive.begin(); iter != m_Archive.end(); ++iter )
{
std::string f = iter->first;
if( f.length() < first.length() || f.length() < last.length() )
continue;
if( f.substr(0,first.length() ) == first )
{
if( f.substr( f.length() - last.length(), last.length() ) == last )
li->push_back( f );
}
}
return 0;
}
Who is online
Users browsing this forum: No registered users and 39 guests