Indentations break the feed.
[SquirrelJME.git] / nanocoat / lib / base / seekableMemory.c
blob42de8468c7d91ecb7e6f3b35cda1156048dd2b9c
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 #include <string.h>
12 #include "sjme/seekable.h"
13 #include "sjme/debug.h"
14 #include "sjme/closeable.h"
16 /**
17 * Memory initialization info.
19 * @since 2024/08/12
21 typedef struct sjme_seekable_memoryInitData
23 /** The base pointer. */
24 sjme_pointer base;
26 /** The memory region size. */
27 sjme_jint length;
28 } sjme_seekable_memoryInitData;
30 static sjme_errorCode sjme_seekable_memoryClose(
31 sjme_attrInNotNull sjme_seekable inSeekable,
32 sjme_attrInNotNull sjme_seekable_implState* inImplState)
34 if (inSeekable == NULL || inImplState == NULL)
35 return SJME_ERROR_NULL_ARGUMENTS;
37 /* Nothing needs to be done for memory regions. */
38 return SJME_ERROR_NONE;
41 static sjme_errorCode sjme_seekable_memoryInit(
42 sjme_attrInNotNull sjme_seekable inSeekable,
43 sjme_attrInNotNull sjme_seekable_implState* inImplState,
44 sjme_attrInNullable sjme_pointer data)
46 sjme_seekable_memoryInitData* init;
48 if (inSeekable == NULL || inImplState == NULL || data == NULL)
49 return SJME_ERROR_NULL_ARGUMENTS;
51 /* Recover init data. */
52 init = data;
54 /* Set parameters. */
55 inImplState->handle = init->base;
56 inImplState->length = init->length;
58 /* Success! */
59 return SJME_ERROR_NONE;
62 static sjme_errorCode sjme_seekable_memoryRead(
63 sjme_attrInNotNull sjme_seekable inSeekable,
64 sjme_attrInNotNull sjme_seekable_implState* inImplState,
65 sjme_attrOutNotNullBuf(length) sjme_buffer outBuf,
66 sjme_attrInPositive sjme_jint base,
67 sjme_attrInPositiveNonZero sjme_jint length)
69 if (inSeekable == NULL || inImplState == NULL || outBuf == NULL)
70 return SJME_ERROR_NULL_ARGUMENTS;
72 if (base < 0 || length < 0 || (base + length) < 0 ||
73 (base + length) > inImplState->length)
74 return SJME_ERROR_INDEX_OUT_OF_BOUNDS;
76 /* Direct memory copy. */
77 memmove(outBuf, SJME_POINTER_OFFSET(inImplState->handle, base),
78 length);
80 /* Success! */
81 return SJME_ERROR_NONE;
84 static sjme_errorCode sjme_seekable_memorySize(
85 sjme_attrInNotNull sjme_seekable inSeekable,
86 sjme_attrInNotNull sjme_seekable_implState* inImplState,
87 sjme_attrOutNotNull sjme_jint* outSize)
89 if (inSeekable == NULL || inImplState == NULL || outSize == NULL)
90 return SJME_ERROR_NULL_ARGUMENTS;
92 /* Just copy from the implementation state. */
93 *outSize = inImplState->length;
94 return SJME_ERROR_NONE;
97 static const sjme_seekable_functions sjme_seekable_memoryFunctions =
99 .close = sjme_seekable_memoryClose,
100 .init = sjme_seekable_memoryInit,
101 .read = sjme_seekable_memoryRead,
102 .size = sjme_seekable_memorySize,
105 sjme_errorCode sjme_seekable_openMemory(
106 sjme_attrInNotNull sjme_alloc_pool* inPool,
107 sjme_attrOutNotNull sjme_seekable* outSeekable,
108 sjme_attrInNotNull sjme_pointer base,
109 sjme_attrInPositive sjme_jint length)
111 uintptr_t rawBase;
112 sjme_seekable_memoryInitData init;
114 if (inPool == NULL || outSeekable == NULL || base == NULL)
115 return SJME_ERROR_NULL_ARGUMENTS;
117 /* Check for overflow. */
118 rawBase = (uintptr_t)base;
119 if (length < 0 || (rawBase + length) < rawBase)
120 return SJME_ERROR_INDEX_OUT_OF_BOUNDS;
122 /* Setup initialization data. */
123 memset(&init, 0, sizeof(init));
124 init.base = base;
125 init.length = length;
127 /* Forward initialize. */
128 return sjme_seekable_open(inPool, outSeekable,
129 &sjme_seekable_memoryFunctions,
130 &init, NULL);