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 // -------------------------------------------------------------------------*/
13 #include "frontend/emulator/common.h"
14 #include "frontend/emulator/jniHelper.h"
15 #include "sjme/alloc.h"
16 #include "sjme/debug.h"
17 #include "sjme/nvm/rom.h"
19 sjme_errorCode
sjme_jni_virtualLibrary_init(
20 sjme_attrInNotNull sjme_rom_library inLibrary
,
21 sjme_attrInNullable sjme_pointer data
)
29 if (inLibrary
== NULL
)
30 return SJME_ERROR_NULL_ARGUMENTS
;
32 /* Get env and object back. */
33 env
= inLibrary
->cache
.common
.frontEnd
.data
;
34 self
= inLibrary
->cache
.common
.frontEnd
.wrapper
;
35 classy
= (*env
)->GetObjectClass(env
, self
);
37 /* Find the ID and name functions. */
38 idFunc
= (*env
)->GetMethodID(env
, classy
, "__id", "()I");
39 nameFunc
= (*env
)->GetMethodID(env
, classy
, "__name", "()J");
42 sjme_message("env: %p, self: %p, selfClass: %p, idFunc: %p, "
44 env
, self
, classy
, idFunc
, nameFunc
);
47 inLibrary
->id
= (*env
)->CallIntMethod(env
, self
, idFunc
, classy
);
48 if (sjme_jni_checkVMException(env
))
49 return SJME_ERROR_JNI_EXCEPTION
;
52 inLibrary
->name
= SJME_JLONG_TO_POINTER(sjme_lpcstr
,
53 (*env
)->CallObjectMethod(env
, self
, nameFunc
));
54 if (sjme_jni_checkVMException(env
))
55 return SJME_ERROR_JNI_EXCEPTION
;
57 /* Nothing needs to be done here... */
58 return SJME_ERROR_NONE
;
61 sjme_errorCode
sjme_jni_virtualLibrary_rawData(
62 sjme_attrInNotNull sjme_rom_library inLibrary
,
63 sjme_attrOutNotNullBuf(length
) void* dest
,
64 sjme_attrInPositive sjme_jint srcPos
,
65 sjme_attrInPositive sjme_jint length
)
70 jmethodID rawDataFunc
;
75 if (inLibrary
== NULL
)
76 return SJME_ERROR_NULL_ARGUMENTS
;
78 if (srcPos
< 0 || length
< 0)
79 return SJME_ERROR_INDEX_OUT_OF_BOUNDS
;
83 error
= SJME_ERROR_UNKNOWN
;
85 /* Get env and object back. */
86 env
= inLibrary
->cache
.common
.frontEnd
.data
;
87 self
= inLibrary
->cache
.common
.frontEnd
.wrapper
;
88 classy
= (*env
)->GetObjectClass(env
, self
);
90 /* It is much faster to use NIO for this! */
91 nioBuf
= (*env
)->NewDirectByteBuffer(env
, dest
, length
);
92 if (sjme_jni_checkVMException(env
))
94 error
= SJME_ERROR_JNI_EXCEPTION
;
95 goto fail_cleanupNioBuf
;
98 /* Find the raw data function. */
99 rawDataFunc
= (*env
)->GetMethodID(env
, classy
,
100 "__rawData", "(ILjava/nio/ByteBuffer;)V");
101 if (sjme_jni_checkVMException(env
))
103 error
= SJME_ERROR_JNI_EXCEPTION
;
104 goto fail_cleanupNioBuf
;
107 /* Call function accordingly. */
108 (*env
)->CallVoidMethod(env
, self
, rawDataFunc
, srcPos
, nioBuf
);
109 if (sjme_jni_checkVMException(env
))
111 error
= SJME_ERROR_JNI_EXCEPTION
;
112 goto fail_cleanupNioBuf
;
116 error
= SJME_ERROR_NONE
;
118 /* Cleanup NIO, just in case. */
122 (*env
)->DeleteLocalRef(env
, nioBuf
);
123 if (sjme_jni_checkVMException(env
))
124 return SJME_ERROR_JNI_EXCEPTION
;
127 /* Return whatever error state. */
131 sjme_errorCode
sjme_jni_virtualLibrary_rawSize(
132 sjme_attrInNotNull sjme_rom_library inLibrary
,
133 sjme_attrOutNotNull sjme_jint
* outSize
)
138 jmethodID rawSizeFunc
;
141 if (inLibrary
== NULL
|| outSize
== NULL
)
142 return SJME_ERROR_NULL_ARGUMENTS
;
144 /* Get env and object back. */
145 env
= inLibrary
->cache
.common
.frontEnd
.data
;
146 self
= inLibrary
->cache
.common
.frontEnd
.wrapper
;
147 classy
= (*env
)->GetObjectClass(env
, self
);
149 /* Find the raw size function. */
150 rawSizeFunc
= (*env
)->GetMethodID(env
, classy
, "__rawSize", "()I");
151 if (sjme_jni_checkVMException(env
))
152 return SJME_ERROR_JNI_EXCEPTION
;
154 /* Ask for the raw size of the given library. */
155 result
= (*env
)->CallIntMethod(env
, self
, rawSizeFunc
);
156 if (sjme_jni_checkVMException(env
))
157 return SJME_ERROR_JNI_EXCEPTION
;
159 /* Store result and success! */
161 return SJME_ERROR_NONE
;
164 static sjme_errorCode
sjme_jni_virtualLibrary_resourceStream(
165 sjme_attrInNotNull sjme_rom_library inLibrary
,
166 sjme_attrOutNotNull sjme_stream_input
* outStream
,
167 sjme_attrInNotNull sjme_lpcstr resourceName
)
169 if (inLibrary
== NULL
|| outStream
== NULL
|| resourceName
== NULL
)
170 return SJME_ERROR_NULL_ARGUMENTS
;
172 sjme_todo("Implement this.");
173 return SJME_ERROR_NONE
;
176 /** Functions for JNI accessed libraries. */
177 static const sjme_rom_libraryFunctions sjme_jni_virtualLibrary_functions
=
179 .init
= sjme_jni_virtualLibrary_init
,
181 .rawData
= sjme_jni_virtualLibrary_rawData
,
182 .rawSize
= sjme_jni_virtualLibrary_rawSize
,
183 .resourceStream
= sjme_jni_virtualLibrary_resourceStream
,
186 jlong
SJME_JNI_METHOD(SJME_CLASS_VIRTUAL_LIBRARY
, _1_1init
)
187 (JNIEnv
* env
, jclass classy
, jobject self
, jlong suitePtr
, jstring libName
)
189 sjme_rom_suite suite
;
190 sjme_alloc_pool
* pool
;
191 sjme_rom_library result
;
192 sjme_errorCode error
;
193 sjme_frontEnd frontEnd
;
194 sjme_lpcstr libNameChars
;
195 jboolean libNameCopy
;
197 /* Get the original owning suite among other details. */
198 suite
= SJME_JLONG_TO_POINTER(sjme_rom_suite
, suitePtr
);
199 pool
= suite
->cache
.common
.allocPool
;
201 /* Seed front end data. */
202 memset(&frontEnd
, 0, sizeof(frontEnd
));
204 frontEnd
.wrapper
= SJME_FRONT_END_WRAP(
205 (*env
)->NewGlobalRef(env
, self
));
207 /* Get library name. */
208 libNameCopy
= JNI_FALSE
;
209 libNameChars
= (*env
)->GetStringUTFChars(env
, libName
, &libNameCopy
);
211 /* Setup resultant library. */
213 if (sjme_error_is(error
= sjme_rom_libraryNew(pool
,
214 &result
, libNameChars
, NULL
,
215 &sjme_jni_virtualLibrary_functions
,
216 &frontEnd
)) || result
== NULL
)
218 (*env
)->ReleaseStringUTFChars(env
, libName
, libNameChars
);
220 sjme_jni_throwVMException(env
, error
);
224 (*env
)->ReleaseStringUTFChars(env
, libName
, libNameChars
);
227 return SJME_POINTER_TO_JLONG(result
);