Add base for list utilities.
[SquirrelJME.git] / nanocoat / src / romSuiteZip.c
blobabf42f13d030c19748adb85fe055947403085424
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/rom.h"
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"
18 #include "sjme/zip.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)
30 #define BUF_SIZE 256
31 sjme_errorCode error;
32 sjme_zip zip;
33 sjme_zip_entry zipEntry;
34 sjme_stream_input inputStream;
35 sjme_jint valid;
36 sjme_cchar buf[BUF_SIZE];
37 sjme_lpstr str;
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;
45 /* Recover Zip. */
46 zip = inSuite->handle;
48 /* These are available from three entries essentially */
49 /* launcher.main */
50 memset(&zipEntry, 0, sizeof(zipEntry));
51 if (!sjme_error_is(sjme_zip_locateEntry(zip,
52 &zipEntry, "SQUIRRELJME.SQC/launcher.main")))
54 /* Open entry. */
55 inputStream = NULL;
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));
62 valid = INT32_MAX;
63 if (sjme_error_is(error = sjme_stream_inputReadFully(
64 inputStream, &valid,
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,
70 BUF_SIZE - 1)))
71 return sjme_error_default(error);
73 /* Duplicate main class. */
74 str = NULL;
75 if (sjme_error_is(error = sjme_alloc_strdup(
76 inPool, &str, (sjme_lpcstr)&buf[0])) || str == NULL)
77 return sjme_error_default(error);
79 /* Give it. */
80 *outMainClass = str;
82 /* Close. */
83 if (sjme_error_is(error = sjme_closeable_close(
84 SJME_AS_CLOSEABLE(inputStream))))
85 return sjme_error_default(error);
88 /* launcher.args */
89 memset(&zipEntry, 0, sizeof(zipEntry));
90 if (!sjme_error_is(sjme_zip_locateEntry(zip,
91 &zipEntry, "SQUIRRELJME.SQC/launcher.args")))
93 /* Open entry. */
94 inputStream = NULL;
95 if (sjme_error_is(error = sjme_zip_entryRead(&zipEntry,
96 &inputStream)) || inputStream == NULL)
97 return sjme_error_default(error);
99 /* Read everything in. */
100 strings = NULL;
101 if (sjme_error_is(error = sjme_listUtil_stringsFromStream(
102 inPool, &strings, -1, inputStream)) ||
103 strings == NULL)
104 return sjme_error_default(error);
106 /* Give it. */
107 *outMainArgs = strings;
109 /* Close. */
110 if (sjme_error_is(error = sjme_closeable_close(
111 SJME_AS_CLOSEABLE(inputStream))))
112 return sjme_error_default(error);
115 /* launcher.path */
116 memset(&zipEntry, 0, sizeof(zipEntry));
117 if (!sjme_error_is(sjme_zip_locateEntry(zip,
118 &zipEntry, "SQUIRRELJME.SQC/launcher.path")))
120 /* Open entry. */
121 inputStream = NULL;
122 if (sjme_error_is(error = sjme_zip_entryRead(&zipEntry,
123 &inputStream)) || inputStream == NULL)
124 return sjme_error_default(error);
126 /* Read everything in. */
127 ints = NULL;
128 if (sjme_error_is(error = sjme_listUtil_intStringsFromStream(
129 inPool, &ints, -1, inputStream)) ||
130 ints == NULL)
131 return sjme_error_default(error);
133 /* Give it. */
134 *outById = ints;
136 /* Close. */
137 if (sjme_error_is(error = sjme_closeable_close(
138 SJME_AS_CLOSEABLE(inputStream))))
139 return sjme_error_default(error);
142 /* Success! */
143 return SJME_ERROR_NONE;
144 #undef BUF_SIZE
147 static sjme_errorCode sjme_rom_zipSuiteInit(
148 sjme_attrInNotNull sjme_rom_suite inSuite,
149 sjme_attrInNullable sjme_pointer data)
151 if (inSuite == NULL)
152 return SJME_ERROR_NULL_ARGUMENTS;
154 /* Set handle, which is the Zip itself. */
155 inSuite->handle = data;
157 /* Success! */
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;
169 sjme_todo("Impl?");
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;
180 sjme_todo("Impl?");
181 return sjme_error_notImplemented(0);
184 static sjme_errorCode sjme_rom_zipSuiteLoadLibrary()
186 sjme_todo("Impl?");
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;
206 sjme_zip zip;
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. */
213 zip = NULL;
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. */
219 result = NULL;
220 if (sjme_error_is(error = sjme_rom_suiteNew(pool,
221 &result, zip,
222 &sjme_rom_zipSuiteFunctions, NULL)) ||
223 result == NULL)
224 goto fail_suiteNew;
226 /* Count up Zip as we are using it. */
227 if (sjme_error_is(error = sjme_alloc_weakRef(zip, NULL)))
228 goto fail_refUp;
230 /* Success! */
231 *outSuite = result;
232 return SJME_ERROR_NONE;
234 fail_refUp:
235 fail_suiteNew:
236 /* Close the zip before failing. */
237 sjme_closeable_close(SJME_AS_CLOSEABLE(zip));
239 return sjme_error_default(error);