Browse Source

Allow in-memory IOStreams to be of length 0 (#13840)

ProgramGamer 1 week ago
parent
commit
2c8c2d72b5
2 changed files with 183 additions and 19 deletions
  1. 2 10
      src/io/SDL_iostream.c
  2. 181 9
      test/testautomation_iostream.c

+ 2 - 10
src/io/SDL_iostream.c

@@ -1023,14 +1023,10 @@ SDL_IOStream *SDL_IOFromFile(const char *file, const char *mode)
 
 
 SDL_IOStream *SDL_IOFromMem(void *mem, size_t size)
 SDL_IOStream *SDL_IOFromMem(void *mem, size_t size)
 {
 {
-    CHECK_PARAM(!mem) {
+    CHECK_PARAM(size && !mem) {
         SDL_InvalidParamError("mem");
         SDL_InvalidParamError("mem");
         return NULL;
         return NULL;
     }
     }
-    CHECK_PARAM(!size) {
-        SDL_InvalidParamError("size");
-        return NULL;
-    }
 
 
     IOStreamMemData *iodata = (IOStreamMemData *) SDL_calloc(1, sizeof (*iodata));
     IOStreamMemData *iodata = (IOStreamMemData *) SDL_calloc(1, sizeof (*iodata));
     if (!iodata) {
     if (!iodata) {
@@ -1065,14 +1061,10 @@ SDL_IOStream *SDL_IOFromMem(void *mem, size_t size)
 
 
 SDL_IOStream *SDL_IOFromConstMem(const void *mem, size_t size)
 SDL_IOStream *SDL_IOFromConstMem(const void *mem, size_t size)
 {
 {
-    CHECK_PARAM(!mem) {
+    CHECK_PARAM(size && !mem) {
         SDL_InvalidParamError("mem");
         SDL_InvalidParamError("mem");
         return NULL;
         return NULL;
     }
     }
-    CHECK_PARAM(!size) {
-        SDL_InvalidParamError("size");
-        return NULL;
-    }
 
 
     IOStreamMemData *iodata = (IOStreamMemData *) SDL_calloc(1, sizeof (*iodata));
     IOStreamMemData *iodata = (IOStreamMemData *) SDL_calloc(1, sizeof (*iodata));
     if (!iodata) {
     if (!iodata) {

+ 181 - 9
test/testautomation_iostream.c

@@ -198,6 +198,110 @@ static void testGenericIOStreamValidations(SDL_IOStream *rw, bool write)
         (int)i);
         (int)i);
 }
 }
 
 
+/**
+ * Makes sure parameters work properly. Local helper function.
+ *
+ * \sa SDL_SeekIO
+ * \sa SDL_ReadIO
+ */
+static void testEmptyIOStreamValidations(SDL_IOStream *rw, bool write)
+{
+    char con[sizeof(IOStreamHelloWorldTestString)];
+    char buf[sizeof(IOStreamHelloWorldTestString)];
+    Sint64 i;
+    size_t s;
+    int seekPos = SDLTest_RandomIntegerInRange(4, 8);
+
+    /* Clear control & buffer */
+    SDL_zeroa(con);
+    SDL_zeroa(buf);
+
+    /* Set to start. */
+    i = SDL_SeekIO(rw, 0, SDL_IO_SEEK_SET);
+    SDLTest_AssertPass("Call to SDL_SeekIO succeeded");
+    SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_SeekIO (SDL_IO_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
+
+    /* Test write */
+    s = SDL_WriteIO(rw, IOStreamHelloWorldTestString, sizeof(IOStreamHelloWorldTestString) - 1);
+    SDLTest_AssertPass("Call to SDL_WriteIO succeeded");
+    if (write) {
+        SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_WriteIO, expected 0, got %i", (int)s);
+    } else {
+        SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_WriteIO, expected 0, got %i", (int)s);
+    }
+
+    /* Test seek to random position */
+    i = SDL_SeekIO(rw, seekPos, SDL_IO_SEEK_SET);
+    SDLTest_AssertPass("Call to SDL_SeekIO succeeded");
+    SDLTest_AssertCheck(i == 0, "Verify seek to %i with SDL_SeekIO (SDL_IO_SEEK_SET), expected 0, got %" SDL_PRIs64, seekPos, i);
+
+    /* Test seek back to start */
+    i = SDL_SeekIO(rw, 0, SDL_IO_SEEK_SET);
+    SDLTest_AssertPass("Call to SDL_SeekIO succeeded");
+    SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_SeekIO (SDL_IO_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
+
+    /* Test read */
+    s = SDL_ReadIO(rw, buf, sizeof(IOStreamHelloWorldTestString) - 1);
+    SDLTest_AssertPass("Call to SDL_ReadIO succeeded");
+    SDLTest_AssertCheck(s == 0, "Verify result from SDL_ReadIO, expected 0, got %i", (int)s);
+    SDLTest_AssertCheck(
+        SDL_memcmp(buf, con, sizeof(IOStreamHelloWorldTestString) - 1) == 0,
+        "Verify that buffer remains unchanged, expected '%s', got '%s'", con, buf);
+
+    /* Test seek back to start */
+    i = SDL_SeekIO(rw, 0, SDL_IO_SEEK_SET);
+    SDLTest_AssertPass("Call to SDL_SeekIO succeeded");
+    SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_SeekIO (SDL_IO_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
+
+    /* Test printf */
+    s = SDL_IOprintf(rw, "%s", IOStreamHelloWorldTestString);
+    SDLTest_AssertPass("Call to SDL_IOprintf succeeded");
+    if (write) {
+        SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_IOprintf, expected 0, got %i", (int)s);
+    } else {
+        SDLTest_AssertCheck(s == 0, "Verify result of writing with SDL_WriteIO, expected 0, got %i", (int)s);
+    }
+
+    /* Test seek back to start */
+    i = SDL_SeekIO(rw, 0, SDL_IO_SEEK_SET);
+    SDLTest_AssertPass("Call to SDL_SeekIO succeeded");
+    SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_SeekIO (SDL_IO_SEEK_SET), expected 0, got %" SDL_PRIs64, i);
+
+    /* Test read */
+    s = SDL_ReadIO(rw, buf, sizeof(IOStreamHelloWorldTestString) - 1);
+    SDLTest_AssertPass("Call to SDL_ReadIO succeeded");
+    SDLTest_AssertCheck(
+        s == 0,
+        "Verify result from SDL_ReadIO, expected 0, got %i",
+        (int)s);
+    SDLTest_AssertCheck(
+        SDL_memcmp(buf, con, sizeof(IOStreamHelloWorldTestString) - 1) == 0,
+        "Verify that buffer remains unchanged, expected '%s', got '%s'", con, buf);
+
+    /* More seek tests. */
+    i = SDL_SeekIO(rw, -4, SDL_IO_SEEK_CUR);
+    SDLTest_AssertPass("Call to SDL_SeekIO(...,-4,SDL_IO_SEEK_CUR) succeeded");
+    SDLTest_AssertCheck(
+        i == 0,
+        "Verify seek to -4 with SDL_SeekIO (SDL_IO_SEEK_CUR), expected 0, got %i",
+        (int)i);
+
+    i = SDL_SeekIO(rw, -1, SDL_IO_SEEK_END);
+    SDLTest_AssertPass("Call to SDL_SeekIO(...,-1,SDL_IO_SEEK_END) succeeded");
+    SDLTest_AssertCheck(
+        i == 0,
+        "Verify seek to -1 with SDL_SeekIO (SDL_IO_SEEK_END), expected 0, got %i",
+        (int)i);
+
+    /* Invalid whence seek */
+    i = SDL_SeekIO(rw, 0, (SDL_IOWhence)999);
+    SDLTest_AssertPass("Call to SDL_SeekIO(...,0,invalid_whence) succeeded");
+    SDLTest_AssertCheck(
+        i == (Sint64)(-1),
+        "Verify seek with SDL_SeekIO (invalid_whence); expected: -1, got %i",
+        (int)i);
+}
+
 /**
 /**
  * Negative test for SDL_IOFromFile parameters
  * Negative test for SDL_IOFromFile parameters
  *
  *
@@ -233,14 +337,6 @@ static int SDLCALL iostrm_testParamNegative(void *arg)
     SDLTest_AssertPass("Call to SDL_IOFromMem(NULL, 10) succeeded");
     SDLTest_AssertPass("Call to SDL_IOFromMem(NULL, 10) succeeded");
     SDLTest_AssertCheck(iostrm == NULL, "Verify SDL_IOFromMem(NULL, 10) returns NULL");
     SDLTest_AssertCheck(iostrm == NULL, "Verify SDL_IOFromMem(NULL, 10) returns NULL");
 
 
-    iostrm = SDL_IOFromMem((void *)IOStreamAlphabetString, 0);
-    SDLTest_AssertPass("Call to SDL_IOFromMem(data, 0) succeeded");
-    SDLTest_AssertCheck(iostrm == NULL, "Verify SDL_IOFromMem(data, 0) returns NULL");
-
-    iostrm = SDL_IOFromConstMem((const void *)IOStreamAlphabetString, 0);
-    SDLTest_AssertPass("Call to SDL_IOFromConstMem(data, 0) succeeded");
-    SDLTest_AssertCheck(iostrm == NULL, "Verify SDL_IOFromConstMem(data, 0) returns NULL");
-
     return TEST_COMPLETED;
     return TEST_COMPLETED;
 }
 }
 
 
@@ -312,6 +408,74 @@ static int SDLCALL iostrm_testConstMem(void *arg)
     return TEST_COMPLETED;
     return TEST_COMPLETED;
 }
 }
 
 
+/**
+ * Tests opening nothing.
+ * 
+ * \sa SDL_IOFromMem
+ * \sa SDL_CloseIO
+ */
+static int SDLCALL iostrm_testMemEmpty(void *arg)
+{
+    char mem[sizeof(IOStreamHelloWorldTestString)];
+    SDL_IOStream *rw;
+    int result;
+
+    /* Clear buffer */
+    SDL_zeroa(mem);
+
+    /* Open empty */
+    rw = SDL_IOFromMem(mem, 0);
+    SDLTest_AssertPass("Call to SDL_IOFromMem() succeeded");
+    SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_IOFromMem does not return NULL");
+
+    /* Bail out if NULL */
+    if (rw == NULL) {
+        return TEST_ABORTED;
+    }
+
+    /* Run generic tests */
+    testEmptyIOStreamValidations(rw, true);
+
+    /* Close */
+    result = SDL_CloseIO(rw);
+    SDLTest_AssertPass("Call to SDL_CloseIO() succeeded");
+    SDLTest_AssertCheck(result == true, "Verify result value is true; got: %d", result);
+
+    return TEST_COMPLETED;
+}
+
+/**
+ * Tests opening nothing.
+ * 
+ * \sa SDL_IOFromMem
+ * \sa SDL_CloseIO
+ */
+static int SDLCALL iostrm_testConstMemEmpty(void *arg)
+{
+    SDL_IOStream *rw;
+    int result;
+
+    /* Open handle */
+    rw = SDL_IOFromConstMem(IOStreamHelloWorldCompString, 0);
+    SDLTest_AssertPass("Call to SDL_IOFromConstMem() succeeded");
+    SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_IOFromConstMem does not return NULL");
+
+    /* Bail out if NULL */
+    if (rw == NULL) {
+        return TEST_ABORTED;
+    }
+
+    /* Run generic tests */
+    testEmptyIOStreamValidations(rw, false);
+
+    /* Close handle */
+    result = SDL_CloseIO(rw);
+    SDLTest_AssertPass("Call to SDL_CloseIO() succeeded");
+    SDLTest_AssertCheck(result == true, "Verify result value is true; got: %d", result);
+
+    return TEST_COMPLETED;
+}
+
 static int free_call_count;
 static int free_call_count;
 void SDLCALL test_free(void* mem) {
 void SDLCALL test_free(void* mem) {
     free_call_count++;
     free_call_count++;
@@ -736,10 +900,18 @@ static const SDLTest_TestCaseReference iostrmTest10 = {
     iostrm_testMemWithFree, "iostrm_testMemWithFree", "Tests opening from memory with free on close", TEST_ENABLED
     iostrm_testMemWithFree, "iostrm_testMemWithFree", "Tests opening from memory with free on close", TEST_ENABLED
 };
 };
 
 
+static const SDLTest_TestCaseReference iostrmTest11 = {
+    iostrm_testMemEmpty, "iostrm_testMemEmpty", "Tests opening empty memory stream", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference iostrmTest12 = {
+    iostrm_testConstMemEmpty, "iostrm_testConstMemEmpty", "Tests opening empty (const) memory stream", TEST_ENABLED
+};
+
 /* Sequence of IOStream test cases */
 /* Sequence of IOStream test cases */
 static const SDLTest_TestCaseReference *iostrmTests[] = {
 static const SDLTest_TestCaseReference *iostrmTests[] = {
     &iostrmTest1, &iostrmTest2, &iostrmTest3, &iostrmTest4, &iostrmTest5, &iostrmTest6,
     &iostrmTest1, &iostrmTest2, &iostrmTest3, &iostrmTest4, &iostrmTest5, &iostrmTest6,
-    &iostrmTest7, &iostrmTest8, &iostrmTest9, &iostrmTest10, NULL
+    &iostrmTest7, &iostrmTest8, &iostrmTest9, &iostrmTest10, &iostrmTest11, &iostrmTest12, NULL
 };
 };
 
 
 /* IOStream test suite (global) */
 /* IOStream test suite (global) */