Merged read-ahead support for Win32 file I/O from SDL 1.2 revision 3183
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402456
This commit is contained in:
parent
f7d87960f4
commit
8daaa10d40
2 changed files with 79 additions and 14 deletions
|
@ -76,6 +76,12 @@ typedef struct SDL_RWops
|
||||||
{
|
{
|
||||||
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
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "SDL_rwops.h"
|
#include "SDL_rwops.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#ifdef __WIN32__
|
||||||
|
|
||||||
/* Functions to read/write Win32 API file pointers */
|
/* Functions to read/write Win32 API file pointers */
|
||||||
/* Will not use it on WinCE because stdio is buffered, it means
|
/* Will not use it on WinCE because stdio is buffered, it means
|
||||||
|
@ -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
|
static int SDLCALL
|
||||||
win32_file_open(SDL_RWops * context, const char *filename, const char *mode)
|
win32_file_open(SDL_RWops * context, const char *filename, const char *mode)
|
||||||
{
|
{
|
||||||
|
@ -59,6 +61,15 @@ win32_file_open(SDL_RWops * context, const char *filename, const char *mode)
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -128,6 +139,12 @@ 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;
|
win32whence = FILE_BEGIN;
|
||||||
|
@ -155,23 +172,54 @@ win32_file_seek(SDL_RWops * context, int offset, int whence)
|
||||||
static int SDLCALL
|
static int SDLCALL
|
||||||
win32_file_read(SDL_RWops * context, void *ptr, int size, int maxnum)
|
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
|
if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE
|
||||||
|| total_bytes <= 0 || !size)
|
|| total_need <= 0 || !size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
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
|
if (!ReadFile
|
||||||
(context->hidden.win32io.h, ptr, total_bytes, &byte_read, NULL)) {
|
(context->hidden.win32io.h, context->hidden.win32io.buffer.data,
|
||||||
|
READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
|
||||||
SDL_Error(SDL_EFREAD);
|
SDL_Error(SDL_EFREAD);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
nread = byte_read / size;
|
read_ahead = SDL_min(total_need, (int) byte_read);
|
||||||
return nread;
|
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);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
total_read += byte_read;
|
||||||
|
}
|
||||||
|
return (total_read / size);
|
||||||
}
|
}
|
||||||
static int SDLCALL
|
static int SDLCALL
|
||||||
win32_file_write(SDL_RWops * context, const void *ptr, int size, int num)
|
win32_file_write(SDL_RWops * context, const void *ptr, int size, int num)
|
||||||
|
@ -186,10 +234,17 @@ win32_file_write(SDL_RWops * context, const void *ptr, int size, int num)
|
||||||
|| total_bytes <= 0 || !size)
|
|| 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)
|
if (SetFilePointer(context->hidden.win32io.h, 0L, NULL, FILE_END) ==
|
||||||
== INVALID_SET_FILE_POINTER) {
|
INVALID_SET_FILE_POINTER) {
|
||||||
SDL_Error(SDL_EFWRITE);
|
SDL_Error(SDL_EFWRITE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -213,6 +268,10 @@ 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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue