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. */
97 if (sjme_error_is(error
= sjme_inflate_inflate(inState
,
98 &count
, dest
, length
)) || count
== INT32_MAX
)
99 return sjme_error_default(error
);
103 return SJME_ERROR_NONE
;
106 /** Input deflate functions. */
107 static const sjme_stream_inputFunctions sjme_stream_inputInflateFunctions
=
109 .close
= sjme_stream_inputInflateClose
,
110 .init
= sjme_stream_inputInflateInit
,
111 .read
= sjme_stream_inputInflateRead
,
114 sjme_errorCode
sjme_stream_inputOpenInflate(
115 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
116 sjme_attrOutNotNull sjme_stream_input
* outStream
,
117 sjme_attrInNotNull sjme_stream_input inCompressed
)
119 sjme_errorCode error
;
120 sjme_stream_input result
;
121 sjme_stream_inflateInit init
;
124 if (inPool
== NULL
|| outStream
== NULL
|| inCompressed
== NULL
)
125 return SJME_ERROR_NULL_ARGUMENTS
;
127 /* Setup decompression state data. */
129 if (sjme_error_is(error
= sjme_inflate_new(inPool
,
130 &state
, inCompressed
)) || state
== NULL
)
131 goto fail_inflateNew
;
133 /* Set initialization data. */
134 memset(&init
, 0, sizeof(init
));
137 /* Setup sub-stream. */
139 if (sjme_error_is(error
= sjme_stream_inputOpen(inPool
,
140 &result
, &sjme_stream_inputInflateFunctions
,
141 &init
, NULL
)) || result
== NULL
)
146 return SJME_ERROR_NONE
;
150 sjme_closeable_close(SJME_AS_CLOSEABLE(result
));
154 sjme_inflate_destroy(state
);
156 return sjme_error_default(error
);