2 * Copyright (c) 2010, 2011 Juan Romero Pardines.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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"
32 #define _READ_CHUNK 512
34 #define TEMPLATE(type) \
36 prop ## type ## _externalize_to_zfile(prop ## type ## _t obj, const char *fname) \
42 xml = prop ## type ## _externalize(obj); \
45 rv = _prop_object_externalize_write_file(fname, xml, strlen(xml), true); \
48 _PROP_FREE(xml, M_TEMP); \
56 prop ## type ## _internalize_from_zfile(const char *fname) \
58 struct _prop_object_internalize_mapped_file *mf; \
59 prop ## type ## _t obj; \
61 unsigned char out[_READ_CHUNK]; \
62 char *uncomp_xml = NULL; \
64 ssize_t totalsize = 0; \
67 mf = _prop_object_internalize_map_file(fname); \
71 /* Decompress the mmap'ed buffer with zlib */ \
72 strm.zalloc = Z_NULL; \
73 strm.zfree = Z_NULL; \
74 strm.opaque = Z_NULL; \
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); \
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); \
94 /* Inflate the input buffer and copy into 'uncomp_xml' */ \
96 strm.avail_out = _READ_CHUNK; \
97 strm.next_out = out; \
98 rv = inflate(&strm, Z_NO_FLUSH); \
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); \
107 case Z_STREAM_ERROR: \
110 (void)inflateEnd(&strm); \
111 _PROP_FREE(uncomp_xml, M_TEMP); \
112 _prop_object_internalize_unmap_file(mf); \
116 have = _READ_CHUNK - strm.avail_out; \
118 uncomp_xml = _PROP_REALLOC(uncomp_xml, totalsize, M_TEMP); \
119 memcpy(uncomp_xml + totalsize - have, out, have); \
120 } while (strm.avail_out == 0); \
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); \
132 TEMPLATE(_dictionary
)