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/stream.h"
13 #include "sjme/alloc.h"
14 #include "sjme/util.h"
15 #include "sjme/inflate.h"
18 * Inflation initializer state.
22 typedef struct sjme_stream_inflateInit
26 } sjme_stream_inflateInit
;
28 static sjme_errorCode
sjme_stream_inputInflateClose(
29 sjme_attrInNotNull sjme_stream_input stream
,
30 sjme_attrInNotNull sjme_stream_implState
* inImplState
)
35 if (stream
== NULL
|| inImplState
== NULL
)
36 return SJME_ERROR_NULL_ARGUMENTS
;
38 /* Do nothing if already closed. */
39 state
= inImplState
->handle
;
41 return SJME_ERROR_NONE
;
44 if (sjme_error_is(error
= sjme_inflate_destroy(state
)))
45 return sjme_error_default(error
);
47 /* The state is now not valid. */
48 inImplState
->handle
= NULL
;
51 return SJME_ERROR_NONE
;
54 static sjme_errorCode
sjme_stream_inputInflateInit(
55 sjme_attrInNotNull sjme_stream_input stream
,
56 sjme_attrInNotNull sjme_stream_implState
* inImplState
,
57 sjme_attrInNullable sjme_pointer data
)
59 sjme_stream_inflateInit
* init
;
62 if (stream
== NULL
|| inImplState
== NULL
|| init
== NULL
)
63 return SJME_ERROR_NULL_ARGUMENTS
;
66 inImplState
->handle
= init
->handle
;
69 return SJME_ERROR_NONE
;
72 static sjme_errorCode
sjme_stream_inputInflateRead(
73 sjme_attrInNotNull sjme_stream_input stream
,
74 sjme_attrInNotNull sjme_stream_implState
* inImplState
,
75 sjme_attrOutNotNull sjme_attrOutNegativeOnePositive sjme_jint
* readCount
,
76 sjme_attrOutNotNullBuf(length
) sjme_pointer dest
,
77 sjme_attrInPositive sjme_jint length
)
80 sjme_inflate
* inState
;
83 if (stream
== NULL
|| inImplState
== NULL
|| readCount
== NULL
||
85 return SJME_ERROR_NULL_ARGUMENTS
;
88 return SJME_ERROR_INDEX_OUT_OF_BOUNDS
;
90 /* Recover state, fail if closed. */
91 inState
= inImplState
->handle
;
93 return SJME_ERROR_ILLEGAL_STATE
;
95 /* Request inflated data. */
99 if (sjme_error_is(error
= sjme_inflate_inflate(inState
,
100 &count
, dest
, length
)) || count
== INT32_MAX
)
101 return sjme_error_default(error
);
102 } while (count
== 0);
106 return SJME_ERROR_NONE
;
109 /** Input deflate functions. */
110 static const sjme_stream_inputFunctions sjme_stream_inputInflateFunctions
=
112 .close
= sjme_stream_inputInflateClose
,
113 .init
= sjme_stream_inputInflateInit
,
114 .read
= sjme_stream_inputInflateRead
,
117 sjme_errorCode
sjme_stream_inputOpenInflate(
118 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
119 sjme_attrOutNotNull sjme_stream_input
* outStream
,
120 sjme_attrInNotNull sjme_stream_input inCompressed
)
122 sjme_errorCode error
;
123 sjme_stream_input result
;
124 sjme_stream_inflateInit init
;
127 if (inPool
== NULL
|| outStream
== NULL
|| inCompressed
== NULL
)
128 return SJME_ERROR_NULL_ARGUMENTS
;
130 /* Setup decompression state data. */
132 if (sjme_error_is(error
= sjme_inflate_new(inPool
,
133 &state
, inCompressed
)) || state
== NULL
)
134 goto fail_inflateNew
;
136 /* Set initialization data. */
137 memset(&init
, 0, sizeof(init
));
140 /* Setup sub-stream. */
142 if (sjme_error_is(error
= sjme_stream_inputOpen(inPool
,
143 &result
, &sjme_stream_inputInflateFunctions
,
144 &init
, NULL
)) || result
== NULL
)
149 return SJME_ERROR_NONE
;
153 sjme_closeable_close(SJME_AS_CLOSEABLE(result
));
157 sjme_inflate_destroy(state
);
159 return sjme_error_default(error
);