lzma.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include <library/cpp/blockcodecs/core/codecs.h>
  2. #include <library/cpp/blockcodecs/core/common.h>
  3. #include <library/cpp/blockcodecs/core/register.h>
  4. #include <contrib/libs/lzmasdk/LzmaLib.h>
  5. using namespace NBlockCodecs;
  6. namespace {
  7. struct TLzmaCodec: public TAddLengthCodec<TLzmaCodec> {
  8. inline TLzmaCodec(int level)
  9. : Level(level)
  10. , MyName("lzma-" + ToString(Level))
  11. {
  12. }
  13. static inline size_t DoMaxCompressedLength(size_t in) noexcept {
  14. return Max<size_t>(in + in / 20, 128) + LZMA_PROPS_SIZE;
  15. }
  16. TStringBuf Name() const noexcept override {
  17. return MyName;
  18. }
  19. inline size_t DoCompress(const TData& in, void* buf) const {
  20. unsigned char* props = (unsigned char*)buf;
  21. unsigned char* data = props + LZMA_PROPS_SIZE;
  22. size_t destLen = Max<size_t>();
  23. size_t outPropsSize = LZMA_PROPS_SIZE;
  24. const int ret = LzmaCompress(data, &destLen, (const unsigned char*)in.data(), in.size(), props, &outPropsSize, Level, 0, -1, -1, -1, -1, -1);
  25. if (ret != SZ_OK) {
  26. ythrow TCompressError(ret);
  27. }
  28. return destLen + LZMA_PROPS_SIZE;
  29. }
  30. inline void DoDecompress(const TData& in, void* out, size_t len) const {
  31. if (in.size() <= LZMA_PROPS_SIZE) {
  32. ythrow TDataError() << TStringBuf("broken lzma stream");
  33. }
  34. const unsigned char* props = (const unsigned char*)in.data();
  35. const unsigned char* data = props + LZMA_PROPS_SIZE;
  36. size_t destLen = len;
  37. SizeT srcLen = in.size() - LZMA_PROPS_SIZE;
  38. const int res = LzmaUncompress((unsigned char*)out, &destLen, data, &srcLen, props, LZMA_PROPS_SIZE);
  39. if (res != SZ_OK) {
  40. ythrow TDecompressError(res);
  41. }
  42. if (destLen != len) {
  43. ythrow TDecompressError(len, destLen);
  44. }
  45. }
  46. const int Level;
  47. const TString MyName;
  48. };
  49. struct TLzmaRegistrar {
  50. TLzmaRegistrar() {
  51. for (int i = 0; i < 10; ++i) {
  52. RegisterCodec(MakeHolder<TLzmaCodec>(i));
  53. }
  54. RegisterAlias("lzma", "lzma-5");
  55. }
  56. };
  57. const TLzmaRegistrar Registrar{};
  58. }