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 "sjme/alloc.h"
14 #include "sjme/debug.h"
15 #include "sjme/payload.h"
16 #include "sjme/romInternal.h"
17 #include "sjme/util.h"
19 #include "sjme/cleanup.h"
20 #include "sjme/listUtil.h"
22 static sjme_errorCode
sjme_rom_zipSuiteDefaultLaunch(
23 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
24 sjme_attrInNotNull sjme_rom_suite inSuite
,
25 sjme_attrOutNotNull sjme_lpstr
* outMainClass
,
26 sjme_attrOutNotNull sjme_list_sjme_lpstr
** outMainArgs
,
27 sjme_attrOutNotNull sjme_list_sjme_jint
** outById
,
28 sjme_attrOutNotNull sjme_list_sjme_lpstr
** outByName
)
33 sjme_zip_entry zipEntry
;
34 sjme_stream_input inputStream
;
36 sjme_cchar buf
[BUF_SIZE
];
38 sjme_list_sjme_lpstr
* strings
;
39 sjme_list_sjme_jint
* ints
;
41 if (inPool
== NULL
|| inSuite
== NULL
|| outMainClass
== NULL
||
42 outMainArgs
== NULL
|| outById
== NULL
|| outByName
== NULL
)
43 return SJME_ERROR_NULL_ARGUMENTS
;
46 zip
= inSuite
->handle
;
48 /* These are available from three entries essentially */
50 memset(&zipEntry
, 0, sizeof(zipEntry
));
51 if (!sjme_error_is(sjme_zip_locateEntry(zip
,
52 &zipEntry
, "SQUIRRELJME.SQC/launcher.main")))
56 if (sjme_error_is(error
= sjme_zip_entryRead(&zipEntry
,
57 &inputStream
)) || inputStream
== NULL
)
58 return sjme_error_default(error
);
60 /* Read everything in. */
61 memset(buf
, 0, sizeof(buf
));
63 if (sjme_error_is(error
= sjme_stream_inputReadFully(
65 buf
, BUF_SIZE
- 1)) || valid
== INT32_MAX
)
66 return sjme_error_default(error
);
68 /* Strip ending whitespace. */
69 if (sjme_error_is(error
= sjme_util_lpstrTrimEnd(buf
,
71 return sjme_error_default(error
);
73 /* Duplicate main class. */
75 if (sjme_error_is(error
= sjme_alloc_strdup(
76 inPool
, &str
, (sjme_lpcstr
)&buf
[0])) || str
== NULL
)
77 return sjme_error_default(error
);
83 if (sjme_error_is(error
= sjme_closeable_close(
84 SJME_AS_CLOSEABLE(inputStream
))))
85 return sjme_error_default(error
);
89 memset(&zipEntry
, 0, sizeof(zipEntry
));
90 if (!sjme_error_is(sjme_zip_locateEntry(zip
,
91 &zipEntry
, "SQUIRRELJME.SQC/launcher.args")))
95 if (sjme_error_is(error
= sjme_zip_entryRead(&zipEntry
,
96 &inputStream
)) || inputStream
== NULL
)
97 return sjme_error_default(error
);
99 /* Read everything in. */
101 if (sjme_error_is(error
= sjme_listUtil_stringsFromStream(
102 inPool
, &strings
, -1, inputStream
)) ||
104 return sjme_error_default(error
);
107 *outMainArgs
= strings
;
110 if (sjme_error_is(error
= sjme_closeable_close(
111 SJME_AS_CLOSEABLE(inputStream
))))
112 return sjme_error_default(error
);
116 memset(&zipEntry
, 0, sizeof(zipEntry
));
117 if (!sjme_error_is(sjme_zip_locateEntry(zip
,
118 &zipEntry
, "SQUIRRELJME.SQC/launcher.path")))
122 if (sjme_error_is(error
= sjme_zip_entryRead(&zipEntry
,
123 &inputStream
)) || inputStream
== NULL
)
124 return sjme_error_default(error
);
126 /* Read everything in. */
128 if (sjme_error_is(error
= sjme_listUtil_intStringsFromStream(
129 inPool
, &ints
, -1, inputStream
)) ||
131 return sjme_error_default(error
);
137 if (sjme_error_is(error
= sjme_closeable_close(
138 SJME_AS_CLOSEABLE(inputStream
))))
139 return sjme_error_default(error
);
143 return SJME_ERROR_NONE
;
147 static sjme_errorCode
sjme_rom_zipSuiteInit(
148 sjme_attrInNotNull sjme_rom_suite inSuite
,
149 sjme_attrInNullable sjme_pointer data
)
152 return SJME_ERROR_NULL_ARGUMENTS
;
154 /* Set handle, which is the Zip itself. */
155 inSuite
->handle
= data
;
158 return SJME_ERROR_NONE
;
161 static sjme_errorCode
sjme_rom_zipSuiteLibraryId(
162 sjme_attrInNotNull sjme_rom_suite inSuite
,
163 sjme_attrInNotNull sjme_rom_library inLibrary
,
164 sjme_attrOutNotNull sjme_jint
* outId
)
166 if (inSuite
== NULL
|| inLibrary
== NULL
|| outId
== NULL
)
167 return SJME_ERROR_NULL_ARGUMENTS
;
170 return sjme_error_notImplemented(0);
173 static sjme_errorCode
sjme_rom_zipSuiteListLibraries(
174 sjme_attrInNotNull sjme_rom_suite inSuite
,
175 sjme_attrOutNotNull sjme_list_sjme_rom_library
** outLibraries
)
177 if (inSuite
== NULL
|| outLibraries
== NULL
)
178 return SJME_ERROR_NULL_ARGUMENTS
;
181 return sjme_error_notImplemented(0);
184 static sjme_errorCode
sjme_rom_zipSuiteLoadLibrary()
187 return sjme_error_notImplemented(0);
190 /** Functions for Zip based suites. */
191 static sjme_rom_suiteFunctions sjme_rom_zipSuiteFunctions
=
193 .defaultLaunch
= sjme_rom_zipSuiteDefaultLaunch
,
194 .init
= sjme_rom_zipSuiteInit
,
195 .libraryId
= sjme_rom_zipSuiteLibraryId
,
196 .list
= sjme_rom_zipSuiteListLibraries
,
197 .loadLibrary
= sjme_rom_zipSuiteLoadLibrary
,
200 sjme_errorCode
sjme_rom_suiteFromZipSeekable(
201 sjme_attrInNotNull sjme_alloc_pool
* pool
,
202 sjme_attrOutNotNull sjme_rom_suite
* outSuite
,
203 sjme_attrInNotNull sjme_seekable seekable
)
205 sjme_errorCode error
;
207 sjme_rom_suite result
;
209 if (pool
== NULL
|| outSuite
== NULL
|| seekable
== NULL
)
210 return SJME_ERROR_NULL_ARGUMENTS
;
212 /* Try opening as a Zip file. */
214 if (sjme_error_is(error
= sjme_zip_openSeekable(pool
, &zip
,
215 seekable
)) || zip
== NULL
)
216 return sjme_error_default(error
);
218 /* Setup new suite. */
220 if (sjme_error_is(error
= sjme_rom_suiteNew(pool
,
222 &sjme_rom_zipSuiteFunctions
, NULL
)) ||
226 /* Count up Zip as we are using it. */
227 if (sjme_error_is(error
= sjme_alloc_weakRef(zip
, NULL
)))
232 return SJME_ERROR_NONE
;
236 /* Close the zip before failing. */
237 sjme_closeable_close(SJME_AS_CLOSEABLE(zip
));
239 return sjme_error_default(error
);