jlzma.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. // LZMA adapted for jlib
  14. #include "platform.h"
  15. #include "jlzma.hpp"
  16. #include "Types.h"
  17. #include "LzFind.h"
  18. #include "LzHash.h"
  19. #include "LzmaEnc.h"
  20. #include "LzmaDec.h"
  21. static void *SzAlloc(void *, size_t size)
  22. {
  23. return checked_malloc(size,-1);
  24. }
  25. static void SzFree(void *, void *address)
  26. {
  27. free(address);
  28. }
  29. static ISzAlloc g_Alloc = { SzAlloc, SzFree };
  30. class CLZMA
  31. {
  32. CLzmaEncHandle enc;
  33. CLzmaEncProps props;
  34. public:
  35. CLZMA()
  36. {
  37. enc = 0;
  38. }
  39. ~CLZMA()
  40. {
  41. if (enc)
  42. LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
  43. }
  44. size32_t compress(const void* input, size32_t inlength, void* output)
  45. { // returns (size32_t)-1 if cannot compress
  46. if (!enc) {
  47. enc = LzmaEnc_Create(&g_Alloc);
  48. if (enc == 0)
  49. throw MakeStringException(-1,"LzmaEnc_Create failed");
  50. LzmaEncProps_Init(&props);
  51. if (LzmaEnc_SetProps(enc, &props)!=SZ_OK)
  52. throw MakeStringException(-1,"LzmaEnc_SetProps failed");
  53. }
  54. if (inlength+LZMA_PROPS_SIZE+sizeof(size32_t)<1024)
  55. return (size32_t)-1; // don't compress less than 1K
  56. SizeT propsize = LZMA_PROPS_SIZE;
  57. LzmaEnc_WriteProperties(enc, (byte *)output+sizeof(size32_t), &propsize);
  58. *(size32_t *)output = (size32_t)propsize;
  59. SizeT reslen = inlength-1-propsize-sizeof(size32_t);
  60. SRes res = LzmaEnc_MemEncode(enc, (byte *)output+propsize+sizeof(size32_t), &reslen, (const byte *)input, inlength, true, NULL, &g_Alloc, &g_Alloc);
  61. if (res==SZ_ERROR_OUTPUT_EOF)
  62. return (size32_t)-1;
  63. if (res!=SZ_OK)
  64. throw MakeStringException(-1,"LzmaEnc_MemEncode failed(%d)",(int)res);
  65. return reslen+propsize+sizeof(size32_t);
  66. }
  67. size32_t expand(const void* input, size32_t inlength, void* output, size32_t maxout)
  68. {
  69. SizeT reslen = maxout;
  70. SizeT propsize = *(size32_t *)input;
  71. SizeT inlen = inlength -= sizeof(size32_t)+propsize;
  72. ELzmaStatus status;
  73. SRes res = LzmaDecode((byte *)output, &reslen, (const byte *)input+sizeof(size32_t)+propsize, &inlen,
  74. (byte *)input+sizeof(size32_t), propsize, LZMA_FINISH_END, &status, &g_Alloc);
  75. if (res!=SZ_OK)
  76. throw MakeStringException(-1,"LzmaDecode failed(%d)",(int)res);
  77. return reslen;
  78. }
  79. };
  80. void LZMACompressToBuffer(MemoryBuffer & out, size32_t len, const void * src)
  81. {
  82. CLZMA lzma;
  83. size32_t outbase = out.length();
  84. out.append(len);
  85. DelayedMarker<size32_t> cmpSzMarker(out);
  86. void *cmpData = out.reserve(len);
  87. size32_t sz = lzma.compress(src, len, cmpData);
  88. if (sz>len)
  89. {
  90. sz = len;
  91. memcpy(cmpData, src, len);
  92. }
  93. else
  94. out.setLength(outbase+sizeof(size32_t)*2+sz);
  95. cmpSzMarker.write(sz);
  96. }
  97. void LZMADecompressToBuffer(MemoryBuffer & out, const void * src)
  98. {
  99. size32_t *sz = (size32_t *)src;
  100. size32_t expsz = *(sz++);
  101. size32_t cmpsz = *(sz++);
  102. void *o = out.reserve(expsz);
  103. if (cmpsz!=expsz) {
  104. CLZMA lzma;
  105. size32_t written = lzma.expand(sz,cmpsz,o,expsz);
  106. if (written!=expsz)
  107. throw MakeStringException(0, "fastLZDecompressToBuffer - corrupt data(1) %d %d",written,expsz);
  108. }
  109. else
  110. memcpy(o,sz,expsz);
  111. }
  112. void LZMADecompressToBuffer(MemoryBuffer & out, MemoryBuffer & in)
  113. {
  114. size32_t expsz;
  115. size32_t cmpsz;
  116. in.read(expsz).read(cmpsz);
  117. void *o = out.reserve(expsz);
  118. if (cmpsz!=expsz) {
  119. CLZMA lzma;
  120. size32_t written = lzma.expand(in.readDirect(cmpsz),cmpsz,o,expsz);
  121. if (written!=expsz)
  122. throw MakeStringException(0, "fastLZDecompressToBuffer - corrupt data(3) %d %d",written,expsz);
  123. }
  124. else
  125. memcpy(o,in.readDirect(cmpsz),expsz);
  126. }
  127. void LZMADecompressToAttr(MemoryAttr & out, const void * src)
  128. {
  129. size32_t *sz = (size32_t *)src;
  130. size32_t expsz = *(sz++);
  131. size32_t cmpsz = *(sz++);
  132. void *o = out.allocate(expsz);
  133. if (cmpsz!=expsz) {
  134. CLZMA lzma;
  135. size32_t written = lzma.expand(sz,cmpsz,o,expsz);
  136. if (written!=expsz)
  137. throw MakeStringException(0, "fastLZDecompressToBuffer - corrupt data(2) %d %d",written,expsz);
  138. }
  139. else
  140. memcpy(o,sz,expsz);
  141. }
  142. void LZMALZDecompressToBuffer(MemoryAttr & out, MemoryBuffer & in)
  143. {
  144. size32_t expsz;
  145. size32_t cmpsz;
  146. in.read(expsz).read(cmpsz);
  147. void *o = out.allocate(expsz);
  148. if (cmpsz!=expsz) {
  149. CLZMA lzma;
  150. size32_t written = lzma.expand(in.readDirect(cmpsz),cmpsz,o,expsz);
  151. if (written!=expsz)
  152. throw MakeStringException(0, "fastLZDecompressToBuffer - corrupt data(4) %d %d",written,expsz);
  153. }
  154. else
  155. memcpy(o,in.readDirect(cmpsz),expsz);
  156. }