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 // -------------------------------------------------------------------------*/
10 #include "sjme/cleanup.h"
11 #include "sjme/nvm/rom.h"
12 #include "sjme/nvm/stringPool.h"
13 #include "sjme/nvm/classy.h"
16 #define SJME_CLEANUP_FREE(w) \
17 do { if ((w) != NULL) \
19 if (sjme_error_is(error = sjme_alloc_free((w)))) \
20 return sjme_error_default(error); \
26 #define SJME_CLEANUP_CLOSE(x) \
27 do { if ((x) != NULL) \
29 if (sjme_error_is(error = sjme_closeable_close( \
30 SJME_AS_CLOSEABLE((x))))) \
31 return sjme_error_default(error); \
36 /** Cleanup of list. */
37 #define SJME_CLEANUP_LIST(y) \
38 do { if ((y) != NULL) \
40 for (i = 0, n = (y)->length; i < n; i++) \
41 SJME_CLEANUP_CLOSE((y)->elements[i]); \
43 SJME_CLEANUP_FREE(y); \
46 static sjme_errorCode
sjme_class_classInfoClose(
47 sjme_attrInNotNull sjme_closeable closeable
)
54 info
= (sjme_class_info
)closeable
;
56 return SJME_ERROR_NULL_ARGUMENTS
;
58 SJME_CLEANUP_CLOSE(info
->pool
);
59 SJME_CLEANUP_CLOSE(info
->name
);
60 SJME_CLEANUP_CLOSE(info
->superName
);
61 SJME_CLEANUP_LIST(info
->interfaceNames
);
62 SJME_CLEANUP_LIST(info
->fields
);
63 SJME_CLEANUP_LIST(info
->methods
);
66 return SJME_ERROR_NONE
;
69 static sjme_errorCode
sjme_class_constantPoolClose(
70 sjme_attrInNotNull sjme_closeable closeable
)
73 sjme_class_poolInfo info
;
74 sjme_class_poolEntry
* entry
;
78 info
= (sjme_class_poolInfo
)closeable
;
80 return SJME_ERROR_NULL_ARGUMENTS
;
82 /* Cleanup any pool entries. */
83 if (info
->pool
!= NULL
)
84 for (i
= 0, n
= info
->pool
->length
; i
< n
; i
++)
86 entry
= &info
->pool
->elements
[i
];
89 case SJME_CLASS_POOL_TYPE_UTF
:
90 SJME_CLEANUP_CLOSE(entry
->utf
.utf
);
93 case SJME_CLASS_POOL_TYPE_CLASS
:
94 SJME_CLEANUP_CLOSE(entry
->classRef
.descriptor
);
97 case SJME_CLASS_POOL_TYPE_STRING
:
98 SJME_CLEANUP_CLOSE(entry
->constString
.value
);
101 case SJME_CLASS_POOL_TYPE_NAME_AND_TYPE
:
102 SJME_CLEANUP_CLOSE(entry
->nameAndType
.descriptor
);
103 SJME_CLEANUP_CLOSE(entry
->nameAndType
.name
);
109 SJME_CLEANUP_FREE(info
->pool
);
112 return SJME_ERROR_NONE
;
115 static sjme_errorCode
sjme_class_fieldInfoClose(
116 sjme_attrInNotNull sjme_closeable closeable
)
118 sjme_errorCode error
;
119 sjme_class_fieldInfo info
;
123 info
= (sjme_class_fieldInfo
)closeable
;
125 return SJME_ERROR_NULL_ARGUMENTS
;
127 SJME_CLEANUP_CLOSE(info
->inClass
);
128 SJME_CLEANUP_CLOSE(info
->name
);
129 SJME_CLEANUP_CLOSE(info
->type
);
132 return SJME_ERROR_NONE
;
135 static sjme_errorCode
sjme_class_methodInfoClose(
136 sjme_attrInNotNull sjme_closeable closeable
)
138 sjme_errorCode error
;
139 sjme_class_methodInfo info
;
143 info
= (sjme_class_methodInfo
)closeable
;
145 return SJME_ERROR_NULL_ARGUMENTS
;
147 SJME_CLEANUP_CLOSE(info
->inClass
);
148 SJME_CLEANUP_CLOSE(info
->name
);
149 SJME_CLEANUP_CLOSE(info
->type
);
150 SJME_CLEANUP_CLOSE(info
->code
);
153 return SJME_ERROR_NONE
;
156 static sjme_errorCode
sjme_desc_identifierClose(
157 sjme_attrInNotNull sjme_closeable closeable
)
159 sjme_errorCode error
;
160 sjme_desc_identifier info
;
163 info
= (sjme_desc_identifier
)closeable
;
165 return SJME_ERROR_NULL_ARGUMENTS
;
167 SJME_CLEANUP_CLOSE(info
->whole
);
170 return SJME_ERROR_NONE
;
173 static sjme_errorCode
sjme_rom_libraryClose(
174 sjme_attrInNotNull sjme_closeable closeable
)
176 sjme_errorCode error
;
177 sjme_rom_library inLibrary
;
179 /* Recover library. */
180 inLibrary
= (sjme_rom_library
)closeable
;
181 if (inLibrary
== NULL
)
182 return SJME_ERROR_NULL_ARGUMENTS
;
184 /* Delete the prefix if there is one. */
185 if (inLibrary
->prefix
!= NULL
)
188 if (sjme_error_is(error
= sjme_alloc_free(
189 (sjme_pointer
)inLibrary
->prefix
)))
190 return sjme_error_default(error
);
193 inLibrary
->prefix
= NULL
;
196 /* Delete name if there is one. */
197 if (inLibrary
->name
!= NULL
)
200 if (sjme_error_is(error
= sjme_alloc_free(
201 (sjme_pointer
)inLibrary
->name
)))
202 return sjme_error_default(error
);
205 inLibrary
->name
= NULL
;
208 /* Forward close handler. */
209 if (inLibrary
->functions
->close
!= NULL
)
210 return inLibrary
->functions
->close(inLibrary
);
213 return SJME_ERROR_NONE
;
216 static sjme_errorCode
sjme_rom_suiteClose(
217 sjme_attrInNotNull sjme_closeable closeable
)
219 if (closeable
== NULL
)
220 return SJME_ERROR_NULL_ARGUMENTS
;
223 return sjme_error_notImplemented(0);
226 static sjme_errorCode
sjme_stringPool_close(
227 sjme_attrInNullable sjme_closeable closeable
)
229 sjme_errorCode error
;
230 sjme_stringPool stringPool
;
232 sjme_list_sjme_stringPool_string
* strings
;
233 sjme_stringPool_string target
;
236 stringPool
= (sjme_stringPool
)closeable
;
237 if (stringPool
== NULL
)
238 return SJME_ERROR_NULL_ARGUMENTS
;
240 /* Loaded string cleanup. */
241 strings
= stringPool
->strings
;
244 /* Close every contained string. */
245 for (i
= 0, n
= strings
->length
; i
< n
; i
++)
248 target
= strings
->elements
[i
];
252 /* Close individual string. */
253 if (sjme_error_is(error
= sjme_closeable_close(
254 SJME_AS_CLOSEABLE(target
))))
255 return sjme_error_default(error
);
258 strings
->elements
[i
] = NULL
;
262 if (sjme_error_is(error
= sjme_alloc_free(strings
)))
263 return sjme_error_default(error
);
268 stringPool
->inPool
= NULL
;
271 return SJME_ERROR_NONE
;
274 static sjme_errorCode
sjme_stringPool_stringClose(
275 sjme_attrInNotNull sjme_closeable closeable
)
277 sjme_errorCode error
;
278 sjme_stringPool_string info
;
281 info
= (sjme_stringPool_string
)closeable
;
283 return SJME_ERROR_NULL_ARGUMENTS
;
286 return SJME_ERROR_NONE
;
289 /* ------------------------------------------------------------------------ */
291 sjme_errorCode
sjme_nvm_allocR(
292 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
293 sjme_attrInPositiveNonZero sjme_jint allocSize
,
294 sjme_attrInValue sjme_nvm_structType inType
,
295 sjme_attrOutNotNull sjme_nvm_common
* outCommon
296 SJME_DEBUG_ONLY_COMMA SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL
)
298 sjme_errorCode error
;
299 sjme_closeable_closeHandlerFunc handler
;
300 sjme_nvm_common result
;
302 if (inPool
== NULL
|| outCommon
== NULL
)
303 return SJME_ERROR_NULL_ARGUMENTS
;
305 if (inType
<= SJME_NVM_STRUCT_UNKNOWN
||
306 inType
>= SJME_NVM_NUM_STRUCT
)
307 return SJME_ERROR_INVALID_ARGUMENT
;
309 /* Which handler is used? */
313 case SJME_NVM_STRUCT_CLASS_INFO
:
314 handler
= sjme_class_classInfoClose
;
317 case SJME_NVM_STRUCT_FIELD_INFO
:
318 handler
= sjme_class_fieldInfoClose
;
321 case SJME_NVM_STRUCT_IDENTIFIER
:
322 handler
= sjme_desc_identifierClose
;
325 case SJME_NVM_STRUCT_METHOD_INFO
:
326 handler
= sjme_class_methodInfoClose
;
329 case SJME_NVM_STRUCT_POOL
:
330 handler
= sjme_class_constantPoolClose
;
333 case SJME_NVM_STRUCT_ROM_LIBRARY
:
334 handler
= sjme_rom_libraryClose
;
337 case SJME_NVM_STRUCT_ROM_SUITE
:
338 handler
= sjme_rom_suiteClose
;
341 case SJME_NVM_STRUCT_STRING_POOL
:
342 handler
= sjme_stringPool_close
;
345 case SJME_NVM_STRUCT_STRING_POOL_STRING
:
346 handler
= sjme_stringPool_stringClose
;
350 sjme_todo("Impl? %d", inType
);
351 return sjme_error_notImplemented(0);
354 /* Allocate result. */
356 #if defined(SJME_CONFIG_DEBUG)
357 if (sjme_error_is(error
= sjme_closeable_allocR(inPool
,
358 allocSize
, handler
, SJME_JNI_TRUE
,
359 SJME_AS_CLOSEABLEP(&result
), file
, line
, func
)) ||
362 if (sjme_error_is(error
= sjme_closeable_alloc(inPool
,
363 allocSize
, handler
, SJME_JNI_TRUE
,
364 SJME_AS_CLOSEABLEP(&result
))) || result
== NULL
)
366 return sjme_error_default(error
);
369 result
->type
= inType
;
373 return SJME_ERROR_NONE
;