blob: 741265427b0ff5c8521a7e2bdbcb141c05db96a3 [file] [log] [blame]
// 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_