common.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #include "codecs.h"
  3. #include <util/ysaveload.h>
  4. #include <util/stream/null.h>
  5. #include <util/stream/mem.h>
  6. #include <util/string/cast.h>
  7. #include <util/string/join.h>
  8. #include <util/system/align.h>
  9. #include <util/system/unaligned_mem.h>
  10. #include <util/generic/hash.h>
  11. #include <util/generic/cast.h>
  12. #include <util/generic/buffer.h>
  13. #include <util/generic/array_ref.h>
  14. #include <util/generic/singleton.h>
  15. #include <util/generic/algorithm.h>
  16. #include <util/generic/mem_copy.h>
  17. namespace NBlockCodecs {
  18. struct TDecompressError: public TDataError {
  19. TDecompressError(int code) {
  20. *this << "cannot decompress (errcode " << code << ")";
  21. }
  22. TDecompressError(size_t exp, size_t real) {
  23. *this << "broken input (expected len: " << exp << ", got: " << real << ")";
  24. }
  25. };
  26. struct TCompressError: public TDataError {
  27. TCompressError(int code) {
  28. *this << "cannot compress (errcode " << code << ")";
  29. }
  30. };
  31. struct TNullCodec: public ICodec {
  32. size_t DecompressedLength(const TData& in) const override {
  33. return in.size();
  34. }
  35. size_t MaxCompressedLength(const TData& in) const override {
  36. return in.size();
  37. }
  38. size_t Compress(const TData& in, void* out) const override {
  39. MemCopy((char*)out, in.data(), in.size());
  40. return in.size();
  41. }
  42. size_t Decompress(const TData& in, void* out) const override {
  43. MemCopy((char*)out, in.data(), in.size());
  44. return in.size();
  45. }
  46. TStringBuf Name() const noexcept override {
  47. return TStringBuf("null");
  48. }
  49. };
  50. template <class T>
  51. struct TAddLengthCodec: public ICodec {
  52. static inline void Check(const TData& in) {
  53. if (in.size() < sizeof(ui64)) {
  54. ythrow TDataError() << "too small input";
  55. }
  56. }
  57. size_t DecompressedLength(const TData& in) const override {
  58. Check(in);
  59. return ReadUnaligned<ui64>(in.data());
  60. }
  61. size_t MaxCompressedLength(const TData& in) const override {
  62. return T::DoMaxCompressedLength(in.size()) + sizeof(ui64);
  63. }
  64. size_t Compress(const TData& in, void* out) const override {
  65. ui64* ptr = (ui64*)out;
  66. WriteUnaligned<ui64>(ptr, (ui64) in.size());
  67. return Base()->DoCompress(!in ? TData(TStringBuf("")) : in, ptr + 1) + sizeof(*ptr);
  68. }
  69. size_t Decompress(const TData& in, void* out) const override {
  70. Check(in);
  71. const auto len = ReadUnaligned<ui64>(in.data());
  72. if (!len)
  73. return 0;
  74. Base()->DoDecompress(TData(in).Skip(sizeof(len)), out, len);
  75. return len;
  76. }
  77. inline const T* Base() const noexcept {
  78. return static_cast<const T*>(this);
  79. }
  80. };
  81. }