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
|
#include "memory_file.h"
#include "internal.h"
#include "utility.h"
namespace audiere {
ADR_EXPORT(File*) AdrCreateMemoryFile(const void* buffer, int size) {
if (size && !buffer) {
return 0;
}
if (size < 0) {
return 0;
}
return new MemoryFile(buffer, size);
}
int getNextPowerOfTwo(int value) {
int i = 1;
while (i < value) {
i *= 2;
}
return i;
}
MemoryFile::MemoryFile(const void* buffer, int size) {
m_capacity = getNextPowerOfTwo(size);
m_size = size;
m_buffer = new u8[m_capacity];
memcpy(m_buffer, buffer, size);
m_position = 0;
}
MemoryFile::~MemoryFile() {
delete[] m_buffer;
}
int ADR_CALL MemoryFile::read(void* buffer, int size) {
int real_read = std::min((m_size - m_position), size);
memcpy(buffer, m_buffer + m_position, real_read);
m_position += real_read;
return real_read;
}
int ADR_CALL MemoryFile::write(const void* buffer, int size) {
ensureSize(m_position + size);
memcpy(m_buffer + m_position, buffer, size);
m_position += size;
return size;
}
bool ADR_CALL MemoryFile::seek(int position, SeekMode mode) {
int real_pos;
switch (mode) {
case BEGIN: real_pos = position; break;
case CURRENT: real_pos = m_position + position; break;
case END: real_pos = m_size + position; break;
default: return false;
}
if (real_pos < 0 || real_pos > m_size) {
m_position = 0;
return false;
} else {
m_position = real_pos;
return true;
}
}
int ADR_CALL MemoryFile::tell() {
return m_position;
}
void MemoryFile::ensureSize(int min_size) {
bool realloc_needed = false;
while (m_capacity < min_size) {
m_capacity *= 2;
realloc_needed = true;
}
if (realloc_needed) {
u8* new_buffer = new u8[m_capacity];
memcpy(new_buffer, m_buffer, m_size);
delete[] m_buffer;
m_buffer = new_buffer;
}
m_size = min_size;
}
};
|