|  | // 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 <blobfs/compression-settings.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/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 or more areas by sending one request per area to the | 
|  | // provided client, using the SeekableDecompressor provided to determine | 
|  | // areas' information. The range specified must be an entire completable | 
|  | // range or set of ranges. | 
|  | zx_status_t DecompressRange(size_t uncompressed_offset, size_t uncompressed_size, | 
|  | size_t max_compressed_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_ |