brotli.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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/brotli/include/brotli/encode.h>
  5. #include <contrib/libs/brotli/include/brotli/decode.h>
  6. using namespace NBlockCodecs;
  7. namespace {
  8. struct TBrotliCodec : public TAddLengthCodec<TBrotliCodec> {
  9. static constexpr int BEST_QUALITY = 11;
  10. inline TBrotliCodec(ui32 level)
  11. : Quality(level)
  12. , MyName(TStringBuf("brotli_") + ToString(level))
  13. {
  14. }
  15. static inline size_t DoMaxCompressedLength(size_t l) noexcept {
  16. return BrotliEncoderMaxCompressedSize(l);
  17. }
  18. inline size_t DoCompress(const TData& in, void* out) const {
  19. size_t resultSize = MaxCompressedLength(in);
  20. auto result = BrotliEncoderCompress(
  21. /*quality*/ Quality,
  22. /*window*/ BROTLI_DEFAULT_WINDOW,
  23. /*mode*/ BrotliEncoderMode::BROTLI_MODE_GENERIC,
  24. /*input_size*/ in.size(),
  25. /*input_buffer*/ (const unsigned char*)(in.data()),
  26. /*encoded_size*/ &resultSize,
  27. /*encoded_buffer*/ static_cast<unsigned char*>(out));
  28. if (result != BROTLI_TRUE) {
  29. ythrow yexception() << "internal brotli error during compression";
  30. }
  31. return resultSize;
  32. }
  33. inline void DoDecompress(const TData& in, void* out, size_t dsize) const {
  34. size_t decoded = dsize;
  35. auto result = BrotliDecoderDecompress(in.size(), (const unsigned char*)in.data(), &decoded, static_cast<unsigned char*>(out));
  36. if (result != BROTLI_DECODER_RESULT_SUCCESS) {
  37. ythrow yexception() << "internal brotli error during decompression";
  38. } else if (decoded != dsize) {
  39. ythrow TDecompressError(dsize, decoded);
  40. }
  41. }
  42. TStringBuf Name() const noexcept override {
  43. return MyName;
  44. }
  45. const int Quality = BEST_QUALITY;
  46. const TString MyName;
  47. };
  48. struct TBrotliRegistrar {
  49. TBrotliRegistrar() {
  50. for (int i = 1; i <= TBrotliCodec::BEST_QUALITY; ++i) {
  51. RegisterCodec(MakeHolder<TBrotliCodec>(i));
  52. }
  53. }
  54. };
  55. const TBrotliRegistrar Registrar{};
  56. }