src/file/SDL_rwops.c
author Bob Pendleton <bob@pendleton.com>
Thu, 12 Jul 2007 20:00:50 +0000
changeset 2185 2032348afed1
parent 2179 8b76cc268771
child 2674 f1d07ba2e275
child 2735 204be4fc2726
permissions -rw-r--r--
This code adds support for DirectColor visuals to SDL 1.3. The support uses part of the Xmu library. To ensure that the library is
available and to keep people form having to install yet another library I have added the essential parts of Xmu in
src/video/extensions/XmuStdCmap and an include file in src/video/extensions. The support makes use of standard X11 mechanisms to
create color maps and make sure that an application uses the same color map for each window/visual combination. This should make it
possible for gamma support to be implemented based on a single color map per application.

Hurm... it looks like "make indent" modified a few extra files. Those are getting committed too.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* This file provides a general interface for SDL to read and write
slouken@0
    25
   data sources.  It can easily be extended to files, memory, etc.
slouken@0
    26
*/
slouken@0
    27
slouken@1354
    28
#include "SDL_endian.h"
slouken@0
    29
#include "SDL_rwops.h"
slouken@1330
    30
slouken@1354
    31
slouken@2159
    32
#ifdef __WIN32__
slouken@0
    33
slouken@1447
    34
/* Functions to read/write Win32 API file pointers */
slouken@1465
    35
/* Will not use it on WinCE because stdio is buffered, it means
slouken@1465
    36
   faster, and all stdio functions anyway are embedded in coredll.dll - 
slouken@1465
    37
   the main wince dll*/
slouken@0
    38
slouken@1446
    39
#define WINDOWS_LEAN_AND_MEAN
slouken@1446
    40
#include <windows.h>
slouken@1446
    41
slouken@1465
    42
#ifndef INVALID_SET_FILE_POINTER
slouken@1465
    43
#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
slouken@1465
    44
#endif
slouken@1465
    45
slouken@2159
    46
#define READAHEAD_BUFFER_SIZE	1024
slouken@2159
    47
slouken@1895
    48
static int SDLCALL
slouken@1895
    49
win32_file_open(SDL_RWops * context, const char *filename, const char *mode)
slouken@1465
    50
{
slouken@1465
    51
#ifndef _WIN32_WCE
slouken@1895
    52
    UINT old_error_mode;
slouken@1465
    53
#endif
slouken@1895
    54
    HANDLE h;
slouken@1895
    55
    DWORD r_right, w_right;
slouken@1895
    56
    DWORD must_exist, truncate;
slouken@1895
    57
    int a_mode;
slouken@1446
    58
slouken@1895
    59
    if (!context)
slouken@2164
    60
        return -1;              /* failed (invalid call) */
slouken@2159
    61
slouken@2173
    62
    context->hidden.win32io.h = INVALID_HANDLE_VALUE;   /* mark this as unusable */
icculus@2165
    63
    context->hidden.win32io.buffer.data = NULL;
icculus@2165
    64
    context->hidden.win32io.buffer.size = 0;
icculus@2165
    65
    context->hidden.win32io.buffer.left = 0;
icculus@2165
    66
slouken@1895
    67
    /* "r" = reading, file must exist */
slouken@1895
    68
    /* "w" = writing, truncate existing, file may not exist */
slouken@1895
    69
    /* "r+"= reading or writing, file must exist            */
slouken@1895
    70
    /* "a" = writing, append file may not exist             */
slouken@1895
    71
    /* "a+"= append + read, file may not exist              */
slouken@1895
    72
    /* "w+" = read, write, truncate. file may not exist    */
slouken@1895
    73
slouken@1895
    74
    must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0;
slouken@1895
    75
    truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0;
slouken@1895
    76
    r_right = (SDL_strchr(mode, '+') != NULL
slouken@1895
    77
               || must_exist) ? GENERIC_READ : 0;
slouken@1895
    78
    a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0;
slouken@1895
    79
    w_right = (a_mode || SDL_strchr(mode, '+')
slouken@1895
    80
               || truncate) ? GENERIC_WRITE : 0;
slouken@1895
    81
slouken@1895
    82
    if (!r_right && !w_right)   /* inconsistent mode */
slouken@1895
    83
        return -1;              /* failed (invalid call) */
slouken@1465
    84
slouken@2173
    85
    context->hidden.win32io.buffer.data =
slouken@2173
    86
        (char *) SDL_malloc(READAHEAD_BUFFER_SIZE);
icculus@2165
    87
    if (!context->hidden.win32io.buffer.data) {
icculus@2165
    88
        SDL_OutOfMemory();
icculus@2165
    89
        return -1;
icculus@2165
    90
    }
slouken@1465
    91
#ifdef _WIN32_WCE
slouken@1895
    92
    {
slouken@1895
    93
        size_t size = SDL_strlen(filename) + 1;
slouken@1895
    94
        wchar_t *filenameW = SDL_stack_alloc(wchar_t, size);
slouken@1465
    95
slouken@1895
    96
        if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) ==
slouken@1895
    97
            0) {
icculus@2165
    98
            SDL_stack_free(filenameW);
icculus@2165
    99
            SDL_free(context->hidden.win32io.buffer.data);
icculus@2165
   100
            context->hidden.win32io.buffer.data = NULL;
slouken@1895
   101
            SDL_SetError("Unable to convert filename to Unicode");
slouken@1895
   102
            return -1;
slouken@1895
   103
        }
