| 197 | | static wi_boolean_t _wi_p7_socket_configure_compression_streams(wi_p7_socket_t *); |
|---|
| 198 | | static wi_integer_t _wi_p7_socket_xcompress_buffer(wi_p7_socket_t *, _wi_p7_socket_compression_t, const void *, uint32_t); |
|---|
| 199 | | static int _wi_p7_socket_xflate_buffer(z_stream *, _wi_p7_socket_compression_t, const void *, uint32_t, uint32_t *, void *, uint32_t *); |
|---|
| | 195 | static wi_integer_t _wi_p7_socket_deflate(wi_p7_socket_t *, const void *, uint32_t); |
|---|
| | 196 | static wi_integer_t _wi_p7_socket_inflate(wi_p7_socket_t *, const void *, uint32_t); |
|---|
| 1305 | | static wi_boolean_t _wi_p7_socket_configure_compression_streams(wi_p7_socket_t *p7_socket) { |
|---|
| 1306 | | int err; |
|---|
| 1307 | | |
|---|
| 1308 | | err = deflateInit(&p7_socket->compression_stream, Z_DEFAULT_COMPRESSION); |
|---|
| | 1309 | static wi_integer_t _wi_p7_socket_deflate(wi_p7_socket_t *p7_socket, const void *in_buffer, uint32_t in_size) { |
|---|
| | 1310 | z_stream stream; |
|---|
| | 1311 | int err, enderr; |
|---|
| | 1312 | |
|---|
| | 1313 | p7_socket->compression_buffer_length = (in_size * 2) + 16; |
|---|
| | 1314 | |
|---|
| | 1315 | if(!p7_socket->compression_buffer) |
|---|
| | 1316 | p7_socket->compression_buffer = wi_malloc(p7_socket->compression_buffer_length); |
|---|
| | 1317 | else |
|---|
| | 1318 | p7_socket->compression_buffer = wi_realloc(p7_socket->compression_buffer, p7_socket->compression_buffer_length); |
|---|
| | 1319 | |
|---|
| | 1320 | stream.data_type = Z_UNKNOWN; |
|---|
| | 1321 | stream.zalloc = Z_NULL; |
|---|
| | 1322 | stream.zfree = Z_NULL; |
|---|
| | 1323 | stream.opaque = Z_NULL; |
|---|
| | 1324 | stream.next_in = (unsigned char *) in_buffer; |
|---|
| | 1325 | stream.avail_in = in_size; |
|---|
| | 1326 | stream.next_out = p7_socket->compression_buffer; |
|---|
| | 1327 | stream.avail_out = p7_socket->compression_buffer_length; |
|---|
| | 1328 | |
|---|
| | 1329 | err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); |
|---|
| 1321 | | return false; |
|---|
| 1322 | | } |
|---|
| 1323 | | |
|---|
| 1324 | | p7_socket->compression_enabled = true; |
|---|
| 1325 | | |
|---|
| 1326 | | return true; |
|---|
| 1327 | | } |
|---|
| 1328 | | |
|---|
| 1329 | | |
|---|
| 1330 | | |
|---|
| 1331 | | static wi_integer_t _wi_p7_socket_xcompress_buffer(wi_p7_socket_t *p7_socket, _wi_p7_socket_compression_t compression, const void *in_buffer, uint32_t in_size) { |
|---|
| 1332 | | const void *input; |
|---|
| 1333 | | void *output; |
|---|
| 1334 | | z_stream *stream; |
|---|
| 1335 | | uint32_t offset, input_size, input_processed, output_size, total_size; |
|---|
| 1336 | | int err; |
|---|
| 1337 | | |
|---|
| 1338 | | if(!p7_socket->compression_buffer) { |
|---|
| 1339 | | p7_socket->compression_buffer_length = in_size * 4; |
|---|
| 1340 | | p7_socket->compression_buffer = wi_malloc(p7_socket->compression_buffer_length); |
|---|
| 1341 | | } |
|---|
| 1342 | | else if(in_size > p7_socket->compression_buffer_length) { |
|---|
| 1343 | | p7_socket->compression_buffer_length = in_size * 4; |
|---|
| 1344 | | p7_socket->compression_buffer = wi_realloc(p7_socket->compression_buffer, p7_socket->compression_buffer_length); |
|---|
| 1345 | | } |
|---|
| 1346 | | |
|---|
| 1347 | | stream = (compression == _WI_P7_SOCKET_COMPRESS) ? &p7_socket->compression_stream : &p7_socket->decompression_stream; |
|---|
| 1348 | | input = in_buffer; |
|---|
| 1349 | | input_size = in_size; |
|---|
| 1350 | | output = p7_socket->compression_buffer; |
|---|
| 1351 | | output_size = p7_socket->compression_buffer_length; |
|---|
| 1352 | | total_size = 0; |
|---|
| 1353 | | |
|---|
| 1354 | | while(true) { |
|---|
| 1355 | | err = _wi_p7_socket_xflate_buffer(stream, compression, input, input_size, &input_processed, output, &output_size); |
|---|
| | 1352 | return -1; |
|---|
| | 1353 | } |
|---|
| | 1354 | |
|---|
| | 1355 | return stream.total_out; |
|---|
| | 1356 | } |
|---|
| | 1357 | |
|---|
| | 1358 | |
|---|
| | 1359 | |
|---|
| | 1360 | static wi_integer_t _wi_p7_socket_inflate(wi_p7_socket_t *p7_socket, const void *in_buffer, uint32_t in_size) { |
|---|
| | 1361 | z_stream stream; |
|---|
| | 1362 | wi_uinteger_t multiple; |
|---|
| | 1363 | int err, enderr; |
|---|
| | 1364 | |
|---|
| | 1365 | for(multiple = 2; multiple < 16; multiple++) { |
|---|
| | 1366 | p7_socket->compression_buffer_length = in_size * (1 << multiple); |
|---|
| | 1367 | |
|---|
| | 1368 | if(!p7_socket->compression_buffer) |
|---|
| | 1369 | p7_socket->compression_buffer = wi_malloc(p7_socket->compression_buffer_length); |
|---|
| | 1370 | else |
|---|
| | 1371 | p7_socket->compression_buffer = wi_realloc(p7_socket->compression_buffer, p7_socket->compression_buffer_length); |
|---|
| | 1372 | |
|---|
| | 1373 | stream.zalloc = Z_NULL; |
|---|
| | 1374 | stream.zfree = Z_NULL; |
|---|
| | 1375 | stream.next_in = (unsigned char *) in_buffer; |
|---|
| | 1376 | stream.avail_in = in_size; |
|---|
| | 1377 | stream.next_out = (unsigned char *) p7_socket->compression_buffer; |
|---|
| | 1378 | stream.avail_out = p7_socket->compression_buffer_length; |
|---|
| | 1379 | |
|---|
| | 1380 | err = inflateInit(&stream); |
|---|
| 1363 | | total_size += output_size; |
|---|
| 1364 | | |
|---|
| 1365 | | if(stream->avail_out > 0) |
|---|
| 1366 | | break; |
|---|
| 1367 | | |
|---|
| 1368 | | p7_socket->compression_buffer_length *= 4; |
|---|
| 1369 | | p7_socket->compression_buffer = wi_realloc(p7_socket->compression_buffer, p7_socket->compression_buffer_length); |
|---|
| 1370 | | |
|---|
| 1371 | | offset = (output - p7_socket->compression_buffer) + output_size; |
|---|
| 1372 | | output = p7_socket->compression_buffer + offset; |
|---|
| 1373 | | output_size = p7_socket->compression_buffer_length - offset; |
|---|
| 1374 | | input += input_processed; |
|---|
| 1375 | | input_size -= input_processed; |
|---|
| 1376 | | |
|---|
| 1377 | | if(compression == _WI_P7_SOCKET_DECOMPRESS && input_size == 0) |
|---|
| 1378 | | break; |
|---|
| 1379 | | } |
|---|
| 1380 | | |
|---|
| 1381 | | return total_size; |
|---|
| 1382 | | } |
|---|
| 1383 | | |
|---|
| 1384 | | |
|---|
| 1385 | | |
|---|
| 1386 | | static int _wi_p7_socket_xflate_buffer(z_stream *stream, _wi_p7_socket_compression_t compression, const void *input, uint32_t input_size, uint32_t *input_processed, void *output, uint32_t *output_size) { |
|---|
| 1387 | | int err; |
|---|
| 1388 | | |
|---|
| 1389 | | stream->next_in = (Bytef *) input; |
|---|
| 1390 | | stream->avail_in = input_size; |
|---|
| 1391 | | stream->total_in = 0; |
|---|
| 1392 | | |
|---|
| 1393 | | stream->next_out = output; |
|---|
| 1394 | | stream->avail_out = *output_size; |
|---|
| 1395 | | stream->total_out = 0; |
|---|
| 1396 | | |
|---|
| 1397 | | if(compression == _WI_P7_SOCKET_COMPRESS) |
|---|
| 1398 | | err = deflate(stream, Z_SYNC_FLUSH); |
|---|
| 1399 | | else |
|---|
| 1400 | | err = inflate(stream, Z_SYNC_FLUSH); |
|---|
| 1401 | | |
|---|
| 1402 | | if(err == Z_OK) { |
|---|
| 1403 | | *input_processed = stream->total_in; |
|---|
| 1404 | | *output_size = stream->total_out; |
|---|
| 1405 | | } |
|---|
| 1406 | | |
|---|
| 1407 | | return err; |
|---|
| | 1388 | err = inflate(&stream, Z_FINISH); |
|---|
| | 1389 | enderr = inflateEnd(&stream); |
|---|
| | 1390 | |
|---|
| | 1391 | if(err == Z_STREAM_END) { |
|---|
| | 1392 | if(enderr != Z_BUF_ERROR) |
|---|
| | 1393 | break; |
|---|
| | 1394 | } |
|---|
| | 1395 | else if(err == Z_OK) { |
|---|
| | 1396 | err = Z_BUF_ERROR; |
|---|
| | 1397 | } |
|---|
| | 1398 | } |
|---|
| | 1399 | |
|---|
| | 1400 | return stream.total_out; |
|---|