|
|
@@ -10,7 +10,6 @@
|
|
|
#include <boost/algorithm/string.hpp>
|
|
|
#include <boost/algorithm/string/replace.hpp>
|
|
|
#include <boost/thread.hpp>
|
|
|
-#include <boost/iostreams/device/mapped_file.hpp>
|
|
|
#ifdef max
|
|
|
#undef max
|
|
|
#endif
|
|
|
@@ -40,12 +39,6 @@ DLL_EXPORT int readNormalNr (int pos, int bytCon, unsigned char * str)
|
|
|
else return -1;
|
|
|
return ret;
|
|
|
}
|
|
|
-
|
|
|
-const unsigned char *CLodHandler::dataptr()
|
|
|
-{
|
|
|
- return (const unsigned char *)mmlod->data();
|
|
|
-}
|
|
|
-
|
|
|
unsigned char * CLodHandler::giveFile(std::string defName, int * length)
|
|
|
{
|
|
|
std::transform(defName.begin(), defName.end(), defName.begin(), (int(*)(int))toupper);
|
|
|
@@ -56,53 +49,43 @@ unsigned char * CLodHandler::giveFile(std::string defName, int * length)
|
|
|
return NULL;
|
|
|
}
|
|
|
if(length) *length = ourEntry->realSize;
|
|
|
-
|
|
|
- const unsigned char *data = dataptr();
|
|
|
- data += ourEntry->offset;
|
|
|
-
|
|
|
+ mutex->lock();
|
|
|
+ fseek(FLOD, ourEntry->offset, 0);
|
|
|
unsigned char * outp;
|
|
|
if (ourEntry->offset<0) //file is in the sprites/ folder; no compression
|
|
|
{
|
|
|
unsigned char * outp = new unsigned char[ourEntry->realSize];
|
|
|
- char name[30];
|
|
|
-
|
|
|
- memset(name,0, sizeof(name));
|
|
|
+ char name[30];memset(name,0,30);
|
|
|
strcat(name, myDir.c_str());
|
|
|
strcat(name, PATHSEPARATOR);
|
|
|
strcat(name,ourEntry->nameStr.c_str());
|
|
|
FILE * f = fopen(name,"rb");
|
|
|
int result = fread(outp,1,ourEntry->realSize,f);
|
|
|
-
|
|
|
- if (result<0) {
|
|
|
- tlog1<<"Error in file reading: " << name << std::endl;
|
|
|
- delete[] outp;
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ mutex->unlock();
|
|
|
+ if(result<0) {tlog1<<"Error in file reading: "<<name<<std::endl;delete[] outp; return NULL;}
|
|
|
else
|
|
|
return outp;
|
|
|
}
|
|
|
-
|
|
|
- else if (ourEntry->size==0)
|
|
|
+ else if (ourEntry->size==0) //file is not compressed
|
|
|
{
|
|
|
- //file is not compressed
|
|
|
- // TODO: we could try to avoid a copy here.
|
|
|
outp = new unsigned char[ourEntry->realSize];
|
|
|
- memcpy(outp, data, ourEntry->realSize);
|
|
|
+ fread((char*)outp, 1, ourEntry->realSize, FLOD);
|
|
|
+ mutex->unlock();
|
|
|
return outp;
|
|
|
}
|
|
|
- else
|
|
|
+ else //we will decompress file
|
|
|
{
|
|
|
- //we will decompress file
|
|
|
+ outp = new unsigned char[ourEntry->size];
|
|
|
+ fread((char*)outp, 1, ourEntry->size, FLOD);
|
|
|
+ mutex->unlock();
|
|
|
unsigned char * decomp = NULL;
|
|
|
- if (!infs2(data, ourEntry->size, ourEntry->realSize, decomp))
|
|
|
- {
|
|
|
- tlog2<<"an error occurred while extracting file "<<defName<<std::endl;
|
|
|
- }
|
|
|
+ int decRes = infs2(outp, ourEntry->size, ourEntry->realSize, decomp);
|
|
|
+ delete[] outp;
|
|
|
return decomp;
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
-int CLodHandler::infs(const unsigned char * in, int size, int realSize, std::ofstream & out, int wBits)
|
|
|
+int CLodHandler::infs(unsigned char * in, int size, int realSize, std::ofstream & out, int wBits)
|
|
|
{
|
|
|
int ret;
|
|
|
unsigned have;
|
|
|
@@ -178,12 +161,15 @@ int CLodHandler::infs(const unsigned char * in, int size, int realSize, std::ofs
|
|
|
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
|
|
}
|
|
|
|
|
|
-DLL_EXPORT bool CLodHandler::infs2(const unsigned char * in, int size, int realSize, unsigned char *& out)
|
|
|
+DLL_EXPORT int CLodHandler::infs2(unsigned char * in, int size, int realSize, unsigned char *& out, int wBits)
|
|
|
{
|
|
|
int ret;
|
|
|
+ unsigned have;
|
|
|
z_stream strm;
|
|
|
-
|
|
|
- out = NULL;
|
|
|
+ unsigned char inx[NLoadHandlerHelp::fCHUNK];
|
|
|
+ unsigned char outx[NLoadHandlerHelp::fCHUNK];
|
|
|
+ out = new unsigned char [realSize];
|
|
|
+ int latPosOut = 0;
|
|
|
|
|
|
/* allocate inflate state */
|
|
|
strm.zalloc = Z_NULL;
|
|
|
@@ -191,33 +177,54 @@ DLL_EXPORT bool CLodHandler::infs2(const unsigned char * in, int size, int realS
|
|
|
strm.opaque = Z_NULL;
|
|
|
strm.avail_in = 0;
|
|
|
strm.next_in = Z_NULL;
|
|
|
- ret = inflateInit(&strm);
|
|
|
+ ret = inflateInit2(&strm, wBits);
|
|
|
if (ret != Z_OK)
|
|
|
return ret;
|
|
|
-
|
|
|
- out = new unsigned char [realSize];
|
|
|
-
|
|
|
- strm.avail_in = size;
|
|
|
- strm.next_in = (Bytef *)in;
|
|
|
- strm.avail_out = realSize;
|
|
|
- strm.next_out = out;
|
|
|
- ret = inflate(&strm, Z_FINISH);
|
|
|
-
|
|
|
- if (ret != Z_STREAM_END)
|
|
|
+ int chunkNumber = 0;
|
|
|
+ do
|
|
|
{
|
|
|
- tlog2 << "Decompression of an object failed (" << (strm.msg ? strm.msg : "not ok") << ")" << std::endl;
|
|
|
- delete [] out;
|
|
|
- out = NULL;
|
|
|
- }
|
|
|
+ int readBytes = 0;
|
|
|
+ for(int i=0; i<NLoadHandlerHelp::fCHUNK && (chunkNumber * NLoadHandlerHelp::fCHUNK + i)<size; ++i)
|
|
|
+ {
|
|
|
+ inx[i] = in[chunkNumber * NLoadHandlerHelp::fCHUNK + i];
|
|
|
+ ++readBytes;
|
|
|
+ }
|
|
|
+ ++chunkNumber;
|
|
|
+ strm.avail_in = readBytes;
|
|
|
+ if (strm.avail_in == 0)
|
|
|
+ break;
|
|
|
+ strm.next_in = inx;
|
|
|
|
|
|
- if (ret == Z_OK || strm.avail_out != 0) {
|
|
|
- // An input parameter was bogus
|
|
|
- tlog2 << "Warning: unexpected decompressed size" << std::endl;
|
|
|
- }
|
|
|
+ /* run inflate() on input until output buffer not full */
|
|
|
+ do
|
|
|
+ {
|
|
|
+ strm.avail_out = NLoadHandlerHelp::fCHUNK;
|
|
|
+ strm.next_out = outx;
|
|
|
+ ret = inflate(&strm, Z_NO_FLUSH);
|
|
|
+ //assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
|
|
+ switch (ret)
|
|
|
+ {
|
|
|
+ case Z_NEED_DICT:
|
|
|
+ ret = Z_DATA_ERROR; /* and fall through */
|
|
|
+ case Z_DATA_ERROR:
|
|
|
+ case Z_MEM_ERROR:
|
|
|
+ (void)inflateEnd(&strm);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ have = NLoadHandlerHelp::fCHUNK - strm.avail_out;
|
|
|
+ for(int oo=0; oo<have; ++oo)
|
|
|
+ {
|
|
|
+ out[latPosOut] = outx[oo];
|
|
|
+ ++latPosOut;
|
|
|
+ }
|
|
|
+ } while (strm.avail_out == 0);
|
|
|
|
|
|
- inflateEnd(&strm);
|
|
|
+ /* done when inflate() says it's done */
|
|
|
+ } while (ret != Z_STREAM_END);
|
|
|
|
|
|
- return ret == Z_STREAM_END;
|
|
|
+ /* clean up and return */
|
|
|
+ (void)inflateEnd(&strm);
|
|
|
+ return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
|
|
}
|
|
|
|
|
|
void CLodHandler::extract(std::string FName)
|
|
|
@@ -225,16 +232,13 @@ void CLodHandler::extract(std::string FName)
|
|
|
std::ofstream FOut;
|
|
|
for (int i=0;i<totalFiles;i++)
|
|
|
{
|
|
|
- const unsigned char *data = dataptr();
|
|
|
- data += entries[i].offset;
|
|
|
-
|
|
|
- std::string bufff = (DATA_DIR + FName.substr(0, FName.size()-4) + PATHSEPARATOR + entries[i].nameStr);
|
|
|
+ fseek(FLOD, entries[i].offset, 0);
|
|
|
+ std::string bufff = (DATA_DIR + FName.substr(0, FName.size()-4) + PATHSEPARATOR + (char*)entries[i].name);
|
|
|
unsigned char * outp;
|
|
|
if (entries[i].size==0) //file is not compressed
|
|
|
{
|
|
|
- // TODO: this could be better written
|
|
|
outp = new unsigned char[entries[i].realSize];
|
|
|
- memcpy(outp, data, entries[i].realSize);
|
|
|
+ fread((char*)outp, 1, entries[i].realSize, FLOD);
|
|
|
std::ofstream out;
|
|
|
out.open(bufff.c_str(), std::ios::binary);
|
|
|
if(!out.is_open())
|
|
|
@@ -252,9 +256,9 @@ void CLodHandler::extract(std::string FName)
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // TODO: this could be better written
|
|
|
outp = new unsigned char[entries[i].size];
|
|
|
- memcpy(outp, data, entries[i].size);
|
|
|
+ fread((char*)outp, 1, entries[i].size, FLOD);
|
|
|
+ fseek(FLOD, 0, 0);
|
|
|
std::ofstream destin;
|
|
|
destin.open(bufff.c_str(), std::ios::binary);
|
|
|
//int decRes = decompress(outp, entries[i].size, entries[i].realSize, bufff);
|
|
|
@@ -267,6 +271,7 @@ void CLodHandler::extract(std::string FName)
|
|
|
}
|
|
|
delete[] outp;
|
|
|
}
|
|
|
+ fclose(FLOD);
|
|
|
}
|
|
|
|
|
|
void CLodHandler::extractFile(std::string FName, std::string name)
|
|
|
@@ -274,21 +279,17 @@ void CLodHandler::extractFile(std::string FName, std::string name)
|
|
|
std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))toupper);
|
|
|
for (int i=0;i<totalFiles;i++)
|
|
|
{
|
|
|
- std::string buf1 = entries[i].nameStr;
|
|
|
+ std::string buf1 = std::string((char*)entries[i].name);
|
|
|
std::transform(buf1.begin(), buf1.end(), buf1.begin(), (int(*)(int))toupper);
|
|
|
if(buf1!=name)
|
|
|
continue;
|
|
|
-
|
|
|
- const unsigned char *data = dataptr();
|
|
|
- data += entries[i].offset;
|
|
|
-
|
|
|
+ fseek(FLOD, entries[i].offset, 0);
|
|
|
std::string bufff = (FName);
|
|
|
unsigned char * outp;
|
|
|
if (entries[i].size==0) //file is not compressed
|
|
|
{
|
|
|
- // TODO: this could be better written
|
|
|
outp = new unsigned char[entries[i].realSize];
|
|
|
- memcpy(outp, data, entries[i].realSize);
|
|
|
+ fread((char*)outp, 1, entries[i].realSize, FLOD);
|
|
|
std::ofstream out;
|
|
|
out.open(bufff.c_str(), std::ios::binary);
|
|
|
if(!out.is_open())
|
|
|
@@ -306,9 +307,9 @@ void CLodHandler::extractFile(std::string FName, std::string name)
|
|
|
}
|
|
|
else //we will decompressing file
|
|
|
{
|
|
|
- // TODO: this could be better written
|
|
|
outp = new unsigned char[entries[i].size];
|
|
|
- memcpy(outp, data, entries[i].size);
|
|
|
+ fread((char*)outp, 1, entries[i].size, FLOD);
|
|
|
+ fseek(FLOD, 0, 0);
|
|
|
std::ofstream destin;
|
|
|
destin.open(bufff.c_str(), std::ios::binary);
|
|
|
//int decRes = decompress(outp, entries[i].size, entries[i].realSize, bufff);
|
|
|
@@ -323,7 +324,7 @@ void CLodHandler::extractFile(std::string FName, std::string name)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int CLodHandler::readNormalNr (const unsigned char* bufor, int bytCon, bool cyclic)
|
|
|
+int CLodHandler::readNormalNr (unsigned char* bufor, int bytCon, bool cyclic)
|
|
|
{
|
|
|
int ret=0;
|
|
|
int amp=1;
|
|
|
@@ -339,47 +340,56 @@ int CLodHandler::readNormalNr (const unsigned char* bufor, int bytCon, bool cycl
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-void CLodHandler::init(const std::string lodFile, const std::string dirName)
|
|
|
+void CLodHandler::init(std::string lodFile, std::string dirName)
|
|
|
{
|
|
|
myDir = dirName;
|
|
|
+ mutex = new boost::mutex;
|
|
|
std::string Ts;
|
|
|
-
|
|
|
- mmlod = new boost::iostreams::mapped_file_source(lodFile);
|
|
|
- if(!mmlod->is_open())
|
|
|
+ FLOD = fopen(lodFile.c_str(), "rb");
|
|
|
+ if(!FLOD)
|
|
|
{
|
|
|
- delete mmlod;
|
|
|
- mmlod = NULL;
|
|
|
tlog1 << "Cannot open " << lodFile << std::endl;
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- const unsigned char *data = dataptr();
|
|
|
-
|
|
|
- totalFiles = readNormalNr(&data[8], 4);
|
|
|
- data += 0x5c;
|
|
|
-
|
|
|
- for (unsigned int i=0; i<totalFiles; i++)
|
|
|
+ fseek(FLOD, 8, 0);
|
|
|
+ unsigned char temp[4];
|
|
|
+ fread((char*)temp, 1, 4, FLOD);
|
|
|
+ totalFiles = readNormalNr(temp,4);
|
|
|
+ fseek(FLOD, 0x5c, 0);
|
|
|
+ for (int i=0; i<totalFiles; i++)
|
|
|
{
|
|
|
Entry entry;
|
|
|
-
|
|
|
+ char * bufc = new char;
|
|
|
+ bool appending = true;
|
|
|
for(int kk=0; kk<12; ++kk)
|
|
|
- {
|
|
|
- if (data[kk] !=0 )
|
|
|
- entry.nameStr+=toupper(data[kk]);
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
- data += 16;
|
|
|
-
|
|
|
- entry.offset=readNormalNr(data, 4);
|
|
|
- data += 4;
|
|
|
-
|
|
|
- entry.realSize=readNormalNr(data, 4);
|
|
|
- data += 8;
|
|
|
-
|
|
|
- entry.size=readNormalNr(data, 4);
|
|
|
- data += 4;
|
|
|
-
|
|
|
+ {
|
|
|
+ //FLOD.read(bufc, 1);
|
|
|
+ fread(bufc, 1, 1, FLOD);
|
|
|
+ if(appending)
|
|
|
+ {
|
|
|
+ entry.name[kk] = toupper(*bufc);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ entry.name[kk] = 0;
|
|
|
+ appending = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ delete bufc;
|
|
|
+ fread((char*)entry.hlam_1, 1, 4, FLOD);
|
|
|
+ fread((char*)temp, 1, 4, FLOD);
|
|
|
+ entry.offset=readNormalNr(temp,4);
|
|
|
+ fread((char*)temp, 1, 4, FLOD);
|
|
|
+ entry.realSize=readNormalNr(temp,4);
|
|
|
+ fread((char*)entry.hlam_2, 1, 4, FLOD);
|
|
|
+ fread((char*)temp, 1, 4, FLOD);
|
|
|
+ entry.size=readNormalNr(temp,4);
|
|
|
+ for (int z=0;z<12;z++)
|
|
|
+ {
|
|
|
+ if (entry.name[z])
|
|
|
+ entry.nameStr+=entry.name[z];
|
|
|
+ else break;
|
|
|
+ }
|
|
|
entries.push_back(entry);
|
|
|
}
|
|
|
boost::filesystem::directory_iterator enddir;
|
|
|
@@ -418,7 +428,6 @@ std::string CLodHandler::getTextFile(std::string name)
|
|
|
{
|
|
|
int length=-1;
|
|
|
unsigned char* data = giveFile(name,&length);
|
|
|
-
|
|
|
std::string ret;
|
|
|
ret.reserve(length);
|
|
|
for(int i=0;i<length;i++)
|