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/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"
19 #include "sjme/cleanup.h"
21 sjme_errorCode
sjme_rom_resolveClassPathById(
22 sjme_attrInNotNull sjme_rom_suite inSuite
,
23 sjme_attrInNotNull
const sjme_list_sjme_jint
* inIds
,
24 sjme_attrOutNotNull sjme_list_sjme_rom_library
** outLibs
)
26 sjme_list_sjme_rom_library
* suiteLibs
;
28 sjme_jint length
, i
, numLibs
, at
, libId
;
29 sjme_rom_library
* working
;
30 sjme_rom_library checkLibrary
;
32 if (inSuite
== NULL
|| inIds
== NULL
|| outLibs
== NULL
)
33 return SJME_ERROR_NULL_ARGUMENTS
;
36 sjme_message("sjme_rom_resolveClassPathById(%p, %p, %p)",
37 inSuite
, inIds
, outLibs
);
39 /* How many are we looking for? */
40 length
= inIds
->length
;
42 return SJME_ERROR_INVALID_ARGUMENT
;
45 sjme_message("Looking for %d libraries...", length
);
47 /* Allocate temporary storage on the stack for the libraries we want. */
48 working
= sjme_alloca(sizeof(*working
) * length
);
50 return sjme_error_outOfMemory(NULL
, length
);
52 /* Make sure it is cleared. */
53 memset(working
, 0, sizeof(*working
) * length
);
56 sjme_message("Getting library list...");
58 /* Obtain the list of libraries within the suite. */
60 if (sjme_error_is(error
= sjme_rom_suiteLibraries(inSuite
,
61 &suiteLibs
)) || suiteLibs
== NULL
)
62 return sjme_error_default(error
);
65 sjme_message("Done: %p!", suiteLibs
);
66 sjme_message("Found %d libraries.", suiteLibs
->length
);
68 /* Go through and find the ones with matching IDs. */
69 /* Order by library because there is likely to be more of those. */
70 numLibs
= suiteLibs
->length
;
71 for (i
= 0; i
< numLibs
; i
++)
73 /* Which library is this? */
74 checkLibrary
= suiteLibs
->elements
[i
];
76 #if defined(SJME_CONFIG_DEBUG)
78 sjme_message("Looking at library #%d: %p",
82 /* Need to initialize the ID? */
83 libId
= checkLibrary
->id
;
87 if (inSuite
->functions
->libraryId
== NULL
)
88 return SJME_ERROR_ILLEGAL_STATE
;
90 /* Get the library ID. */
91 if (sjme_error_is(error
= inSuite
->functions
->libraryId(
92 inSuite
, checkLibrary
,
94 return sjme_error_default(error
);
96 /* Library ID function did not store it? */
97 if (checkLibrary
->id
== 0)
98 checkLibrary
->id
= libId
;
101 /* Scan through the requested classpath for matches. */
102 for (at
= 0; at
< length
; at
++)
103 if (inIds
->elements
[at
] == libId
)
105 working
[at
] = checkLibrary
;
110 /* Scan through and fail if any are null, that is not found. */
111 for (at
= 0; at
< length
; at
++)
112 if (working
[at
] == NULL
)
113 return SJME_ERROR_LIBRARY_NOT_FOUND
;
115 /* Return the libraries which gets placed into a list as a copy. */
116 return sjme_list_newA(inSuite
->cache
.common
.allocPool
,
117 sjme_rom_library
, 0, length
, outLibs
, working
);
120 sjme_errorCode
sjme_rom_resolveClassPathByName(
121 sjme_attrInNotNull sjme_rom_suite inSuite
,
122 sjme_attrInNotNull
const sjme_list_sjme_lpcstr
* inNames
,
123 sjme_attrOutNotNull sjme_list_sjme_rom_library
** outLibs
)
125 sjme_list_sjme_rom_library
* suiteLibs
;
126 sjme_errorCode error
;
127 sjme_jint length
, i
, at
, hash
, numSuiteLibs
;
128 sjme_rom_library
* working
;
129 sjme_rom_library lib
;
132 if (inSuite
== NULL
|| inNames
== NULL
|| outLibs
== NULL
)
133 return SJME_ERROR_NULL_ARGUMENTS
;
135 /* How many are we looking for? */
136 length
= inNames
->length
;
138 return SJME_ERROR_INVALID_ARGUMENT
;
140 /* Make sure there are no NULL libraries as input. */
141 for (i
= 0; i
< length
; i
++)
142 if (inNames
->elements
[i
] == NULL
)
143 return SJME_ERROR_NULL_ARGUMENTS
;
145 /* Allocate temporary storage on the stack for the libraries we want. */
146 working
= sjme_alloca(sizeof(*working
) * length
);
147 inHashes
= sjme_alloca(sizeof(*inHashes
) * length
);
148 if (working
== NULL
|| inHashes
== NULL
)
149 return sjme_error_outOfMemory(NULL
, length
);
152 memset(working
, 0, sizeof(*working
) * length
);
153 memset(inHashes
, 0, sizeof(*inHashes
) * length
);
155 /* First hash all the input libraries, so we can quickly scan through. */
156 for (i
= 0; i
< length
; i
++)
157 inHashes
[i
] = sjme_string_hash(inNames
->elements
[i
]);
159 /* Obtain the list of libraries within the suite. */
161 if (sjme_error_is(error
= sjme_rom_suiteLibraries(inSuite
,
162 &suiteLibs
) || suiteLibs
== NULL
))
163 return sjme_error_default(error
);
165 /* Go through each library and get hash matches. */
166 numSuiteLibs
= suiteLibs
->length
;
167 for (i
= 0; i
< numSuiteLibs
; i
++)
169 /* Get hash of this library. */
170 lib
= suiteLibs
->elements
[i
];
171 if (sjme_error_is(error
= sjme_rom_libraryHash(lib
,
173 return sjme_error_default(error
);
175 /* Look for match in output. */
176 for (at
= 0; at
< length
; at
++)
177 if (working
[at
] == NULL
&& inHashes
[at
] == hash
&&
178 0 == strcmp(inNames
->elements
[at
], lib
->name
))
182 /* Scan through and fail if any are null, that is not found. */
183 for (at
= 0; at
< length
; at
++)
184 if (working
[at
] == NULL
)
185 return SJME_ERROR_LIBRARY_NOT_FOUND
;
187 /* Return the libraries which gets placed into a list as a copy. */
188 return sjme_list_newA(inSuite
->cache
.common
.allocPool
,
189 sjme_rom_library
, 0, length
, outLibs
, working
);