slouken@1895
   104
        h = CreateFile(filenameW, (w_right | r_right),
slouken@1895
   105
                       (w_right) ? 0 : FILE_SHARE_READ, NULL,
slouken@1895
   106
                       (must_exist | truncate | a_mode),
slouken@1895
   107
                       FILE_ATTRIBUTE_NORMAL, NULL);
slouken@1895
   108
        SDL_stack_free(filenameW);
slouken@1895
   109
    }
slouken@1465
   110
#else
slouken@1895
   111
    /* Do not open a dialog box if failure */
slouken@1895
   112
    old_error_mode =
slouken@1895
   113
        SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
slouken@1465
   114
slouken@1895
   115
    h = CreateFile(filename, (w_right | r_right),
slouken@1895
   116
                   (w_right) ? 0 : FILE_SHARE_READ, NULL,
slouken@1895
   117
                   (must_exist | truncate | a_mode), FILE_ATTRIBUTE_NORMAL,
slouken@1895
   118
                   NULL);
slouken@1465
   119
slouken@1895
   120
    /* restore old behaviour */
slouken@1895
   121
    SetErrorMode(old_error_mode);
slouken@1465
   122
#endif /* _WIN32_WCE */
slouken@1446
   123
slouken@1895
   124
    if (h == INVALID_HANDLE_VALUE) {
icculus@2165
   125
        SDL_free(context->hidden.win32io.buffer.data);
icculus@2165
   126
        context->hidden.win32io.buffer.data = NULL;
slouken@1895
   127
        SDL_SetError("Couldn't open %s", filename);
slouken@1895
   128
        return -2;              /* failed (CreateFile) */
slouken@1895
   129
    }
slouken@1895
   130
    context->hidden.win32io.h = h;
slouken@2161
   131
    context->hidden.win32io.append = a_mode ? SDL_TRUE : SDL_FALSE;
slouken@1895
   132
slouken@1895
   133
    return 0;                   /* ok */
slouken@1446
   134
}
slouken@2160
   135
static long SDLCALL
slouken@2160
   136
win32_file_seek(SDL_RWops * context, long offset, int whence)
slouken@1465
   137
{
slouken@1895
   138
    DWORD win32whence;
slouken@2160
   139
    long file_pos;
slouken@1446
   140
slouken@1895
   141
    if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE) {
slouken@1895
   142
        SDL_SetError("win32_file_seek: invalid context/file not opened");
slouken@1895
   143
        return -1;
slouken@1895
   144
    }
slouken@1895
   145
slouken@2159
   146
    /* FIXME: We may be able to satisfy the seek within buffered data */
slouken@2159
   147
    if (whence == RW_SEEK_CUR && context->hidden.win32io.buffer.left) {
slouken@2159
   148
        offset -= context->hidden.win32io.buffer.left;
slouken@2159
   149
    }
