| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_STORAGE_BLOBFS_COMPRESSION_CHUNKED_H_ |
| #define SRC_STORAGE_BLOBFS_COMPRESSION_CHUNKED_H_ |
| |
| #include <lib/zx/status.h> |
| #include <zircon/types.h> |
| |
| #include <memory> |
| #include <optional> |
| |
| #include <src/lib/chunked-compression/chunked-decompressor.h> |
| #include <src/lib/chunked-compression/streaming-chunked-compressor.h> |
| |
| #include "src/storage/blobfs/compression-settings.h" |
| #include "src/storage/blobfs/compression/compressor.h" |
| #include "src/storage/blobfs/compression/decompressor.h" |
| #include "src/storage/blobfs/compression/seekable-decompressor.h" |
| #include "src/storage/blobfs/format.h" |
| |
| namespace blobfs { |
| |
| // Implementation of |Compressor| backed by the "chunked-compression" library |
| // (//src/lib/chunked-compression). |
| class ChunkedCompressor : public Compressor { |
| public: |
| ChunkedCompressor() = delete; |
| ~ChunkedCompressor() = default; |
| DISALLOW_COPY_ASSIGN_AND_MOVE(ChunkedCompressor); |
| |
| static uint32_t InodeHeaderCompressionFlags() { return kBlobFlagChunkCompressed; } |
| |
| static zx_status_t Create(CompressionSettings settings, size_t input_size, |
| size_t* output_limit_out, std::unique_ptr<ChunkedCompressor>* out); |
| |
| // Registers |dst| as the output for compression. |
| // Must be called before |Update()| or |End()| are called. |
| zx_status_t SetOutput(void* dst, size_t dst_len); |
| |
| // Returns an upper bound on the size of the buffer required to store the compressed |
| // representation of a blob of size `input_length`. |
| static size_t BufferMax(size_t input_length); |
| |
| //////////////////////////////////////// |
| // Compressor interface |
| size_t Size() const final; |
| zx_status_t Update(const void* input_data, size_t input_length) final; |
| zx_status_t End() final; |
| |
| size_t GetChunkSize() const override { return compressor_.params().chunk_size; } |
| |
| private: |
| explicit ChunkedCompressor(chunked_compression::StreamingChunkedCompressor compressor, |
| size_t input_len); |
| |
| chunked_compression::StreamingChunkedCompressor compressor_; |
| size_t input_len_; |
| // Set when End() is called to the final output size. |
| std::optional<size_t> compressed_size_; |
| }; |
| |
| // Implementation of |Decompressor| backed by the "chunked-compression" library |
| // (//src/lib/chunked-compression). |
| class ChunkedDecompressor : public Decompressor { |
| public: |
| ChunkedDecompressor() = default; |
| DISALLOW_COPY_ASSIGN_AND_MOVE(ChunkedDecompressor); |
| |
| // Decompressor implementation. |
| zx_status_t Decompress(void* uncompressed_buf, size_t* uncompressed_size, |
| const void* compressed_buf, const size_t max_compressed_size) final; |
| |
| private: |
| chunked_compression::ChunkedDecompressor decompressor_; |
| }; |
| |
| // Implementation of |SeekableDecompressor| backed by the "chunked-compression" library |
| // (//src/lib/chunked-compression). |
| class SeekableChunkedDecompressor : public SeekableDecompressor { |
| public: |
| SeekableChunkedDecompressor() = default; |
| DISALLOW_COPY_ASSIGN_AND_MOVE(SeekableChunkedDecompressor); |
| |
| // |max_seek_table_size| and |max_compressed_size| are used for validation purposes only. |
| // |seek_table_buf| should be at least |max_seek_table_size|. |
| static zx_status_t CreateDecompressor(const void* seek_table_buf, size_t max_seek_table_size, |
| size_t max_compressed_size, |
| std::unique_ptr<SeekableDecompressor>* out); |
| |
| // SeekableDecompressor implementation. |
| zx_status_t DecompressRange(void* uncompressed_buf, size_t* uncompressed_size, |
| const void* compressed_buf, size_t max_compressed_size, |
| size_t offset) final; |
| |
| zx::status<CompressionMapping> MappingForDecompressedRange(size_t offset, size_t len, |
| size_t max_decompressed_len) final; |
| |
| CompressionAlgorithm algorithm() const final { return CompressionAlgorithm::CHUNKED; }; |
| |
| private: |
| chunked_compression::SeekTable seek_table_; |
| chunked_compression::ChunkedDecompressor decompressor_; |
| }; |
| |
| } // namespace blobfs |
| |
| #endif // SRC_STORAGE_BLOBFS_COMPRESSION_CHUNKED_H_ |