-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathread.h
144 lines (120 loc) · 2.67 KB
/
read.h
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
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <vector>
#include <cstdint>
extern std::vector<unsigned char> InflatedFile;
extern int g_iBytesRead;
extern int g_iInflatedSize;
class EOFException : public std::runtime_error
{
public:
EOFException(int a) : std::runtime_error("End of file was reached"), Position(a) { }
int GetPosition() const {
return Position;
}
private:
int Position;
};
template <typename T>
void unaligned_copy(T& dest, const T& src)
{
#ifdef EMSCRIPTEN
for (int i = 0; i < sizeof(T); i++)
*(uint8_t*)(((uint8_t*)&dest) + i) = *(uint8_t*)(((uint8_t*)&src) + i);
#else
dest = src;
#endif
}
template <typename T>
T unaligned_read(T& arg)
{
#ifdef EMSCRIPTEN
T temp;
unaligned_copy(temp, arg);
return temp;
#else
return arg;
#endif
}
//#define BOUNDS_CHECK
template <typename T>
void peekat(T& buf, int pos)
{
#ifdef BOUNDS_CHECK
if (pos + sizeof(buf) > InflatedFile.size())
throw EOFException(pos);
#endif
void Print(const char*, ...);
if (pos + sizeof(buf) > InflatedFile.size())
Print("Exceeded bounds %d, %d\n", pos, sizeof(buf));
if (true)//(g_iBytesRead & 3) != 0))
{
unaligned_copy(buf, *(T*)&InflatedFile[pos]);
}
else
{
buf = *(T *)(InflatedFile.data() + pos);
}
}
template<typename T>
void peek(T &buf)
{
peekat(buf, g_iBytesRead);
}
template<typename T>
void read(T &buf)
{
peek(buf);
g_iBytesRead += sizeof(T);
}
template<typename T>
void read(T &buf, int pos)
{
peekat(buf, pos);
}
template<typename T, int _size>
void read(T(&buf)[_size])
{
for (int read = 0; read < _size; read++)
peekat(buf[read], g_iBytesRead + read * sizeof(T));
g_iBytesRead += sizeof(T) * _size;
}
template<typename T, int _size>
void read(T(&buf)[_size], int pos)
{
for (int read = 0; read < _size; read++)
peekat(buf[read], pos + read * sizeof(T));
}
template<typename T>
T &ref()
{
if (g_iBytesRead + sizeof(T) > InflatedFile.size())
throw EOFException(g_iBytesRead);
return *(T *)(InflatedFile.data() + g_iBytesRead);
}
template<typename T>
void write(const T &buf, int pos)
{
#ifdef BOUNDS_CHECK
if (g_iBytesRead + sizeof(buf) > InflatedFile.size())
throw EOFException(g_iBytesRead);
#endif
unaligned_copy(*(T*)&InflatedFile[pos], buf);
}
template<typename T, int _size>
void write(const T(&buf)[_size], int pos)
{
for (int read = 0; read < _size; read++)
write(buf[read], pos + read * sizeof(T));
}
template <typename T>
T& RefAt(int Pos)
{
return *(T*)(InflatedFile.data() + Pos);
}
void nullexpand(int pos, int size)
{
InflatedFile.resize(InflatedFile.size() + size);
memmove((void *)((uint32_t)InflatedFile.data() + pos + size), InflatedFile.data() + pos, g_iInflatedSize - pos);
memset(InflatedFile.data() + pos, 0, size);
g_iInflatedSize += size;
g_iBytesRead += size;
}