bzip.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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/libbz2/bzlib.h>
  5. using namespace NBlockCodecs;
  6. namespace {
  7. struct TBZipCodec: public TAddLengthCodec<TBZipCodec> {
  8. inline TBZipCodec(int level)
  9. : Level(level)
  10. , MyName("bzip2-" + ToString(Level))
  11. {
  12. }
  13. static inline size_t DoMaxCompressedLength(size_t in) noexcept {
  14. // very strange
  15. return in * 2 + 128;
  16. }
  17. TStringBuf Name() const noexcept override {
  18. return MyName;
  19. }
  20. inline size_t DoCompress(const TData& in, void* buf) const {
  21. unsigned int ret = DoMaxCompressedLength(in.size());
  22. const int res = BZ2_bzBuffToBuffCompress((char*)buf, &ret, (char*)in.data(), in.size(), Level, 0, 0);
  23. if (res != BZ_OK) {
  24. ythrow TCompressError(res);
  25. }
  26. return ret;
  27. }
  28. inline void DoDecompress(const TData& in, void* out, size_t len) const {
  29. unsigned int tmp = SafeIntegerCast<unsigned int>(len);
  30. const int res = BZ2_bzBuffToBuffDecompress((char*)out, &tmp, (char*)in.data(), in.size(), 0, 0);
  31. if (res != BZ_OK) {
  32. ythrow TDecompressError(res);
  33. }
  34. if (len != tmp) {
  35. ythrow TDecompressError(len, tmp);
  36. }
  37. }
  38. const int Level;
  39. const TString MyName;
  40. };
  41. struct TBZipRegistrar {
  42. TBZipRegistrar() {
  43. for (int i = 1; i < 10; ++i) {
  44. RegisterCodec(MakeHolder<TBZipCodec>(i));
  45. }
  46. RegisterAlias("bzip2", "bzip2-6");
  47. }
  48. };
  49. const TBZipRegistrar Registrar{};
  50. }