libpurple/protocols/gg/lib/deflate.c

branch
release-2.x.y
changeset 35627
fd11790cc4d6
parent 31828
906428efd520
equal deleted inserted replaced
35625:783e5cce1a46 35627:fd11790cc4d6
26 26
27 #include <stdlib.h> 27 #include <stdlib.h>
28 #include <string.h> 28 #include <string.h>
29 29
30 #include "libgadu.h" 30 #include "libgadu.h"
31 #include "internal.h"
31 #include "deflate.h" 32 #include "deflate.h"
32 33
33 #ifdef GG_CONFIG_HAVE_ZLIB 34 #ifdef GG_CONFIG_HAVE_ZLIB
34 #include <zlib.h> 35 #include <zlib.h>
35 #endif 36 #endif
36 37
37 /** 38 /**
38 * \internal Kompresuje dane wejściowe algorytmem Deflate z najwyższym 39 * \internal Kompresuje dane wejściowe algorytmem Deflate z najwyższym
39 * stopniem kompresji, tak samo jak oryginalny klient. 40 * stopniem kompresji, tak samo jak oryginalny klient.
40 * 41 *
41 * Wynik funkcji należy zwolnić za pomocą \c free. 42 * Wynik funkcji należy zwolnić za pomocą \c free.
42 * 43 *
43 * \param in Ciąg znaków do skompresowania, zakończony \c \\0 44 * \param in Ciąg znaków do skompresowania, zakończony \c \\0
44 * \param out_lenp Wskaźnik na zmienną, do której zostanie zapisana 45 * \param out_lenp Wskaźnik na zmienną, do której zostanie zapisana
45 * długość bufora wynikowego 46 * długość bufora wynikowego
71 72
72 out_len = deflateBound(&strm, strm.avail_in); 73 out_len = deflateBound(&strm, strm.avail_in);
73 out = malloc(out_len); 74 out = malloc(out_len);
74 75
75 if (out == NULL) { 76 if (out == NULL) {
76 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for output data (%d)\n", out_len); 77 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for "
78 "output data (%" GG_SIZE_FMT ")\n", out_len);
77 goto fail; 79 goto fail;
78 } 80 }
79 81
80 strm.avail_out = out_len; 82 strm.avail_out = out_len;
81 strm.next_out = out; 83 strm.next_out = out;
82 84
83 for (;;) { 85 for (;;) {
84 ret = deflate(&strm, Z_FINISH); 86 ret = deflate(&strm, Z_FINISH);
85 87
86 if (ret == Z_STREAM_END) 88 if (ret == Z_STREAM_END)
87 break; 89 break;
88 90
89 /* raczej nie powinno się zdarzyć przy Z_FINISH i out_len == deflateBound(), 91 /* raczej nie powinno się zdarzyć przy Z_FINISH i out_len == deflateBound(),
90 * ale dokumentacja zlib nie wyklucza takiej możliwości */ 92 * ale dokumentacja zlib nie wyklucza takiej możliwości */
91 if (ret == Z_OK) { 93 if (ret == Z_OK) {
92 out_len *= 2; 94 out_len *= 2;
93 out2 = realloc(out, out_len); 95 out2 = realloc(out, out_len);
94 96
95 if (out2 == NULL) { 97 if (out2 == NULL) {
96 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for output data (%d)\n", out_len); 98 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not "
99 "enough memory for output data (%"
100 GG_SIZE_FMT ")\n", out_len);
97 goto fail; 101 goto fail;
98 } 102 }
99 103
100 out = out2; 104 out = out2;
101 105
102 strm.avail_out = out_len / 2; 106 strm.avail_out = out_len / 2;
103 strm.next_out = out + out_len / 2; 107 strm.next_out = out + out_len / 2;
104 } else { 108 } else {
105 gg_debug(GG_DEBUG_MISC, "// gg_deflate() deflate() failed (ret=%d, msg=%s)\n", ret, strm.msg != NULL ? strm.msg : "no error message provided"); 109 gg_debug(GG_DEBUG_MISC, "// gg_deflate() deflate() "
110 "failed (ret=%d, msg=%s)\n", ret,
111 strm.msg != NULL ? strm.msg :
112 "no error message provided");
106 goto fail; 113 goto fail;
107 } 114 }
108 } 115 }
109 116
110 out_len = strm.total_out; 117 out_len = strm.total_out;
111 out2 = realloc(out, out_len); 118 out2 = realloc(out, out_len);
112 119
113 if (out2 == NULL) { 120 if (out2 == NULL) {
114 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for output data (%d)\n", out_len); 121 gg_debug(GG_DEBUG_MISC, "// gg_deflate() not enough memory for "
122 "output data (%" GG_SIZE_FMT ")\n", out_len);
115 goto fail; 123 goto fail;
116 } 124 }
117 125
118 *out_lenp = out_len; 126 *out_lenp = out_len;
119 deflateEnd(&strm); 127 deflateEnd(&strm);
166 } 174 }
167 175
168 do { 176 do {
169 out_len *= 2; 177 out_len *= 2;
170 out2 = realloc(out, out_len); 178 out2 = realloc(out, out_len);
171 179
172 if (out2 == NULL) { 180 if (out2 == NULL) {
173 gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough memory for output data (%d)\n", out_len); 181 gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough "
182 "memory for output data (%" GG_SIZE_FMT ")\n", out_len);
174 goto fail; 183 goto fail;
175 } 184 }
176 185
177 out = out2; 186 out = out2;
178 187
179 if (first) { 188 if (first) {
180 strm.avail_out = out_len; 189 strm.avail_out = out_len;
181 strm.next_out = (unsigned char*) out; 190 strm.next_out = (unsigned char*) out;
182 } else { 191 } else {
183 strm.avail_out = out_len / 2; 192 strm.avail_out = out_len / 2;
184 strm.next_out = (unsigned char*) out + out_len / 2; 193 strm.next_out = (unsigned char*) out + out_len / 2;
185 } 194 }
186 195
187 ret = inflate(&strm, Z_NO_FLUSH); 196 ret = inflate(&strm, Z_NO_FLUSH);
188 197
189 if (ret != Z_OK && ret != Z_STREAM_END) { 198 if (ret != Z_OK && ret != Z_STREAM_END) {
190 gg_debug(GG_DEBUG_MISC, "// gg_inflate() inflate() failed (ret=%d, msg=%s)\n", ret, strm.msg != NULL ? strm.msg : "no error message provided"); 199 gg_debug(GG_DEBUG_MISC, "// gg_inflate() inflate() "
200 "failed (ret=%d, msg=%s)\n", ret,
201 strm.msg != NULL ? strm.msg :
202 "no error message provided");
191 goto fail; 203 goto fail;
192 } 204 }
193 205
194 first = 0; 206 first = 0;
195 } while (ret != Z_STREAM_END); 207 } while (ret != Z_STREAM_END);
196 208
197 /* rezerwujemy ostatni znak na NULL-a */ 209 /* rezerwujemy ostatni znak na NULL-a */
198 out_len = strm.total_out + 1; 210 out_len = strm.total_out + 1;
199 out2 = realloc(out, out_len); 211 out2 = realloc(out, out_len);
200 212
201 if (out2 == NULL) { 213 if (out2 == NULL) {
202 gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough memory for output data (%d)\n", out_len); 214 gg_debug(GG_DEBUG_MISC, "// gg_inflate() not enough memory for "
215 "output data (%" GG_SIZE_FMT ")\n", out_len);
203 goto fail; 216 goto fail;
204 } 217 }
205 218
206 out = out2; 219 out = out2;
207 out[out_len - 1] = '\0'; 220 out[out_len - 1] = '\0';
214 inflateEnd(&strm); 227 inflateEnd(&strm);
215 free(out); 228 free(out);
216 #endif 229 #endif
217 return NULL; 230 return NULL;
218 } 231 }
219

mercurial