1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <vector>
8 
9 #include <blobfs/host.h>
10 #include <digest/digest.h>
11 #include <fbl/array.h>
12 #include <fbl/vector.h>
13 #include <fs-host/common.h>
14 #include <lib/fit/defer.h>
15 
16 class BlobfsCreator : public FsCreator {
17 public:
BlobfsCreator()18     BlobfsCreator()
19         : FsCreator(blobfs::kMinimumDataBlocks) {}
20 
21 private:
22     // Parent overrides:
23     zx_status_t Usage() override;
GetToolName()24     const char* GetToolName() override { return "blobfs"; }
25     bool IsCommandValid(Command command) override;
26     bool IsOptionValid(Option option) override;
27     bool IsArgumentValid(Argument argument) override;
28 
29     // Identify blobs to be operated on, populating the internal
30     // |blob_list_|.
31     zx_status_t ProcessManifestLine(FILE* manifest, const char* dir_path) override;
32     zx_status_t ProcessCustom(int argc, char** argv, uint8_t* processed) override;
33 
34     // Calculates merkle trees for the processed blobs, and determines
35     // the total size of the underlying storage necessary to contain them.
36     zx_status_t CalculateRequiredSize(off_t* out) override;
37 
38     //TODO(planders): Add ls support for blobfs.
39     zx_status_t Mkfs() override;
40     zx_status_t Fsck() override;
41     zx_status_t Add() override;
42 
43     // A comparison function used to quickly compare MerkleInfo.
44     struct DigestCompare {
operatorDigestCompare45         inline bool operator()(const blobfs::MerkleInfo& lhs, const blobfs::MerkleInfo& rhs) const {
46             const uint8_t* lhs_bytes = lhs.digest.AcquireBytes();
47             const uint8_t* rhs_bytes = rhs.digest.AcquireBytes();
48             auto auto_release = fit::defer([&]() {
49                 lhs.digest.ReleaseBytes();
50                 rhs.digest.ReleaseBytes();
51             });
52 
53             for (size_t i = 0; i < digest::Digest::kLength; i++) {
54                 if (lhs_bytes[i] < rhs_bytes[i]) {
55                     return true;
56                 }
57             }
58             return false;
59         }
60     };
61 
62     // List of all blobs to be copied into blobfs.
63     fbl::Vector<fbl::String> blob_list_;
64 
65     // A list of Merkle Information for blobs in |blob_list_|.
66     std::vector<blobfs::MerkleInfo> merkle_list_;
67 };
68