blob: 23471c19f409f43945647d3ab6ab64dbf663550f [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_VOLUME_IMAGE_UTILS_LZ4_DECOMPRESSOR_H_
#define SRC_STORAGE_VOLUME_IMAGE_UTILS_LZ4_DECOMPRESSOR_H_
#include <lib/fpromise/result.h>
#include <lib/stdcompat/span.h>
#include <string>
#include <vector>
#include <lz4/lz4frame.h>
#include "src/storage/volume_image/options.h"
#include "src/storage/volume_image/utils/decompressor.h"
namespace storage::volume_image {
// This class provides an implementation of |Decompressor| backed by LZ4 Decompression algorithm.
//
// This class is move construcable only.
class Lz4Decompressor final : public Decompressor {
public:
// Default size for the decompression buffer exposed to the decompression handler.
static constexpr uint64_t kDecompressionBufferSize = static_cast<uint64_t>(64 * (1u << 10));
// Returns a |Lz4Decompressor| on success.
//
// On failure, returns a string describing the error.
static fpromise::result<Lz4Decompressor, std::string> Create(
const CompressionOptions& options,
uint64_t decompression_buffer_size = kDecompressionBufferSize);
explicit Lz4Decompressor(uint64_t decompression_buffer_size = kDecompressionBufferSize) {
decompression_buffer_.resize(decompression_buffer_size, 0);
}
Lz4Decompressor(const Lz4Decompressor&) = delete;
Lz4Decompressor(Lz4Decompressor&&) noexcept = default;
Lz4Decompressor& operator=(const Lz4Decompressor&) = delete;
Lz4Decompressor& operator=(Lz4Decompressor&&) = delete;
~Lz4Decompressor() final;
// Returns |fpromise::ok| on success. Setting |handler| for consuming symbols emitted during
// decompression.
//
// On failure, returns a string decribing the error condition.
fpromise::result<void, std::string> Prepare(Handler handler) final;
// Returns |fpromise::ok| on success. When data has been fully decompressed, will return |true|,
// otherwise will return |false|.
//
// On failure, returns a string decribing the error condition.
fpromise::result<DecompressResult, std::string> Decompress(
cpp20::span<const uint8_t> compressed_data) final;
// Returns |fpromise::ok| on success. At this point all remaining symbols for the decompressed
// representation will be emitted.
//
// On failure, returns a string describing the error condition.
fpromise::result<void, std::string> Finalize() final;
// Provide size hint of the expected compressed content size.
void ProvideSizeHint(size_t size_hint);
private:
// Describes the possible states of the compressor.
enum class State {
// The Decompressor was created with valid options, yet it has not been prepared.
kInitalized,
// The compressor, has been prepared, and is ready for compressing data.
kPrepared,
// The compressor has at least decompressed a piece of data.
kDecompressed,
// The compressor finished compressing, and has deallocated the required structures.
kFinalized,
};
// LZ4 decompression context, that handles the LZ4 internals.
LZ4F_decompressionContext_t context_ = nullptr;
// Current state of the compressor.
State state_ = State::kInitalized;
// Internal buffer used for storing decompressed data.
std::vector<uint8_t> decompression_buffer_;
// Provides a callable for handling compressed representation symbols.
Handler handler_;
};
} // namespace storage::volume_image
#endif // SRC_STORAGE_VOLUME_IMAGE_UTILS_LZ4_DECOMPRESSOR_H_