blob: 1b9cbf9355105500c7c34aa4e233ca4c35243f6d [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_EXTERNAL_DECOMPRESSOR_H_
#define SRC_STORAGE_BLOBFS_COMPRESSION_EXTERNAL_DECOMPRESSOR_H_
#include <fuchsia/blobfs/internal/cpp/fidl.h>
#include <fuchsia/blobfs/internal/llcpp/fidl.h>
#include <lib/zx/fifo.h>
#include <lib/zx/status.h>
#include <lib/zx/vmo.h>
#include "src/storage/blobfs/compression-settings.h"
#include "src/storage/blobfs/compression/seekable-decompressor.h"
namespace blobfs {
// A client class for managing the connection to the decompressor sandbox,
// sending messages, and returning the status result. This class is *not* thread
// safe.
class ExternalDecompressorClient {
public:
DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalDecompressorClient);
// Creates a DecompressorClient that takes data from `compressed_vmo` and
// places the results in `decompressed_vmo`. This calls `Prepare()` and
// returns a failure if it cannot succeed on the first try. Both vmos require
// the ZX_DEFAULT_VMO_RIGHTS except that ZX_RIGHT_WRITE is not required on
// `compressed_vmo`, this permission will be ommited before sending to the
// external decompressor if present.
static zx::status<std::unique_ptr<ExternalDecompressorClient>> Create(
const zx::vmo& decompressed_vmo, const zx::vmo& compressed_vmo);
// Sends the request over the fifo, and awaits the response before verifying
// the resulting size and reporting the status passed from the server. This
// succeeds only if the resulting decompressed size matches the
// `decompressed.size`. Starts by calling `Prepare()`.
zx_status_t SendMessage(const llcpp::fuchsia::blobfs::internal::DecompressRequest& request);
// Convert from fidl compatible enum to local.
static CompressionAlgorithm CompressionAlgorithmFidlToLocal(
llcpp::fuchsia::blobfs::internal::CompressionAlgorithm algorithm);
// Convert to fidl compatible enum from local.
static llcpp::fuchsia::blobfs::internal::CompressionAlgorithm CompressionAlgorithmLocalToFidl(
CompressionAlgorithm algorithm);
// Convert to fidl compatible enum from local for partial decompresion.
static zx::status<llcpp::fuchsia::blobfs::internal::CompressionAlgorithm>
CompressionAlgorithmLocalToFidlForPartial(CompressionAlgorithm algorithm);
private:
ExternalDecompressorClient() = default;
// If the fifo is useable nothing is done and returns ZX_OK. If the fifo is
// not ready to use, this attempts to set one up via the DecompressorCreator.
zx_status_t Prepare();
// If the DecompressorCreator fidl channel is ready then nothing is done.
// Otherwise the channel is set up.
zx_status_t PrepareDecompressorCreator();
// The vmo that will contain the decompressed data for requests. A copy is kept
// so that if it needs to reconnect with the server another copy can be sent.
zx::vmo decompressed_vmo_;
// The vmo that will contain the compressed data for requests. A copy is kept
// so that if it needs to reconnect with the server another copy can be sent.
zx::vmo compressed_vmo_;
// Fidl connection to the DecompressorCreator.
fuchsia::blobfs::internal::DecompressorCreatorSyncPtr decompressor_creator_;
// The fifo that communicates with the Decompressor.
zx::fifo fifo_;
};
// A class for decompressing entire files for which there is an implementation
// of the Decompressor interface for the `algorithm`. Uses the given `client`
// for communication to the external decompressor process.
class ExternalDecompressor {
public:
ExternalDecompressor(ExternalDecompressorClient* client, CompressionAlgorithm algorithm);
DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalDecompressor);
// Performs decompression for an entire archive using the provided client.
zx_status_t Decompress(size_t uncompressed_size, size_t max_compressed_size);
private:
// Client used for communication with the decompressor.
ExternalDecompressorClient* client_;
// The algorithm to be used for this file.
CompressionAlgorithm algorithm_;
};
// A class for decompressing parts of files for which there is an implementation
// of the SeekableDecompressor interface for the `algorithm`. Uses the given
// `client` for communication to the external decompressor process.
class ExternalSeekableDecompressor {
public:
ExternalSeekableDecompressor(ExternalDecompressorClient* client,
SeekableDecompressor* decompressor);
DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalSeekableDecompressor);
// Decompresses one region by sending a request to the provided client.
// The range specified must be one or more entire completeable chunks.
// `compressed_offset` is the offset into the `compressed_vmo_` to start
// decompressing from.
zx_status_t DecompressRange(size_t compressed_offset, size_t compressed_size,
size_t uncompressed_size);
private:
// Client used for communication with the decompressor.
ExternalDecompressorClient* client_;
// The SeekableDecompressor that would otherwise be used to decompress
// locally, which has the CompressionMapping information.
SeekableDecompressor* decompressor_;
};
} // namespace blobfs
#endif // SRC_STORAGE_BLOBFS_COMPRESSION_EXTERNAL_DECOMPRESSOR_H_