Cleanup and moving of NanoCoat VM specific headers to their own include directory...
[SquirrelJME.git] / nanocoat / src / romSuite.c
blob845388103e010151c9214775c6079f6cecbcb991
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/nvm/rom.h"
13 #include "sjme/alloc.h"
14 #include "sjme/debug.h"
15 #include "sjme/nvm/payload.h"
16 #include "sjme/nvm/romInternal.h"
17 #include "sjme/util.h"
18 #include "sjme/zip.h"
19 #include "sjme/cleanup.h"
21 static sjme_errorCode sjme_rom_suiteClose(
22 sjme_attrInNotNull sjme_closeable closeable)
24 if (closeable == NULL)
25 return SJME_ERROR_NULL_ARGUMENTS;
27 sjme_todo("Impl?");
28 return sjme_error_notImplemented(0);
31 sjme_errorCode sjme_rom_suiteDefaultLaunch(
32 sjme_attrInNotNull sjme_alloc_pool* inPool,
33 sjme_attrInNotNull sjme_rom_suite inSuite,
34 sjme_attrOutNotNull sjme_lpstr* outMainClass,
35 sjme_attrOutNotNull sjme_list_sjme_lpstr** outMainArgs,
36 sjme_attrOutNotNull sjme_list_sjme_jint** outById,
37 sjme_attrOutNotNull sjme_list_sjme_lpstr** outByName)
39 sjme_errorCode error;
41 if (inPool == NULL || inSuite == NULL || outMainClass == NULL ||
42 outMainArgs == NULL || outById == NULL || outByName == NULL)
43 return SJME_ERROR_NULL_ARGUMENTS;
45 /* Not supported internally? */
46 if (inSuite->functions->defaultLaunch == NULL)
47 return SJME_ERROR_UNSUPPORTED_OPERATION;
49 /* Lock suite. */
50 if (sjme_error_is(error = sjme_thread_spinLockGrab(
51 &inSuite->common.lock)))
52 return sjme_error_default(error);
54 /* Forward call. */
55 error = inSuite->functions->defaultLaunch(inPool,
56 inSuite, outMainClass, outMainArgs, outById, outByName);
58 /* Unlock suite. */
59 if (sjme_error_is(sjme_thread_spinLockRelease(
60 &inSuite->common.lock, NULL)))
61 return sjme_error_default(error);
63 /* Success? */
64 return error;
67 sjme_errorCode sjme_rom_suiteFromMerge(
68 sjme_attrInNotNull sjme_alloc_pool* pool,
69 sjme_attrOutNotNull sjme_rom_suite* outSuite,
70 sjme_attrInNotNull sjme_rom_suite* inSuites,
71 sjme_attrInPositive sjme_jint numInSuites)
73 if (pool == NULL || outSuite == NULL || inSuites == NULL)
74 return SJME_ERROR_NULL_ARGUMENTS;
76 if (numInSuites < 0)
77 return SJME_ERROR_INVALID_ARGUMENT;
79 sjme_todo("Implement this?");
80 return SJME_ERROR_UNKNOWN;
83 sjme_errorCode sjme_rom_suiteFromPayload(
84 sjme_attrInNotNull sjme_alloc_pool* pool,
85 sjme_attrOutNotNull sjme_rom_suite* outSuite,
86 sjme_attrInNotNull const sjme_payload_config* payloadConfig)
88 sjme_jint i, numActive, numLibraries;
90 if (pool == NULL || outSuite == NULL || payloadConfig == NULL)
91 return SJME_ERROR_NULL_ARGUMENTS;
93 /* Count the number of active ROMs. */
94 numActive = 0;
95 numLibraries = 0;
96 for (i = 0; i < SJME_NVM_PAYLOAD_MAX_ROMS; i++)
97 if (payloadConfig->roms[i].isActive)
99 /* Count up! */
100 numActive++;
102 /* Anything that is a library we need to build a container. */
103 if (payloadConfig->roms[i].isLibrary)
104 numLibraries++;
107 /* If there is nothing active then nothing needs to be done. */
108 if (numActive == 0)
110 *outSuite = NULL;
111 return SJME_ERROR_NONE;
114 sjme_todo("Implement this?");
115 return SJME_ERROR_UNKNOWN;
118 sjme_errorCode sjme_rom_suiteLibraries(
119 sjme_attrInNotNull sjme_rom_suite inSuite,
120 sjme_attrOutNotNull sjme_list_sjme_rom_library** outLibs)
122 sjme_rom_suiteCache* cache;
123 sjme_rom_suiteListLibrariesFunc listFunc;
124 sjme_list_sjme_rom_library* result;
125 sjme_errorCode error;
126 sjme_jint i, n;
128 if (inSuite == NULL || outLibs == NULL)
129 return SJME_ERROR_NULL_ARGUMENTS;
131 /* Must be a valid cache. */
132 cache = &inSuite->cache;
133 if (cache->common.allocPool == NULL)
134 return SJME_ERROR_ILLEGAL_STATE;
136 /* Has this been processed already? */
137 if (cache->libraries != NULL)
139 /* Debug. */
140 sjme_message("Using existing cache: %p", cache->libraries);
142 *outLibs = cache->libraries;
143 return SJME_ERROR_NONE;
146 /* Check list function. */
147 listFunc = inSuite->functions->list;
148 if (listFunc == NULL)
149 return SJME_ERROR_NOT_IMPLEMENTED;
151 /* Lock suite. */
152 if (sjme_error_is(error = sjme_thread_spinLockGrab(
153 &inSuite->common.lock)))
154 return sjme_error_default(error);
156 /* Call the list function. */
157 result = NULL;
158 if (sjme_error_is(error = listFunc(inSuite,
159 &result)) || result == NULL)
160 goto fail_list;
162 /* Store it within the cache. */
163 cache->libraries = result;
165 /* All of these must be valid libraries. */
166 for (i = 0, n = result->length; i < n; i++)
167 if (result->elements[i] == NULL)
169 error = SJME_ERROR_LIBRARY_NOT_FOUND;
170 goto fail_missingLib;
173 /* Unlock suite. */
174 if (sjme_error_is(error = sjme_thread_spinLockRelease(
175 &inSuite->common.lock, NULL)))
176 return sjme_error_default(error);
178 /* Success! */
179 *outLibs = result;
180 return SJME_ERROR_NONE;
182 fail_missingLib:
183 fail_list:
184 /* Release lock before failing. */
185 if (sjme_error_is(sjme_thread_spinLockRelease(
186 &inSuite->common.lock, NULL)))
187 return sjme_error_default(error);
189 return sjme_error_default(error);
192 sjme_errorCode sjme_rom_suiteNew(
193 sjme_attrInNotNull sjme_alloc_pool* pool,
194 sjme_attrOutNotNull sjme_rom_suite* outSuite,
195 sjme_attrInNullable sjme_pointer data,
196 sjme_attrInNotNull const sjme_rom_suiteFunctions* inFunctions,
197 sjme_attrInNullable const sjme_frontEnd* copyFrontEnd)
199 sjme_rom_suite result;
200 sjme_errorCode error;
202 if (pool == NULL || outSuite == NULL || inFunctions == NULL)
203 return SJME_ERROR_NULL_ARGUMENTS;
205 /* These functions are required. */
206 if (inFunctions->init == NULL ||
207 inFunctions->libraryId == NULL ||
208 inFunctions->list == NULL ||
209 inFunctions->loadLibrary == NULL)
210 return SJME_ERROR_NOT_IMPLEMENTED;
212 /* Allocate resultant suite. */
213 result = NULL;
214 if (sjme_error_is(error = sjme_alloc_weakNew(pool,
215 sizeof(*result),
216 sjme_nvm_enqueueHandler, SJME_NVM_ENQUEUE_IDENTITY,
217 (void**)&result, NULL)) || result == NULL)
218 goto fail_alloc;
220 /* Setup result. */
221 result->common.closeable.closeHandler = sjme_rom_suiteClose;
222 result->common.type = SJME_NVM_STRUCTTYPE_ROM_SUITE;
223 result->cache.common.allocPool = pool;
224 result->functions = inFunctions;
226 /* Copy front end data? */
227 if (copyFrontEnd != NULL)
228 memmove(&result->common.frontEnd, copyFrontEnd,
229 sizeof(*copyFrontEnd));
231 /* Call initializer. */
232 if (sjme_error_is(error = inFunctions->init(result, data)))
233 goto fail_init;
235 /* Success! */
236 *outSuite = result;
237 return SJME_ERROR_NONE;
239 fail_refUp:
240 fail_init:
241 fail_alloc:
242 if (result != NULL)
243 sjme_alloc_free(result);
245 return sjme_error_default(error);