_zlib.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "_zlib.h"
  2. #include "fastlz.h"
  3. Arg* _zlib_compress(PikaObj* self, Arg* data, int level) {
  4. if (arg_getType(data) != ARG_TYPE_BYTES) {
  5. obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
  6. obj_setSysOut(self, "TypeError: a bytes is required");
  7. return NULL;
  8. }
  9. Arg* aRet = NULL;
  10. uint8_t* input = arg_getBytes(data);
  11. size_t input_len = arg_getBytesSize(data);
  12. size_t max_output_len =
  13. input_len * 1.1 + 64; // Fastlz's maximum output size guideline
  14. uint8_t* ret = pikaMalloc(max_output_len);
  15. size_t ret_len = fastlz_compress_level(level, input, input_len, ret);
  16. if (ret_len == 0) {
  17. obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
  18. obj_setSysOut(self, "Compression failed");
  19. aRet = NULL;
  20. goto __exit;
  21. }
  22. aRet = arg_newBytes(ret, ret_len);
  23. goto __exit;
  24. __exit:
  25. pikaFree(ret, max_output_len);
  26. return aRet;
  27. }
  28. Arg* _zlib_decompress(PikaObj* self, Arg* data) {
  29. if (arg_getType(data) != ARG_TYPE_BYTES) {
  30. obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
  31. obj_setSysOut(self, "TypeError: a bytes is required");
  32. return NULL;
  33. }
  34. uint8_t* input = arg_getBytes(data);
  35. size_t input_len = arg_getBytesSize(data);
  36. size_t max_output_len =
  37. input_len * 4; // Assume the decompressed data is no more than 4 times
  38. // the input data
  39. size_t ret_len = 0;
  40. uint8_t* ret = NULL;
  41. Arg* aRet = NULL;
  42. int multiplier = 1;
  43. do {
  44. multiplier *= 2;
  45. max_output_len = input_len * multiplier;
  46. ret = pikaMalloc(max_output_len);
  47. ret_len = fastlz_decompress(input, input_len, ret, max_output_len);
  48. if (ret_len == 0) {
  49. pikaFree(ret, max_output_len);
  50. }
  51. } while (ret_len == 0 && multiplier <= 8);
  52. if (ret_len == 0) {
  53. obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
  54. obj_setSysOut(self, "Decompression failed");
  55. return NULL;
  56. }
  57. aRet = arg_newBytes(ret, ret_len);
  58. pikaFree(ret, max_output_len);
  59. return aRet;
  60. }