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;
|
||||
void *h;
|
||||
struct
|
||||
{
|
||||
void *data;
|
||||
int size;
|
||||
int left;
|
||||
} buffer;
|
||||
} win32io;
|
||||
#endif
|
||||
#ifdef HAVE_STDIO_H
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "SDL_rwops.h"
|
||||
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#ifdef __WIN32__
|
||||
|
||||
/* Functions to read/write Win32 API file pointers */
|
||||
/* Will not use it on WinCE because stdio is buffered, it means
|
||||
|
@ -43,6 +43,8 @@
|
|||
#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define READAHEAD_BUFFER_SIZE 1024
|
||||
|
||||
static int SDLCALL
|
||||
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.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 */
|
||||
/* "w" = writing, truncate existing, file may not exist */
|
||||
/* "r+"= reading or writing, file must exist */
|
||||
|
@ -128,6 +139,12 @@ win32_file_seek(SDL_RWops * context, int offset, int whence)
|
|||
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) {
|
||||
case RW_SEEK_SET:
|
||||
win32whence = FILE_BEGIN;
|
||||
|
@ -155,23 +172,54 @@ 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)
|
||||
{
|
||||
int total_need;
|
||||
int total_read = 0;
|
||||
int read_ahead;
|
||||
DWORD byte_read;
|
||||
|
||||
int total_bytes;
|
||||
DWORD byte_read, nread;
|
||||
|
||||
total_bytes = size * maxnum;
|
||||
total_need = size * maxnum;
|
||||
|
||||
if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE
|
||||
|| total_bytes <= 0 || !size)
|
||||
|| total_need <= 0 || !size)
|
||||
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
|
||||
(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);
|
||||
return 0;
|
||||
}
|
||||
nread = byte_read / size;
|
||||
return nread;
|
||||
read_ahead = SDL_min(total_need, (int) 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);
|
||||
return 0;
|
||||
}
|
||||
total_read += byte_read;
|
||||
}
|
||||
return (total_read / size);
|
||||
}
|
||||
static int SDLCALL
|
||||
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)
|
||||
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 (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) {
|
||||
SDL_Error(SDL_EFWRITE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -213,6 +268,10 @@ win32_file_close(SDL_RWops * context)
|
|||
CloseHandle(context->hidden.win32io.h);
|
||||
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);
|
||||
}
|
||||
return (0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue