[8587] MaNGOS 0.14 release.
[getmangos.git] / contrib / extractor / mpq_libmpq.cpp
blob41253b242b32772a7f6c403d74abd2f65a07451d
1 #include "mpq_libmpq.h"
2 #include <deque>
4 ArchiveSet gOpenArchives;
6 MPQArchive::MPQArchive(const char* filename)
8 int result = libmpq_archive_open(&mpq_a, (unsigned char*)filename);
9 printf("Opening %s\n", filename);
10 if(result) {
11 switch(result) {
12 case LIBMPQ_EFILE : /* error on file operation */
13 printf("Error opening archive '%s': File operation Error\n", filename);
14 break;
15 case LIBMPQ_EFILE_FORMAT : /* bad file format */
16 printf("Error opening archive '%s': Bad file format\n", filename);
17 break;
18 case LIBMPQ_EFILE_CORRUPT : /* file corrupt */
19 printf("Error opening archive '%s': File corrupt\n", filename);
20 break;
21 case LIBMPQ_EFILE_NOT_FOUND : /* file in archive not found */
22 printf("Error opening archive '%s': File in archive not found\n", filename);
23 break;
24 case LIBMPQ_EFILE_READ : /* Read error in archive */
25 printf("Error opening archive '%s': Read error in archive\n", filename);
26 break;
27 case LIBMPQ_EALLOCMEM : /* maybe not enough memory? :) */
28 printf("Error opening archive '%s': Maybe not enough memory\n", filename);
29 break;
30 case LIBMPQ_EFREEMEM : /* can not free memory */
31 printf("Error opening archive '%s': Cannot free memory\n", filename);
32 break;
33 case LIBMPQ_EINV_RANGE : /* Given filenumber is out of range */
34 printf("Error opening archive '%s': Given filenumber is out of range\n", filename);
35 break;
36 case LIBMPQ_EHASHTABLE : /* error in reading hashtable */
37 printf("Error opening archive '%s': Error in reading hashtable\n", filename);
38 break;
39 case LIBMPQ_EBLOCKTABLE : /* error in reading blocktable */
40 printf("Error opening archive '%s': Error in reading blocktable\n", filename);
41 break;
42 default:
43 printf("Error opening archive '%s': Unknown error\n", filename);
44 break;
46 return;
48 gOpenArchives.push_front(this);
51 void MPQArchive::close()
53 //gOpenArchives.erase(erase(&mpq_a);
54 libmpq_archive_close(&mpq_a);
57 MPQFile::MPQFile(const char* filename):
58 eof(false),
59 buffer(0),
60 pointer(0),
61 size(0)
63 for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
65 mpq_archive &mpq_a = (*i)->mpq_a;
67 mpq_hash hash = (*i)->GetHashEntry(filename);
68 uint32 blockindex = hash.blockindex;
70 if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) {
71 continue; //file not found
74 uint32 fileno = blockindex;
76 //int fileno = libmpq_file_number(&mpq_a, filename);
77 //if(fileno == LIBMPQ_EFILE_NOT_FOUND)
78 // continue;
80 // Found!
81 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno);
82 // HACK: in patch.mpq some files don't want to open and give 1 for filesize
83 if (size<=1) {
84 eof = true;
85 buffer = 0;
86 return;
88 buffer = new char[size];
90 //libmpq_file_getdata
91 libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);
92 return;
95 eof = true;
96 buffer = 0;
99 size_t MPQFile::read(void* dest, size_t bytes)
101 if (eof) return 0;
103 size_t rpos = pointer + bytes;
104 if (rpos > size) {
105 bytes = size - pointer;
106 eof = true;
109 memcpy(dest, &(buffer[pointer]), bytes);
111 pointer = rpos;
113 return bytes;
116 void MPQFile::seek(int offset)
118 pointer = offset;
119 eof = (pointer >= size);
122 void MPQFile::seekRelative(int offset)
124 pointer += offset;
125 eof = (pointer >= size);
128 void MPQFile::close()
130 if (buffer) delete[] buffer;
131 buffer = 0;
132 eof = true;