Overte C++ Documentation
Storage.h
1 //
2 // Created by Bradley Austin Davis on 2016/02/17
3 // Copyright 2013-2017 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 
9 #pragma once
10 #ifndef hifi_Storage_h
11 #define hifi_Storage_h
12 
13 #include <cstdint>
14 #include <vector>
15 #include <memory>
16 #include <functional>
17 #include <stdexcept>
18 
19 #include <QtCore/QFile>
20 #include <QtCore/QString>
21 
22 namespace storage {
23  class Storage;
24  using Pointer = std::shared_ptr<const Storage>;
25  using StoragePointer = Pointer;
26  // A function that can construct storage, useful for creating a list of
27  // things that can become storage without requiring that they all be instantiated at once
28  using Builder = std::function<StoragePointer()>;
29  using Builders = std::vector<Builder>;
30 
31  // Abstract class to represent memory that stored _somewhere_ (in system memory or in a file, for example)
32  class Storage : public std::enable_shared_from_this<Storage> {
33  public:
34  virtual ~Storage() {}
35  virtual const uint8_t* data() const = 0;
36  virtual uint8_t* mutableData() = 0;
37  virtual size_t size() const = 0;
38  virtual operator bool() const { return true; }
39 
40  StoragePointer createView(size_t size = 0, size_t offset = 0) const;
41  StoragePointer toFileStorage(const QString& filename) const;
42  StoragePointer toMemoryStorage() const;
43 
44  // Aliases to prevent having to re-write a ton of code
45  inline size_t getSize() const { return size(); }
46  inline const uint8_t* readData() const { return data(); }
47  };
48 
49  class MemoryStorage : public Storage {
50  public:
51  MemoryStorage(size_t size, const uint8_t* data = nullptr);
52  const uint8_t* data() const override { return _data.data(); }
53  uint8_t* data() { return _data.data(); }
54  uint8_t* mutableData() override { return _data.data(); }
55  size_t size() const override { return _data.size(); }
56  operator bool() const override { return true; }
57  private:
58  std::vector<uint8_t> _data;
59  };
60 
61  class FileStorage : public Storage {
62  public:
63  static StoragePointer create(const QString& filename, size_t size, const uint8_t* data);
64  FileStorage(const QString& filename);
65  ~FileStorage();
66  // Prevent copying
67  FileStorage(const FileStorage& other) = delete;
68  FileStorage& operator=(const FileStorage& other) = delete;
69 
70  const uint8_t* data() const override { return _mapped; }
71  uint8_t* mutableData() override { return _hasWriteAccess ? _mapped : nullptr; }
72  size_t size() const override { return _size; }
73  operator bool() const override { return _valid; }
74  private:
75  // For compressed QRC files we can't map the file object, so we need to read it into memory
76  QByteArray _fallback;
77  size_t _size { 0 };
78  bool _valid { false };
79  bool _hasWriteAccess { false };
80  QFile _file;
81  uint8_t* _mapped { nullptr };
82  };
83 
84  class ViewStorage : public Storage {
85  public:
86  ViewStorage(const storage::StoragePointer& owner, size_t size, const uint8_t* data);
87  const uint8_t* data() const override { return _data; }
88  uint8_t* mutableData() override { throw std::runtime_error("Cannot modify ViewStorage"); }
89  size_t size() const override { return _size; }
90  operator bool() const override { return *_owner; }
91  private:
92  const storage::StoragePointer _owner;
93  const size_t _size;
94  const uint8_t* _data;
95  };
96 
97 }
98 
99 #endif // hifi_Storage_h