CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Format/RIFF.cpp
Views: 1401
1
#include <cstring>
2
3
#include "Common/Log.h"
4
#include "Common/Data/Format/RIFF.h"
5
6
inline uint32_t flipID(uint32_t id) {
7
return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000);
8
}
9
10
RIFFReader::RIFFReader(const uint8_t *data, int dataSize) {
11
data_ = new uint8_t[dataSize];
12
memcpy(data_, data, dataSize);
13
depth_ = 0;
14
pos_ = 0;
15
eof_ = dataSize;
16
fileSize_ = dataSize;
17
}
18
19
RIFFReader::~RIFFReader() {
20
delete[] data_;
21
}
22
23
int RIFFReader::ReadInt() {
24
int value = 0;
25
if (data_ && pos_ < eof_ - 3) {
26
pos_ += 4;
27
memcpy(&value, data_ + pos_ - 4, 4);
28
}
29
return value;
30
}
31
32
bool RIFFReader::Descend(uint32_t intoId) {
33
if (depth_ > 30)
34
return false;
35
36
intoId = flipID(intoId);
37
bool found = false;
38
39
// save information to restore after the next Ascend
40
stack[depth_].parentStartLocation = pos_;
41
stack[depth_].parentEOF = eof_;
42
43
// let's search through children..
44
while (pos_ < eof_) {
45
int id = ReadInt();
46
int length = ReadInt();
47
int startLocation = pos_;
48
49
if (pos_ + length > fileSize_) {
50
ERROR_LOG(Log::IO, "Block extends outside of RIFF file - failing descend");
51
pos_ = stack[depth_].parentStartLocation;
52
return false;
53
}
54
55
if (id == intoId) {
56
stack[depth_].ID = intoId;
57
stack[depth_].length = length;
58
stack[depth_].startLocation = startLocation;
59
found = true;
60
break;
61
} else {
62
if (length > 0) {
63
pos_ += length; // try next block
64
} else {
65
ERROR_LOG(Log::IO, "Bad data in RIFF file : block length %d. Not descending.", length);
66
pos_ = stack[depth_].parentStartLocation;
67
return false;
68
}
69
}
70
}
71
72
// if we found nothing, return false so the caller can skip this
73
if (!found) {
74
pos_ = stack[depth_].parentStartLocation;
75
return false;
76
}
77
78
// descend into it
79
// pos was set inside the loop above
80
eof_ = stack[depth_].startLocation + stack[depth_].length;
81
depth_++;
82
return true;
83
}
84
85
void RIFFReader::Ascend() {
86
// ascend, and restore information
87
depth_--;
88
pos_ = stack[depth_].parentStartLocation;
89
eof_ = stack[depth_].parentEOF;
90
}
91
92
void RIFFReader::ReadData(void *what, int count) {
93
memcpy(what, data_ + pos_, count);
94
pos_ += count;
95
count &= 3;
96
if (count) {
97
count = 4 - count;
98
pos_ += count;
99
}
100
}
101
102
int RIFFReader::GetCurrentChunkSize() {
103
if (depth_)
104
return stack[depth_ - 1].length;
105
else
106
return 0;
107
}
108
109