slouken@2159
   150
    context->hidden.win32io.buffer.left = 0;
slouken@2159
   151
slouken@1895
   152
    switch (whence) {
slouken@1895
   153
    case RW_SEEK_SET:
slouken@1895
   154
        win32whence = FILE_BEGIN;
slouken@1895
   155
        break;
slouken@1895
   156
    case RW_SEEK_CUR:
slouken@1895
   157
        win32whence = FILE_CURRENT;
slouken@1895
   158
        break;
slouken@1895
   159
    case RW_SEEK_END:
slouken@1895
   160
        win32whence = FILE_END;
slouken@1895
   161
        break;
slouken@1895
   162
    default:
slouken@1895
   163
        SDL_SetError("win32_file_seek: Unknown value for 'whence'");
slouken@1895
   164
        return -1;
slouken@1895
   165
    }
slouken@1895
   166
slouken@1895
   167
    file_pos =
slouken@1895
   168
        SetFilePointer(context->hidden.win32io.h, offset, NULL, win32whence);
slouken@1895
   169
slouken@1895
   170
    if (file_pos != INVALID_SET_FILE_POINTER)
slouken@1895
   171
        return file_pos;        /* success */
slouken@1895
   172
slouken@1895
   173
    SDL_Error(SDL_EFSEEK);
slouken@1895
   174
    return -1;                  /* error */
slouken@1446
   175
}
slouken@2160
   176
static size_t SDLCALL
slouken@2160
   177
win32_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
slouken@1465
   178
{
slouken@2160
   179
    size_t total_need;
slouken@2160
   180
    size_t total_read = 0;
slouken@2160
   181
    size_t read_ahead;
slouken@2159
   182
    DWORD byte_read;
slouken@1895
   183
slouken@2159
   184
    total_need = size * maxnum;
slouken@1895
   185
slouken@1895
   186
    if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE
slouken@2160
   187
        || !total_need)
slouken@1895
   188
        return 0;
slouken@1895
   189
slouken@2159
   190
    if (context->hidden.win32io.buffer.left > 0) {
slouken@2159
   191
        void *data = (char *) context->hidden.win32io.buffer.data +
slouken@2159
   192
            context->hidden.win32io.buffer.size -
slouken@2159
   193
            context->hidden.win32io.buffer.left;
bob@2185
   194
        read_ahead =
bob@2185
   195
            SDL_min(total_need, (size_t) context->hidden.win32io.buffer.left);
slouken@2159
   196
        SDL_memcpy(ptr, data, read_ahead);
slouken@2159
   197
        context->hidden.win32io.buffer.left -= read_ahead;
slouken@2159
   198
slouken@2159
   199
        if (read_ahead == total_need) {
slouken@2159
   200
            return maxnum;
slouken@2159
   201
        }
slouken@2159
   202
        ptr = (char *) ptr + read_ahead;
slouken@2159
   203
        total_need -= read_ahead;
slouken@2159
   204
        total_read += read_ahead;
slouken@1895
   205
    }
slouken@2159
   206
slouken@2159
   207
    if (total_need < READAHEAD_BUFFER_SIZE) {
slouken@2159
   208
        if (!ReadFile
slouken@2159
   209
            (context->hidden.win32io.h, context->hidden.win32io.buffer.data,
slouken@2159
   210
             READAHEAD_BUFFER_SIZE, &byte_read, NULL)) {
slouken@2159
   211
            SDL_Error(SDL_EFREAD);
slouken@2159
   212
            return 0;
slouken@2159
   213
        }
slouken@2159
   214
        read_ahead = SDL_min(total_need, (int) byte_read);
slouken@2159
   215
        SDL_memcpy(ptr, context->hidden.win32io.buffer.data, read_ahead);
slouken@2159
   216
        context->hidden.win32io.buffer.size = byte_read;
slouken@2159
   217
        context->hidden.win32io.buffer.left = byte_read - read_ahead;
slouken@2159
   218
        total_read += read_ahead;
slouken@2159
   219
    } else {
slouken@2159
   220
        if (!ReadFile
slouken@2159
   221
            (context->hidden.win32io.h, ptr, total_need, &byte_read, NULL)) {
slouken@2159
   222
            SDL_Error(SDL_EFREAD);
slouken@2159
   223
            return 0;
slouken@2159
   224
        }
slouken@2159
   225
        total_read += byte_read;
slouken@2159
   226
    }
slouken@2159
   227
    return (total_read / size);
slouken@1446
   228
}
slouken@2160
   229
static size_t SDLCALL
slouken@2160
   230
win32_file_write(SDL_RWops * context, const void *ptr, size_t size,
slouken@2160
   231
                 size_t num)
slouken@1465
   232
{
slouken@1446
   233
slouken@2160
   234
    size_t total_bytes;
slouken@1895
   235
    DWORD byte_written, nwritten;
slouken@1446
   236
slouken@1895
   237
    total_bytes = size * num;
slouken@1895
   238
slouken@1895
   239
    if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE
slouken@1895
   240
        || total_bytes <= 0 || !size)
slouken@1895
   241
        return 0;
slouken@1895
   242
slouken@2159
   243
    if (context->hidden.win32io.buffer.left) {
slouken@2159
   244
        SetFilePointer(context->hidden.win32io.h,
slouken@2159
   245
                       -context->hidden.win32io.buffer.left, NULL,
slouken@2159
   246
                       FILE_CURRENT);
slouken@2159
   247
        context->hidden.win32io.buffer.left = 0;
slouken@2159
   248
    }
slouken@2159
   249
slouken@1895
   250
    /* if in append mode, we must go to the EOF before write */
slouken@1895
   251
    if (context->hidden.win32io.append) {
slouken@2159
   252
        if (SetFilePointer(context->hidden.win32io.h, 0L, NULL, FILE_END) ==
slouken@2159
   253
            INVALID_SET_FILE_POINTER) {
slouken@1895
   254
            SDL_Error(SDL_EFWRITE);
slouken@1895
   255
            return 0;
slouken@1895
   256
        }
slouken@1895
   257
    }
slouken@1895
   258
slouken@1895
   259
    if (!WriteFile
slouken@1895
   260
        (context->hidden.win32io.h, ptr, total_bytes, &byte_written, NULL)) {
slouken@1895
   261
        SDL_Error(SDL_EFWRITE);
slouken@1895
   262
        return 0;
slouken@1895
   263
    }
slouken@1895
   264
slouken@1895
   265
    nwritten = byte_written / size;
slouken@1895
   266
    return nwritten;
slouken@1446
   267
}
slouken@1895
   268
static int SDLCALL
slouken@1895
   269
win32_file_close(SDL_RWops * context)
slouken@1465
   270
{
slouken@1895
   271
slouken@1895
   272
    if (context) {
slouken@1895
   273
        if (context->hidden.win32io.h != INVALID_HANDLE_VALUE) {
slouken@1895
   274
            CloseHandle(context->hidden.win32io.h);
slouken@1895
   275
            context->hidden.win32io.h = INVALID_HANDLE_VALUE;   /* to be sure */
slouken@1895
   276
        }
slouken@2159
   277
        if (context->hidden.win32io.buffer.data) {
slouken@2159
   278
            SDL_free(context->hidden.win32io.buffer.data);
slouken@2159
   279
            context->hidden.win32io.buffer.data = NULL;
slouken@2159
   280
        }
slouken@1895
   281
        SDL_FreeRW(context);
slouken@1895
   282
    }
slouken@1895
   283
    return (0);
slouken@1446
   284
}
slouken@1447
   285
#endif /* __WIN32__ */
slouken@1446
   286
slouken@1447
   287
#ifdef HAVE_STDIO_H
slouken@1446
   288
slouken@1447
   289
/* Functions to read/write stdio file pointers */
slouken@1446
   290
slouken@2160
   291
static long SDLCALL
slouken@2160
   292
stdio_seek(SDL_RWops * context, long offset, int whence)
slouken@1447
   293
{
slouken@1895
   294
    if (fseek(context->hidden.stdio.fp, offset, whence) == 0) {
slouken@1895
   295
        return (ftell(context->hidden.stdio.fp));
slouken@1895
   296
    } else {
slouken@1895
   297
        SDL_Error(SDL_EFSEEK);
slouken@1895
   298
        return (-1);
slouken@1895
   299
    }
slouken@1447
   300
}
slouken@2160
   301
static size_t SDLCALL
slouken@2160
   302
stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
slouken@1447
   303
{
slouken@1895
   304
    size_t nread;
slouken@1447
   305
slouken@1895
   306
    nread = fread(ptr, size, maxnum, context->hidden.stdio.fp);
slouken@1895
   307
    if (nread == 0 && ferror(context->hidden.stdio.fp)) {
slouken@1895
   308
        SDL_Error(SDL_EFREAD);
slouken@1895
   309
    }
slouken@1895
   310
    return (nread);
slouken@1447
   311
}
slouken@2160
   312
static size_t SDLCALL
slouken@2160
   313
stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
slouken@1447
   314
{
slouken@1895
   315
    size_t nwrote;
slouken@1447
   316
slouken@1895
   317
    nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp);
slouken@1895
   318
    if (nwrote == 0 && ferror(context->hidden.stdio.fp)) {
slouken@1895
   319
        SDL_Error(SDL_EFWRITE);
slouken@1895
   320
    }
slouken@1895
   321
    return (nwrote);
slouken@1447
   322
}
slouken@1895
   323
static int SDLCALL
slouken@1895
   324
stdio_close(SDL_RWops * context)
slouken@1447
   325
{
slouken@2160
   326
    int status = 0;
slouken@1895
   327
    if (context) {
slouken@1895
   328
        if (context->hidden.stdio.autoclose) {
slouken@1895
   329
            /* WARNING:  Check the return value here! */
slouken@2160
   330
            if (fclose(context->hidden.stdio.fp) != 0) {
slouken@2160
   331
                SDL_Error(SDL_EFWRITE);
slouken@2160
   332
                status = -1;
slouken@2160
   333
            }
slouken@1895
   334
        }
slouken@1895
   335
        SDL_FreeRW(context);
slouken@1895
   336
    }
slouken@2160
   337
    return status;
slouken@1447
   338
}
slouken@1446
   339
#endif /* !HAVE_STDIO_H */
slouken@1330
   340
slouken@0
   341
/* Functions to read/write memory pointers */
slouken@0
   342
slouken@2160
   343
static long SDLCALL
slouken@2160
   344
mem_seek(SDL_RWops * context, long offset, int whence)
slouken@0
   345
{
slouken@1895
   346
    Uint8 *newpos;
slouken@0
   347
slouken@1895
   348
    switch (whence) {
slouken@1895
   349
    case RW_SEEK_SET:
slouken@1895
   350
        newpos = context->hidden.mem.base + offset;
slouken@1895
   351
        break;
slouken@1895
   352
    case RW_SEEK_CUR:
slouken@1895
   353
        newpos = context->hidden.mem.here + offset;
slouken@1895
   354
        break;
slouken@1895
   355
    case RW_SEEK_END:
slouken@1895
   356
        newpos = context->hidden.mem.stop + offset;
slouken@1895
   357
        break;
slouken@1895
   358
    default:
slouken@1895
   359
        SDL_SetError("Unknown value for 'whence'");
slouken@1895
   360
        return (-1);
slouken@1895
   361
    }
slouken@1895
   362
    if (newpos < context->hidden.mem.base) {
slouken@1895
   363
        newpos = context->hidden.mem.base;
slouken@1895
   364
    }
slouken@1895
   365
    if (newpos > context->hidden.mem.stop) {
slouken@1895
   366
        newpos = context->hidden.mem.stop;
slouken@1895
   367
    }
slouken@1895
   368
    context->hidden.mem.here = newpos;
slouken@1895
   369
    return (context->hidden.mem.here - context->hidden.mem.base);
slouken@0
   370
}
slouken@2160
   371
static size_t SDLCALL
slouken@2160
   372
mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum)
slouken@0
   373
{
slouken@1895
   374
    size_t total_bytes;
slouken@1895
   375
    size_t mem_available;
slouken@0
   376
slouken@1895
   377
    total_bytes = (maxnum * size);
slouken@1895
   378
    if ((maxnum <= 0) || (size <= 0)
slouken@1895
   379
        || ((total_bytes / maxnum) != (size_t) size)) {
slouken@1895
   380
        return 0;
slouken@1895
   381
    }
icculus@1078
   382
slouken@1895
   383
    mem_available = (context->hidden.mem.stop - context->hidden.mem.here);
slouken@1895
   384
    if (total_bytes > mem_available) {
slouken@1895
   385
        total_bytes = mem_available;
slouken@1895
   386
    }
icculus@1078
   387
slouken@1895
   388
    SDL_memcpy(ptr, context->hidden.mem.here, total_bytes);
slouken@1895
   389
    context->hidden.mem.here += total_bytes;
icculus@1078
   390
slouken@1895
   391
    return (total_bytes / size);
slouken@0
   392
}
slouken@2160
   393
static size_t SDLCALL
slouken@2160
   394
mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num)
slouken@0
   395
{
slouken@1895
   396
    if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) {
slouken@1895
   397
        num = (context->hidden.mem.stop - context->hidden.mem.here) / size;
slouken@1895
   398
    }
slouken@1895
   399
    SDL_memcpy(context->hidden.mem.here, ptr, num * size);
slouken@1895
   400
    context->hidden.mem.here += num * size;
slouken@1895
   401
    return (num);
slouken@0
   402
}
slouken@2160
   403
static size_t SDLCALL
slouken@2160
   404
mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num)
slouken@764
   405
{
slouken@1895
   406
    SDL_SetError("Can't write to read-only memory");
slouken@1895
   407
    return (-1);
slouken@764
   408
}
slouken@1895
   409
static int SDLCALL
slouken@1895
   410
mem_close(SDL_RWops * context)
slouken@0
   411
{
slouken@1895
   412
    if (context) {
slouken@1895
   413
        SDL_FreeRW(context);
slouken@1895
   414
    }
slouken@1895
   415
    return (0);
slouken@0
   416
}
slouken@0
   417
slouken@1447
   418
slouken@0
   419
/* Functions to create SDL_RWops structures from various data sources */
slouken@0
   420
slouken@1895
   421
SDL_RWops *
slouken@1895
   422
SDL_RWFromFile(const char *file, const char *mode)
slouken@0
   423
{
slouken@1895
   424
    SDL_RWops *rwops = NULL;
slouken@1465
   425
#ifdef HAVE_STDIO_H
slouken@1895
   426
    FILE *fp = NULL;
slouken@1465
   427
#endif
slouken@1895
   428
    if (!file || !*file || !mode || !*mode) {
slouken@1895
   429
        SDL_SetError("SDL_RWFromFile(): No file or no mode specified");
slouken@1895
   430
        return NULL;
slouken@1895
   431
    }
slouken@1465
   432
#if defined(__WIN32__)
slouken@1895
   433
    rwops = SDL_AllocRW();
slouken@1895
   434
    if (!rwops)
slouken@1895
   435
        return NULL;            /* SDL_SetError already setup by SDL_AllocRW() */
slouken@2164
   436
    if (win32_file_open(rwops, file, mode) < 0) {
slouken@1895
   437
        SDL_FreeRW(rwops);
slouken@1895
   438
        return NULL;
slouken@1895
   439
    }
slouken@1895
   440
    rwops->seek = win32_file_seek;
slouken@1895
   441
    rwops->read = win32_file_read;
slouken@1895
   442
    rwops->write = win32_file_write;
slouken@1895
   443
    rwops->close = win32_file_close;
slouken@1447
   444
slouken@1447
   445
#elif HAVE_STDIO_H
slouken@0
   446
slouken@1895
   447
    fp = fopen(file, mode);
slouken@1895
   448
    if (fp == NULL) {
slouken@1895
   449
        SDL_SetError("Couldn't open %s", file);
slouken@1895
   450
    } else {
slouken@1895
   451
        rwops = SDL_RWFromFP(fp, 1);
slouken@1895
   452
    }
slouken@0
   453
#else
slouken@1895
   454
    SDL_SetError("SDL not compiled with stdio support");
slouken@1446
   455
#endif /* !HAVE_STDIO_H */
slouken@1447
   456
slouken@1895
   457
    return (rwops);
slouken@0
   458
}
slouken@0
   459
slouken@1330
   460
#ifdef HAVE_STDIO_H
slouken@1895
   461
SDL_RWops *
slouken@2161
   462
SDL_RWFromFP(FILE * fp, SDL_bool autoclose)
slouken@0
   463
{
slouken@1895
   464
    SDL_RWops *rwops = NULL;
slouken@0
   465
slouken@1895
   466
    rwops = SDL_AllocRW();
slouken@1895
   467
    if (rwops != NULL) {
slouken@1895
   468
        rwops->seek = stdio_seek;
slouken@1895
   469
        rwops->read = stdio_read;
slouken@1895
   470
        rwops->write = stdio_write;
slouken@1895
   471
        rwops->close = stdio_close;
slouken@1895
   472
        rwops->hidden.stdio.fp = fp;
slouken@1895
   473
        rwops->hidden.stdio.autoclose = autoclose;
slouken@1895
   474
    }
slouken@1895
   475
    return (rwops);
slouken@0
   476
}
slouken@1330
   477
#endif /* HAVE_STDIO_H */
slouken@0
   478
slouken@1895
   479
SDL_RWops *
slouken@1895
   480
SDL_RWFromMem(void *mem, int size)
slouken@0
   481
{
slouken@1895
   482
    SDL_RWops *rwops;
slouken@0
   483
slouken@1895
   484
    rwops = SDL_AllocRW();
slouken@1895
   485
    if (rwops != NULL) {
slouken@1895
   486
        rwops->seek = mem_seek;
slouken@1895
   487
        rwops->read = mem_read;
slouken@1895
   488
        rwops->write = mem_write;
slouken@1895
   489
        rwops->close = mem_close;
slouken@1895
   490
        rwops->hidden.mem.base = (Uint8 *) mem;
slouken@1895
   491
        rwops->hidden.mem.here = rwops->hidden.mem.base;
slouken@1895
   492
        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
slouken@1895
   493
    }
slouken@1895
   494
    return (rwops);
slouken@0
   495
}
slouken@0
   496
slouken@1895
   497
SDL_RWops *
slouken@1895
   498
SDL_RWFromConstMem(const void *mem, int size)
slouken@764
   499
{
slouken@1895
   500
    SDL_RWops *rwops;
slouken@764
   501
slouken@1895
   502
    rwops = SDL_AllocRW();
slouken@1895
   503
    if (rwops != NULL) {
slouken@1895
   504
        rwops->seek = mem_seek;
slouken@1895
   505
        rwops->read = mem_read;
slouken@1895
   506
        rwops->write = mem_writeconst;
slouken@1895
   507
        rwops->close = mem_close;
slouken@1895
   508
        rwops->hidden.mem.base = (Uint8 *) mem;
slouken@1895
   509
        rwops->hidden.mem.here = rwops->hidden.mem.base;
slouken@1895
   510
        rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
slouken@1895
   511
    }
slouken@1895
   512
    return (rwops);
slouken@764
   513
}
slouken@764
   514
slouken@1895
   515
SDL_RWops *
slouken@1895
   516
SDL_AllocRW(void)
slouken@0
   517
{
slouken@1895
   518
    SDL_RWops *area;
slouken@0
   519
slouken@1895
   520
    area = (SDL_RWops *) SDL_malloc(sizeof *area);
slouken@1895
   521
    if (area == NULL) {
slouken@1895
   522
        SDL_OutOfMemory();
slouken@1895
   523
    }
slouken@1895
   524
    return (area);
slouken@0
   525
}
slouken@0
   526
slouken@1895
   527
void
slouken@1895
   528
SDL_FreeRW(SDL_RWops * area)
slouken@0
   529
{
slouken@1895
   530
    SDL_free(area);
slouken@0
   531
}
slouken@1354
   532
slouken@1354
   533
/* Functions for dynamically reading and writing endian-specific values */
slouken@1354
   534
slouken@1895
   535
Uint16
slouken@1895
   536
SDL_ReadLE16(SDL_RWops * src)
slouken@1354
   537
{
slouken@1895
   538
    Uint16 value;
slouken@1354
   539
slouken@1895
   540
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   541
    return (SDL_SwapLE16(value));
slouken@1354
   542
}
slouken@1354
   543
slouken@1895
   544
Uint16
slouken@1895
   545
SDL_ReadBE16(SDL_RWops * src)
slouken@1354
   546
{
slouken@1895
   547
    Uint16 value;
slouken@1895
   548
slouken@1895
   549
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   550
    return (SDL_SwapBE16(value));
slouken@1354
   551
}
slouken@1895
   552
slouken@1895
   553
Uint32
slouken@1895
   554
SDL_ReadLE32(SDL_RWops * src)
slouken@1354
   555
{
slouken@1895
   556
    Uint32 value;
slouken@1895
   557
slouken@1895
   558
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   559
    return (SDL_SwapLE32(value));
slouken@1354
   560
}
slouken@1895
   561
slouken@1895
   562
Uint32
slouken@1895
   563
SDL_ReadBE32(SDL_RWops * src)
slouken@1354
   564
{
slouken@1895
   565
    Uint32 value;
slouken@1895
   566
slouken@1895
   567
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   568
    return (SDL_SwapBE32(value));
slouken@1354
   569
}
slouken@1895
   570
slouken@1895
   571
Uint64
slouken@1895
   572
SDL_ReadLE64(SDL_RWops * src)
slouken@1354
   573
{
slouken@1895
   574
    Uint64 value;
slouken@1895
   575
slouken@1895
   576
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   577
    return (SDL_SwapLE64(value));
slouken@1354
   578
}
slouken@1895
   579
slouken@1895
   580
Uint64
slouken@1895
   581
SDL_ReadBE64(SDL_RWops * src)
slouken@1354
   582
{
slouken@1895
   583
    Uint64 value;
slouken@1895
   584
slouken@1895
   585
    SDL_RWread(src, &value, (sizeof value), 1);
slouken@1895
   586
    return (SDL_SwapBE64(value));
slouken@1354
   587
}
slouken@1895
   588
slouken@1895
   589
int
slouken@1895
   590
SDL_WriteLE16(SDL_RWops * dst, Uint16 value)
slouken@1354
   591
{
slouken@1895
   592
    value = SDL_SwapLE16(value);
slouken@1895
   593
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1354
   594
}
slouken@1895
   595
slouken@1895
   596
int
slouken@1895
   597
SDL_WriteBE16(SDL_RWops * dst, Uint16 value)
slouken@1895
   598
{
slouken@1895
   599
    value = SDL_SwapBE16(value);
slouken@1895
   600
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1895
   601
}
slouken@1895
   602
slouken@1895
   603
int
slouken@1895
   604
SDL_WriteLE32(SDL_RWops * dst, Uint32 value)
slouken@1895
   605
{
slouken@1895
   606
    value = SDL_SwapLE32(value);
slouken@1895
   607
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1895
   608
}
slouken@1895
   609
slouken@1895
   610
int
slouken@1895
   611
SDL_WriteBE32(SDL_RWops * dst, Uint32 value)
slouken@1895
   612
{
slouken@1895
   613
    value = SDL_SwapBE32(value);
slouken@1895
   614
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1895
   615
}
slouken@1895
   616
slouken@1895
   617
int
slouken@1895
   618
SDL_WriteLE64(SDL_RWops * dst, Uint64 value)
slouken@1895
   619
{
slouken@1895
   620
    value = SDL_SwapLE64(value);
slouken@1895
   621
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1895
   622
}
slouken@1895
   623
slouken@1895
   624
int
slouken@1895
   625
SDL_WriteBE64(SDL_RWops * dst, Uint64 value)
slouken@1895
   626
{
slouken@1895
   627
    value = SDL_SwapBE64(value);
slouken@1895
   628
    return (SDL_RWwrite(dst, &value, (sizeof value), 1));
slouken@1895
   629
}
slouken@1895
   630
slouken@1895
   631
/* vi: set ts=4 sw=4 expandtab: */