Compile fixes.
[SquirrelJME.git] / nanocoat / frontend / emulator / nativeVirtualLibrary.c
blobe47a1d81a18a760a76f08cc36a0ffb9c46025afe
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 <jni.h>
11 #include <string.h>
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)
23 JNIEnv* env;
24 jobject self;
25 jclass classy;
26 jmethodID idFunc;
27 jmethodID nameFunc;
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");
41 /* Debug. */
42 sjme_message("env: %p, self: %p, selfClass: %p, idFunc: %p, "
43 "nameFunc: %p\n",
44 env, self, classy, idFunc, nameFunc);
46 /* Pre-seed ID. */
47 inLibrary->id = (*env)->CallIntMethod(env, self, idFunc, classy);
48 if (sjme_jni_checkVMException(env))
49 return SJME_ERROR_JNI_EXCEPTION;
51 /* Pre-seed name. */
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)
67 JNIEnv* env;
68 jobject self;
69 jclass classy;
70 jmethodID rawDataFunc;
71 jint result;
72 jobject nioBuf;
73 sjme_errorCode error;
75 if (inLibrary == NULL)
76 return SJME_ERROR_NULL_ARGUMENTS;
78 if (srcPos < 0 || length < 0)
79 return SJME_ERROR_INDEX_OUT_OF_BOUNDS;
81 /* Initial setup. */
82 nioBuf = NULL;
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;
115 /* Success! */
116 error = SJME_ERROR_NONE;
118 /* Cleanup NIO, just in case. */
119 fail_cleanupNioBuf:
120 if (nioBuf != NULL)
122 (*env)->DeleteLocalRef(env, nioBuf);
123 if (sjme_jni_checkVMException(env))
124 return SJME_ERROR_JNI_EXCEPTION;
127 /* Return whatever error state. */
128 return error;
131 sjme_errorCode sjme_jni_virtualLibrary_rawSize(
132 sjme_attrInNotNull sjme_rom_library inLibrary,
133 sjme_attrOutNotNull sjme_jint* outSize)
135 JNIEnv* env;
136 jobject self;
137 jclass classy;
138 jmethodID rawSizeFunc;
139 jint result;
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! */
160 *outSize = result;
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,
180 .path = NULL,
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));
203 frontEnd.data = env;
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. */
212 result = NULL;
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);
221 return 0;
224 (*env)->ReleaseStringUTFChars(env, libName, libNameChars);
226 /* Success! */
227 return SJME_POINTER_TO_JLONG(result);