File: CASProvidingFileSystem.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (79 lines) | stat: -rw-r--r-- 2,963 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//===- CASProvidingFileSystem.cpp -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/CAS/CASProvidingFileSystem.h"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Support/VirtualFileSystem.h"

using namespace llvm;
using namespace llvm::cas;

namespace {

class CASProvidingFile final : public vfs::File {
  std::shared_ptr<ObjectStore> DB;
  std::unique_ptr<File> UnderlyingFile;

public:
  CASProvidingFile(std::shared_ptr<ObjectStore> DB,
                   std::unique_ptr<File> UnderlyingFile)
      : DB(std::move(DB)), UnderlyingFile(std::move(UnderlyingFile)) {}

  ErrorOr<vfs::Status> status() override { return UnderlyingFile->status(); }

  ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name,
                                                   int64_t FileSize,
                                                   bool RequiresNullTerminator,
                                                   bool IsVolatile) override {
    return UnderlyingFile->getBuffer(Name, FileSize, RequiresNullTerminator,
                                     IsVolatile);
  }

  ErrorOr<std::optional<cas::ObjectRef>> getObjectRefForContent() override {
    auto UnderlyingCASRef = UnderlyingFile->getObjectRefForContent();
    if (!UnderlyingCASRef || *UnderlyingCASRef)
      return UnderlyingCASRef;

    auto Buffer = UnderlyingFile->getBuffer("<contents>", /*FileSize*/ -1,
                                            /*RequiresNullTerminator*/ false);
    if (!Buffer)
      return Buffer.getError();
    auto Blob = DB->storeFromString(std::nullopt, (*Buffer)->getBuffer());
    if (!Blob)
      return errorToErrorCode(Blob.takeError());
    return *Blob;
  }

  std::error_code close() override { return UnderlyingFile->close(); }
};

class CASProvidingFileSystem : public vfs::ProxyFileSystem {
  std::shared_ptr<ObjectStore> DB;

public:
  CASProvidingFileSystem(std::shared_ptr<ObjectStore> DB,
                         IntrusiveRefCntPtr<vfs::FileSystem> FS)
      : ProxyFileSystem(std::move(FS)), DB(std::move(DB)) {}

  ErrorOr<std::unique_ptr<vfs::File>>
  openFileForRead(const Twine &Path) override {
    auto UnderlyingFile = ProxyFileSystem::openFileForRead(Path);
    if (!UnderlyingFile)
      return UnderlyingFile.getError();
    return std::make_unique<CASProvidingFile>(DB, std::move(*UnderlyingFile));
  }
};

} // namespace

std::unique_ptr<vfs::FileSystem> cas::createCASProvidingFileSystem(
    std::shared_ptr<ObjectStore> DB,
    IntrusiveRefCntPtr<vfs::FileSystem> UnderlyingFS) {
  return std::make_unique<CASProvidingFileSystem>(std::move(DB),
                                                  std::move(UnderlyingFS));
}