Commit 4b89904e authored by Sam Lantinga's avatar Sam Lantinga

Added read-ahead support for Win32 file IO

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402450
parent 31d16a05
...@@ -62,10 +62,15 @@ typedef struct SDL_RWops { ...@@ -62,10 +62,15 @@ typedef struct SDL_RWops {
Uint32 type; Uint32 type;
union { union {
#ifdef __WIN32__ #if defined(__WIN32__) && !defined(__SYMBIAN32__)
struct { struct {
int append; int append;
void* h; void *h;
struct {
void *data;
int size;
int left;
} buffer;
} win32io; } win32io;
#endif #endif
#ifdef HAVE_STDIO_H #ifdef HAVE_STDIO_H
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
#define INVALID_SET_FILE_POINTER 0xFFFFFFFF #define INVALID_SET_FILE_POINTER 0xFFFFFFFF
#endif #endif
#define READAHEAD_BUFFER_SIZE 1024
static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, const char *mode) static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, const char *mode)
{ {
#ifndef _WIN32_WCE #ifndef _WIN32_WCE
...@@ -58,6 +60,14 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con ...@@ -58,6 +60,14 @@ static int SDLCALL win32_file_open(SDL_RWops *context, const char *filename, con
context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */
context->hidden.win32io.buffer.data = (char *)SDL_malloc(READAHEAD_BUFFER_SIZE);
if (!context->hidden.win32io.buffer.data) {
SDL_OutOfMemory();
return -1;
}
context->hidden.win32io.buffer.size = 0;
context->hidden.win32io.buffer.left = 0;
/* "r" = reading, file must exist */ /* "r" = reading, file must exist */
/* "w" = writing, truncate existing, file may not exist */ /* "w" = writing, truncate existing, file may not exist */
/* "r+"= reading or writing, file must exist */ /* "r+"= reading or writing, file must exist */
...@@ -118,6 +128,12 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) ...@@ -118,6 +128,12 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence)
return -1; return -1;
} }
/* FIXME: We may be able to satisfy the seek within buffered data */
if (whence == RW_SEEK_CUR && context->hidden.win32io.buffer.left) {
offset -= context->hidden.win32io.buffer.left;
}
context->hidden.win32io.buffer.left = 0;
switch (whence) { switch (whence) {
case RW_SEEK_SET: case RW_SEEK_SET:
win32whence = FILE_BEGIN; break; win32whence = FILE_BEGIN; break;
...@@ -140,21 +156,50 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence) ...@@ -140,21 +156,50 @@ static int SDLCALL win32_file_seek(SDL_RWops *context, int offset, int whence)
} }
static int SDLCALL win32_file_read(SDL_RWops *context, void *ptr, int size, int maxnum) static int SDLCALL win32_file_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{ {
int total_need;
int total_read = 0;
int read_ahead;
DWORD byte_read;
int total_bytes; total_need = size*maxnum;
DWORD byte_read,nread;
total_bytes = size*maxnum;
if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE || total_bytes<=0 || !size) if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE || total_need<=0 || !size)
return 0; return 0;
if (!ReadFile(context->hidden.win32io.h,ptr,total_bytes,&byte_read,NULL)) { if (context->hidden.win32io.buffer.left > 0) {
void *data = (char *)context->hidden.win32io.buffer.data +
context->hidden.win32io.buffer.size -
context->hidden.win32io.buffer.left;
read_ahead = SDL_min(total_need, context->hidden.win32io.buffer.left);
SDL_memcpy(ptr, data, read_ahead);
context->hidden.win32io.buffer.left -= read_ahead;
if (read_ahead == total_need) {
return maxnum;
}
ptr = (char *)ptr + read_ahead;
total_need -= read_ahead;
total_read += read_ahead;
}
if (total_need < READAHEAD_BUFFER_SIZE) {
if (!ReadFile(context->hidden.win32io.h,context->hidden.win32io.buffer.data,READAHEAD_BUFFER_SIZE,&byte_read,NULL)) {
SDL_Error(SDL_EFREAD);
return 0;
}
read_ahead = SDL_min(total_need, byte_read);
SDL_memcpy(ptr, context->hidden.win32io.buffer.data, read_ahead);
context->hidden.win32io.buffer.size = byte_read;
context->hidden.win32io.buffer.left = byte_read-read_ahead;
total_read += read_ahead;
} else {
if (!ReadFile(context->hidden.win32io.h,ptr,total_need,&byte_read,NULL)) {
SDL_Error(SDL_EFREAD); SDL_Error(SDL_EFREAD);
return 0; return 0;
} }
nread = byte_read/size; total_read += byte_read;
return nread; }
return (total_read/size);
} }
static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int size, int num) static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int size, int num)
{ {
...@@ -167,6 +212,11 @@ static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int siz ...@@ -167,6 +212,11 @@ static int SDLCALL win32_file_write(SDL_RWops *context, const void *ptr, int siz
if (!context || context->hidden.win32io.h==INVALID_HANDLE_VALUE || total_bytes<=0 || !size) if (!context || context->hidden.win32io.h==INVALID_HANDLE_VALUE || total_bytes<=0 || !size)
return 0; return 0;
if (context->hidden.win32io.buffer.left) {
SetFilePointer(context->hidden.win32io.h,-context->hidden.win32io.buffer.left,NULL,FILE_CURRENT);
context->hidden.win32io.buffer.left = 0;
}
/* if in append mode, we must go to the EOF before write */ /* if in append mode, we must go to the EOF before write */
if (context->hidden.win32io.append) { if (context->hidden.win32io.append) {
if ( SetFilePointer(context->hidden.win32io.h,0L,NULL,FILE_END) == INVALID_SET_FILE_POINTER ) { if ( SetFilePointer(context->hidden.win32io.h,0L,NULL,FILE_END) == INVALID_SET_FILE_POINTER ) {
...@@ -191,6 +241,10 @@ static int SDLCALL win32_file_close(SDL_RWops *context) ...@@ -191,6 +241,10 @@ static int SDLCALL win32_file_close(SDL_RWops *context)
CloseHandle(context->hidden.win32io.h); CloseHandle(context->hidden.win32io.h);
context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* to be sure */ context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* to be sure */
} }
if (context->hidden.win32io.buffer.data) {
SDL_free(context->hidden.win32io.buffer.data);
context->hidden.win32io.buffer.data = NULL;
}
SDL_FreeRW(context); SDL_FreeRW(context);
} }
return(0); return(0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment