Browse Source

Added an API SDL_LoadFile_RW() to load all the data from an SDL data stream, and a convenience macro SDL_LoadFile() to load all the data from a file.

Sam Lantinga 7 years ago
parent
commit
dc40018438
4 changed files with 78 additions and 0 deletions
  1. 23 0
      include/SDL_rwops.h
  2. 1 0
      src/dynapi/SDL_dynapi_overrides.h
  3. 1 0
      src/dynapi/SDL_dynapi_procs.h
  4. 53 0
      src/file/SDL_rwops.c

+ 23 - 0
include/SDL_rwops.h

@@ -190,6 +190,29 @@ extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area);
 /* @} *//* Read/write macros */
 
 
+/**
+ *  Load all the data from an SDL data stream.
+ *
+ *  The data is allocated with a zero byte at the end (null terminated)
+ *
+ *  If \c datasize is not NULL, it is filled with the size of the data read.
+ *
+ *  If \c freesrc is non-zero, the stream will be closed after being read.
+ *
+ *  The data should be freed with SDL_free().
+ *
+ *  \return the data, or NULL if there was an error.
+ */
+extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize,
+                                                    int freesrc);
+
+/**
+ *  Load an entire file.
+ *
+ *  Convenience macro.
+ */
+#define SDL_LoadFile(file, datasize)   SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, 1)
+
 /**
  *  \name Read endian functions
  *

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -625,3 +625,4 @@
 #define SDL_MemoryBarrierAcquireFunction SDL_MemoryBarrierAcquireFunction_REAL
 #define SDL_JoystickGetDeviceInstanceID SDL_JoystickGetDeviceInstanceID_REAL
 #define SDL_utf8strlen SDL_utf8strlen_REAL
+#define SDL_LoadFile_RW SDL_LoadFile_RW_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -657,3 +657,4 @@ SDL_DYNAPI_PROC(void,SDL_MemoryBarrierReleaseFunction,(void),(),)
 SDL_DYNAPI_PROC(void,SDL_MemoryBarrierAcquireFunction,(void),(),)
 SDL_DYNAPI_PROC(SDL_JoystickID,SDL_JoystickGetDeviceInstanceID,(int a),(a),return)
 SDL_DYNAPI_PROC(size_t,SDL_utf8strlen,(const char *a),(a),return)
+SDL_DYNAPI_PROC(void*,SDL_LoadFile_RW,(SDL_RWops *a, size_t *b, int c),(a,b,c),return)

+ 53 - 0
src/file/SDL_rwops.c

@@ -653,6 +653,59 @@ SDL_FreeRW(SDL_RWops * area)
     SDL_free(area);
 }
 
+/* Load all the data from an SDL data stream */
+void *
+SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc)
+{
+    const int FILE_CHUNK_SIZE = 1024;
+    Sint64 size;
+    size_t size_read, size_total;
+    void *data = NULL, *newdata;
+
+    if (!src) {
+        SDL_InvalidParamError("src");
+        return NULL;
+    }
+
+    size = SDL_RWsize(src);
+    if (size < 0) {
+        size = FILE_CHUNK_SIZE;
+    }
+    data = SDL_malloc(size+1);
+
+    size_total = 0;
+    for (;;) {
+        if ((size_total + FILE_CHUNK_SIZE) > size) {
+            size = (size_total + FILE_CHUNK_SIZE);
+            newdata = SDL_realloc(data, size + 1);
+            if (!newdata) {
+                SDL_free(data);
+                data = NULL;
+                SDL_OutOfMemory();
+                goto done;
+            }
+            data = newdata;
+        }
+
+        size_read = SDL_RWread(src, (char *)data+size_total, 1, (size_t)(size-size_total));
+        if (size_read == 0) {
+            break;
+        }
+        size_total += size_read;
+    }
+
+    if (datasize) {
+        *datasize = size_total;
+    }
+    ((char *)data)[size_total] = '\0';
+
+done:
+    if (freesrc && src) {
+        SDL_RWclose(src);
+    }
+    return data;
+}
+
 /* Functions for dynamically reading and writing endian-specific values */
 
 Uint8