Remove duplicated headers.
[portableproplib.git] / src / prop_zlib.c
blob0c4db3d17cd64584a90d91b4500e469092b7fd7f
1 /*-
2 * Copyright (c) 2010, 2011 Juan Romero Pardines.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include <prop/proplib.h>
27 #include "prop_object_impl.h"
29 #include <errno.h>
30 #include <zlib.h>
32 #define _READ_CHUNK 512
34 #define TEMPLATE(type) \
35 bool \
36 prop ## type ## _externalize_to_zfile(prop ## type ## _t obj, const char *fname) \
37 { \
38 char *xml; \
39 bool rv; \
40 int save_errno = 0; \
42 xml = prop ## type ## _externalize(obj); \
43 if (xml == NULL) \
44 return false; \
45 rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true); \
46 if (rv == false) \
47 save_errno = errno; \
48 _PROP_FREE(xml, M_TEMP); \
49 if (rv == false) \
50 errno = save_errno; \
52 return rv; \
53 } \
55 prop ## type ## _t \
56 prop ## type ## _internalize_from_zfile(const char *fname) \
57 { \
58 struct _prop_object_internalize_mapped_file *mf; \
59 prop ## type ## _t obj; \
60 z_stream strm; \
61 unsigned char out[_READ_CHUNK]; \
62 char *uncomp_xml = NULL; \
63 size_t have; \
64 ssize_t totalsize = 0; \
65 int rv = 0; \
67 mf = _prop_object_internalize_map_file(fname); \
68 if (mf == NULL) \
69 return NULL; \
71 /* Decompress the mmap'ed buffer with zlib */ \
72 strm.zalloc = Z_NULL; \
73 strm.zfree = Z_NULL; \
74 strm.opaque = Z_NULL; \
75 strm.avail_in = 0; \
76 strm.next_in = Z_NULL; \
78 /* 15+16 to use gzip method */ \
79 if (inflateInit2(&strm, 15+16) != Z_OK) { \
80 _prop_object_internalize_unmap_file(mf); \
81 return NULL; \
82 } \
83 strm.avail_in = mf->poimf_mapsize; \
84 strm.next_in = (unsigned char *)mf->poimf_xml; \
86 /* Output buffer (uncompressed) */ \
87 uncomp_xml = _PROP_MALLOC(_READ_CHUNK, M_TEMP); \
88 if (uncomp_xml == NULL) { \
89 (void)inflateEnd(&strm); \
90 _prop_object_internalize_unmap_file(mf); \
91 return NULL; \
92 } \
94 /* Inflate the input buffer and copy into 'uncomp_xml' */ \
95 do { \
96 strm.avail_out = _READ_CHUNK; \
97 strm.next_out = out; \
98 rv = inflate(&strm, Z_NO_FLUSH); \
99 switch (rv) { \
100 case Z_DATA_ERROR: \
101 /* Wrong compressed data or uncompressed, try normal method. */ \
102 (void)inflateEnd(&strm); \
103 _PROP_FREE(uncomp_xml, M_TEMP); \
104 obj = prop ## type ## _internalize(mf->poimf_xml); \
105 _prop_object_internalize_unmap_file(mf); \
106 return obj; \
107 case Z_STREAM_ERROR: \
108 case Z_NEED_DICT: \
109 case Z_MEM_ERROR: \
110 (void)inflateEnd(&strm); \
111 _PROP_FREE(uncomp_xml, M_TEMP); \
112 _prop_object_internalize_unmap_file(mf); \
113 errno = rv; \
114 return NULL; \
116 have = _READ_CHUNK - strm.avail_out; \
117 totalsize += have; \
118 uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP); \
119 memcpy(uncomp_xml + totalsize - have, out, have); \
120 } while (strm.avail_out == 0); \
122 /* we are done */ \
123 (void)inflateEnd(&strm); \
124 obj = prop ## type ## _internalize(uncomp_xml); \
125 _PROP_FREE(uncomp_xml, M_TEMP); \
126 _prop_object_internalize_unmap_file(mf); \
128 return obj; \
131 TEMPLATE(_array)
132 TEMPLATE(_dictionary)
134 #undef TEMPLATE