aboutsummaryrefslogtreecommitdiff
path: root/contrib/extractor/mpq_libmpq.h
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /contrib/extractor/mpq_libmpq.h
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'contrib/extractor/mpq_libmpq.h')
-rw-r--r--contrib/extractor/mpq_libmpq.h124
1 files changed, 124 insertions, 0 deletions
diff --git a/contrib/extractor/mpq_libmpq.h b/contrib/extractor/mpq_libmpq.h
new file mode 100644
index 00000000000..542e7b21d17
--- /dev/null
+++ b/contrib/extractor/mpq_libmpq.h
@@ -0,0 +1,124 @@
+#define _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_WARNINGS
+
+#ifndef MPQ_H
+#define MPQ_H
+
+#include "libmpq/mpq.h"
+#include <string.h>
+#include <ctype.h>
+#include <vector>
+#include <iostream>
+#include <deque>
+
+using namespace std;
+
+typedef unsigned int uint32;
+class MPQArchive
+{
+
+public:
+ mpq_archive mpq_a;
+
+ MPQArchive(const char* filename);
+ void close();
+
+ uint32 HashString(const char* Input, uint32 Offset) {
+ uint32 seed1 = 0x7fed7fed;
+ uint32 seed2 = 0xeeeeeeee;
+
+ for (uint32 i = 0; i < strlen(Input); i++) {
+ uint32 val = toupper(Input[i]);
+ seed1 = mpq_a.buf[Offset + val] ^ (seed1 + seed2);
+ seed2 = val + seed1 + seed2 + (seed2 << 5) + 3;
+ }
+
+ return seed1;
+ }
+ mpq_hash GetHashEntry(const char* Filename) {
+ uint32 index = HashString(Filename, 0);
+ index &= mpq_a.header->hashtablesize - 1;
+ uint32 name1 = HashString(Filename, 0x100);
+ uint32 name2 = HashString(Filename, 0x200);
+
+ for(uint32 i = index; i < mpq_a.header->hashtablesize; ++i) {
+ mpq_hash hash = mpq_a.hashtable[i];
+ if (hash.name1 == name1 && hash.name2 == name2) return hash;
+ }
+
+ mpq_hash nullhash;
+ nullhash.blockindex = 0xFFFFFFFF;
+ return nullhash;
+ }
+
+ vector<string> GetFileList() {
+ vector<string> filelist;
+
+ mpq_hash hash = GetHashEntry("(listfile)");
+ uint32 blockindex = hash.blockindex;
+
+ if ((blockindex == 0xFFFFFFFF) || (blockindex == 0))
+ return filelist;
+
+ uint32 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, blockindex);
+ char *buffer = new char[size];
+
+ libmpq_file_getdata(&mpq_a, hash, blockindex, (unsigned char*)buffer);
+
+ char seps[] = "\n";
+ char *token;
+
+ token = strtok( buffer, seps );
+ uint32 counter = 0;
+ while ((token != NULL) && (counter < size)) {
+ //cout << token << endl;
+ token[strlen(token) - 1] = 0;
+ string s = token;
+ filelist.push_back(s);
+ counter += strlen(token) + 2;
+ token = strtok(NULL, seps);
+ }
+
+ delete buffer;
+ return filelist;
+ }
+};
+typedef std::deque<MPQArchive*> ArchiveSet;
+
+class MPQFile
+{
+ //MPQHANDLE handle;
+ bool eof;
+ char *buffer;
+ size_t pointer,size;
+
+ // disable copying
+ MPQFile(const MPQFile &f) {}
+ void operator=(const MPQFile &f) {}
+
+public:
+ MPQFile(const char* filename); // filenames are not case sensitive
+ ~MPQFile() { close(); }
+ size_t read(void* dest, size_t bytes);
+ size_t getSize() { return size; }
+ size_t getPos() { return pointer; }
+ char* getBuffer() { return buffer; }
+ char* getPointer() { return buffer + pointer; }
+ bool isEof() { return eof; }
+ void seek(int offset);
+ void seekRelative(int offset);
+ void close();
+};
+
+inline void flipcc(char *fcc)
+{
+ char t;
+ t=fcc[0];
+ fcc[0]=fcc[3];
+ fcc[3]=t;
+ t=fcc[1];
+ fcc[1]=fcc[2];
+ fcc[2]=t;
+}
+
+#endif