Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Merged read-ahead support for Win32 file I/O from SDL 1.2 revision 3183
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Jul 10, 2007
1 parent efad537 commit db3b805
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 14 deletions.
6 changes: 6 additions & 0 deletions include/SDL_rwops.h
Expand Up @@ -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
Expand Down
87 changes: 73 additions & 14 deletions src/file/SDL_rwops.c
Expand Up @@ -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
Expand All @@ -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)
{
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 (!ReadFile
(context->hidden.win32io.h, ptr, total_bytes, &byte_read, NULL)) {
SDL_Error(SDL_EFREAD);
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, context->hidden.win32io.buffer.data,
READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
SDL_Error(SDL_EFREAD);
return 0;
}
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;
}
nread = byte_read / size;
return nread;
return (total_read / size);
}
static int SDLCALL
win32_file_write(SDL_RWops * context, const void *ptr, int size, int num)
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down

0 comments on commit db3b805

Please sign in to comment.