1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mpq_libmpq04.h"
#include <cstdio>
#include <deque>
ArchiveSet gOpenArchives;
MPQArchive::MPQArchive(const char* filename)
{
int result = libmpq__archive_open(&mpq_a, filename, -1);
printf("Opening %s\n", filename);
if (result)
{
switch (result)
{
case LIBMPQ_ERROR_OPEN :
printf("Error opening archive '%s': Does file really exist?\n", filename);
break;
case LIBMPQ_ERROR_FORMAT : /* bad file format */
printf("Error opening archive '%s': Bad file format\n", filename);
break;
case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
printf("Error opening archive '%s': Seeking in file failed\n", filename);
break;
case LIBMPQ_ERROR_READ : /* Read error in archive */
printf("Error opening archive '%s': Read error in archive\n", filename);
break;
case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
printf("Error opening archive '%s': Maybe not enough memory\n", filename);
break;
default:
printf("Error opening archive '%s': Unknown error\n", filename);
break;
}
return;
}
gOpenArchives.push_front(this);
}
void MPQArchive::close()
{
//gOpenArchives.erase(erase(&mpq_a);
libmpq__archive_close(mpq_a);
}
MPQFile::MPQFile(const char* filename):
eof(false),
buffer(nullptr),
pointer(0),
size(0)
{
for (auto & gOpenArchive : gOpenArchives)
{
mpq_archive* mpq_a = gOpenArchive->mpq_a;
uint32_t filenum;
if (libmpq__file_number(mpq_a, filename, &filenum)) continue;
libmpq__off_t transferred;
libmpq__file_unpacked_size(mpq_a, filenum, &size);
// HACK: in patch.mpq some files don't want to open and give 1 for filesize
if (size <= 1)
{
// printf("warning: file %s has size %d; cannot read.\n", filename, size);
eof = true;
buffer = nullptr;
return;
}
buffer = new char[size];
//libmpq_file_getdata
libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
/*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
return;
}
eof = true;
buffer = nullptr;
}
std::size_t MPQFile::read(void* dest, std::size_t bytes)
{
if (eof) return 0;
std::size_t rpos = pointer + bytes;
if (rpos > std::size_t(size))
{
bytes = size - pointer;
eof = true;
}
memcpy(dest, &(buffer[pointer]), bytes);
pointer = rpos;
return bytes;
}
void MPQFile::seek(int offset)
{
pointer = offset;
eof = (pointer >= size);
}
void MPQFile::seekRelative(int offset)
{
pointer += offset;
eof = (pointer >= size);
}
void MPQFile::close()
{
delete[] buffer;
buffer = nullptr;
eof = true;
}
|