1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
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 // -------------------------------------------------------------------------*/
12 #include "sjme/seekable.h"
13 #include "sjme/debug.h"
14 #include "sjme/closeable.h"
17 * Memory initialization info.
21 typedef struct sjme_seekable_memoryInitData
23 /** The base pointer. */
26 /** The memory region size. */
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. */
55 inImplState
->handle
= init
->base
;
56 inImplState
->length
= init
->length
;
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
),
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
)
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
));
125 init
.length
= length
;
127 /* Forward initialize. */
128 return sjme_seekable_open(inPool
, outSeekable
,
129 &sjme_seekable_memoryFunctions
,