mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 23:54:09 +02:00
file stream buffering (read)
This commit is contained in:
88
src/utils.h
88
src/utils.h
@@ -5,6 +5,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
|
//#define TEST_SLOW_FIO
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER)
|
#if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER)
|
||||||
#define debugBreak() raise(SIGTRAP);
|
#define debugBreak() raise(SIGTRAP);
|
||||||
@@ -1281,6 +1283,8 @@ char cacheDir[255];
|
|||||||
char saveDir[255];
|
char saveDir[255];
|
||||||
char contentDir[255];
|
char contentDir[255];
|
||||||
|
|
||||||
|
#define STREAM_BUFFER_SIZE (8 * 1024)
|
||||||
|
|
||||||
struct Stream {
|
struct Stream {
|
||||||
typedef void (Callback)(Stream *stream, void *userData);
|
typedef void (Callback)(Stream *stream, void *userData);
|
||||||
Callback *callback;
|
Callback *callback;
|
||||||
@@ -1289,16 +1293,19 @@ struct Stream {
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
char *data;
|
char *data;
|
||||||
char *name;
|
char *name;
|
||||||
int size, pos;
|
int size, pos, fpos;
|
||||||
|
|
||||||
Stream(const char *name, const void *data, int size, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data((char*)data), name(NULL), size(size), pos(0) {
|
char *buffer;
|
||||||
|
int bufferIndex;
|
||||||
|
|
||||||
|
Stream(const char *name, const void *data, int size, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data((char*)data), name(NULL), size(size), pos(0), buffer(NULL) {
|
||||||
if (name) {
|
if (name) {
|
||||||
this->name = new char[strlen(name) + 1];
|
this->name = new char[strlen(name) + 1];
|
||||||
strcpy(this->name, name);
|
strcpy(this->name, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream(const char *name, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data(NULL), name(NULL), size(-1), pos(0) {
|
Stream(const char *name, Callback *callback = NULL, void *userData = NULL) : callback(callback), userData(userData), f(NULL), data(NULL), name(NULL), size(-1), pos(0), buffer(NULL) {
|
||||||
if (!name && callback) {
|
if (!name && callback) {
|
||||||
callback(NULL, userData);
|
callback(NULL, userData);
|
||||||
delete this;
|
delete this;
|
||||||
@@ -1336,8 +1343,11 @@ struct Stream {
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
size = (int32)ftell(f);
|
fpos = (int32)ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
size = fpos;
|
||||||
|
|
||||||
|
buffer = new char[STREAM_BUFFER_SIZE];
|
||||||
|
bufferIndex = -1;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
this->name = new char[strlen(name) + 1];
|
this->name = new char[strlen(name) + 1];
|
||||||
@@ -1351,6 +1361,7 @@ struct Stream {
|
|||||||
|
|
||||||
~Stream() {
|
~Stream() {
|
||||||
delete[] name;
|
delete[] name;
|
||||||
|
delete[] buffer;
|
||||||
if (f) fclose(f);
|
if (f) fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1364,10 +1375,8 @@ struct Stream {
|
|||||||
|
|
||||||
static bool exists(const char *name) {
|
static bool exists(const char *name) {
|
||||||
FILE *f = fopen(name, "rb");
|
FILE *f = fopen(name, "rb");
|
||||||
if (!f)
|
if (!f) return false;
|
||||||
return false;
|
fclose(f);
|
||||||
else
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1379,37 +1388,60 @@ struct Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setPos(int pos) {
|
void setPos(int pos) {
|
||||||
if (this->pos != pos) {
|
this->pos = pos;
|
||||||
this->pos = pos;
|
|
||||||
if (f) fseek(f, pos, SEEK_SET);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void seek(int offset) {
|
void seek(int offset) {
|
||||||
if (!offset) return;
|
|
||||||
if (f) fseek(f, offset, SEEK_CUR);
|
|
||||||
pos += offset;
|
pos += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int raw(void *data, int count) {
|
void raw(void *data, int count) {
|
||||||
if (!count) return 0;
|
if (!count) return;
|
||||||
if (f)
|
|
||||||
count = (int)fread(data, 1, count, f);
|
if (f) {
|
||||||
else
|
uint8 *ptr = (uint8*)data;
|
||||||
|
while (count > 0) {
|
||||||
|
int bIndex = pos / STREAM_BUFFER_SIZE;
|
||||||
|
int bPos = pos % STREAM_BUFFER_SIZE;
|
||||||
|
int delta = min(STREAM_BUFFER_SIZE - bPos, count);
|
||||||
|
|
||||||
|
if (bufferIndex != bIndex) {
|
||||||
|
bufferIndex = bIndex;
|
||||||
|
|
||||||
|
if (fpos != bufferIndex * STREAM_BUFFER_SIZE) {
|
||||||
|
fpos = bufferIndex * STREAM_BUFFER_SIZE;
|
||||||
|
fseek(f, fpos, SEEK_SET);
|
||||||
|
|
||||||
|
#ifdef TEST_SLOW_FIO
|
||||||
|
LOG("seek %d\n", bufferIndex * STREAM_BUFFER_SIZE);
|
||||||
|
Sleep(5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int readed = fread(buffer, 1, min(STREAM_BUFFER_SIZE, size - bufferIndex * STREAM_BUFFER_SIZE), f);
|
||||||
|
ASSERT(readed > 0);
|
||||||
|
fpos += readed;
|
||||||
|
|
||||||
|
#ifdef TEST_SLOW_FIO
|
||||||
|
LOG("read %d + %d\n", bufferIndex * STREAM_BUFFER_SIZE, readed);
|
||||||
|
Sleep(5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ptr, buffer + bPos, delta);
|
||||||
|
count -= delta;
|
||||||
|
pos += delta;
|
||||||
|
ptr += delta;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
memcpy(data, this->data + pos, count);
|
memcpy(data, this->data + pos, count);
|
||||||
pos += count;
|
pos += count;
|
||||||
return count;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T& read(T &x) {
|
inline T& read(T &x) {
|
||||||
raw(&x, sizeof(x));
|
raw(&x, sizeof(x));
|
||||||
/*
|
|
||||||
if (endian == eBig) {
|
|
||||||
if (sizeof(T) == 2) x = T(swap16(x));
|
|
||||||
if (sizeof(T) == 4) x = T(swap32(x));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user