Components/IFS/src/include/IFS/FWFS/ArchiveStream.h
Go to the documentation of this file.
1 /****
2  * ArchiveStream.h
3  *
4  * Copyright 2021 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the IFS Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #pragma once
21 
22 #include <IFS/FileSystem.h>
23 #include <IFS/FsBase.h>
24 #include "ObjectBuffer.h"
25 #include "BlockEncoder.h"
26 
27 namespace IFS
28 {
29 namespace FWFS
30 {
50 class ArchiveStream : public FsBase, public IDataSourceStream
51 {
52  struct DirInfo;
53 
54 public:
55  enum class Flag {
57  };
58 
60 
61  struct VolumeInfo {
63  uint32_t id{0};
65 
67  {
68  name = fsinfo.name.c_str();
69  id = fsinfo.volumeID;
70  creationTime = fsinfo.creationTime;
71  return *this;
72  }
73  };
74 
78  class FileInfo
79  {
80  public:
81  FileInfo(ArchiveStream& stream, DirInfo& dir, FileHandle handle, const Stat& stat)
82  : handle(handle), stat(stat), stream(stream), dir(dir)
83  {
84  }
85 
87  {
88  return stream.getFileSystem();
89  }
90 
99  int setAttribute(AttributeTag tag, const void* data, size_t size);
100 
101  int setAttribute(AttributeTag tag, const String& data)
102  {
103  return setAttribute(tag, data.c_str(), data.length());
104  }
105 
109  template <typename... ParamTypes> int setUserAttribute(uint8_t tagValue, ParamTypes... params)
110  {
111  return setAttribute(getUserAttributeTag(tagValue), params...);
112  }
113 
115  const Stat& stat;
116 
117  private:
118  ArchiveStream& stream;
119  DirInfo& dir;
120  };
121 
122  using FilterStatCallback = Delegate<bool(const Stat& stat)>;
124 
132  ArchiveStream(FileSystem* fileSystem, const VolumeInfo& volumeInfo, const String& rootPath = nullptr,
133  Flags flags = 0)
134  : FsBase(fileSystem), currentPath(rootPath), volumeInfo(volumeInfo), flags(flags)
135  {
136  }
137 
139  {
140  reset();
141  }
142 
150  virtual bool filterStat(const Stat& stat)
151  {
152  return filterStatCallback ? filterStatCallback(stat) : true;
153  }
154 
156  {
157  filterStatCallback = callback;
158  }
159 
169  {
170  return createEncoderCallback ? createEncoderCallback(file) : nullptr;
171  }
172 
174  {
175  createEncoderCallback = callback;
176  }
177 
181  const String& getCurrentPath() const
182  {
183  return currentPath;
184  }
185 
186  uint16_t readMemoryBlock(char* data, int bufSize) override;
187 
188  int seekFrom(int offset, SeekOrigin origin) override;
189 
190  bool isFinished() override
191  {
192  return state >= State::done;
193  }
194 
195  MimeType getMimeType() const override
196  {
197  return MimeType::BINARY;
198  }
199 
200  bool isSuccess() const
201  {
202  return state == State::done;
203  }
204 
208  void reset();
209 
210 private:
211  enum class State {
212  idle,
213  start,
214  dataHeader,
215  dataContent,
216  fileHeader,
217  dirHeader,
218  volumeHeader,
219  end,
220  done,
221  error,
222  };
223 
224  struct DirInfo {
225  DirHandle handle;
226  std::unique_ptr<ObjectBuffer> content; // Directory or object content
227  Object::Type type; // Differentiate between e.g. Directory and MountPoint
228  uint8_t namelen; // Used to track current path
229 
230  void reset()
231  {
232  assert(handle == nullptr);
233  namelen = 0;
234  handle = nullptr;
235  content.reset();
236  }
237 
238  void createContent()
239  {
240  content = std::make_unique<ObjectBuffer>();
241  }
242 
243  int addAttribute(AttributeTag tag, const void* data, size_t size);
244  };
245 
246  bool fillBuffers();
247  void queueStream(IDataSourceStream* stream, State newState);
248  bool openRootDirectory();
249  void openDirectory(const Stat& stat);
250  bool readDirectory();
251  bool readFileEntry(const Stat& stat);
252  void sendDataHeader();
253  void sendDataContent();
254  void sendFileHeader();
255  int getAttributes(FileHandle file, DirInfo& entry);
256  void closeDirectory();
257  void getVolume();
258 
259  String currentPath;
260  VolumeInfo volumeInfo;
261  FilterStatCallback filterStatCallback;
262  CreateEncoderCallback createEncoderCallback;
263  ObjectBuffer buffer;
264  std::unique_ptr<IBlockEncoder> encoder;
265  IDataSourceStream* dataBlock{nullptr};
266  IDataSourceStream* source{nullptr};
267  unsigned level{0};
268  static constexpr size_t maxLevels{16};
269  DirInfo directories[maxLevels]{};
270  uint32_t streamOffset{0};
271  uint32_t queuedSize{0};
272  Flags flags{};
273  State state{};
274 };
275 
276 } // namespace FWFS
277 } // namespace IFS
SeekOrigin
Stream/file seek origins.
Definition: SeekOrigin.h:18
Base class for read-only stream.
Definition: DataSourceStream.h:46
Passed to callbacks to allow modification of output data.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:79
FileSystem * getFileSystem() const
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:86
FileInfo(ArchiveStream &stream, DirInfo &dir, FileHandle handle, const Stat &stat)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:81
const Stat & stat
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:115
int setAttribute(AttributeTag tag, const void *data, size_t size)
Set an additional attribute on the file.
int setAttribute(AttributeTag tag, const String &data)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:101
const FileHandle handle
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:114
int setUserAttribute(uint8_t tagValue, ParamTypes... params)
Set an additional user attribute.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:109
Supports direct streaming into FWFS archive format.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:51
void reset()
Reset stream to beginning.
void onCreateEncoder(CreateEncoderCallback callback)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:173
~ArchiveStream()
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:138
virtual IBlockEncoder * createEncoder(FileInfo &file)
Override this method to implement custom encoding such as compression or encryption.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:168
ArchiveStream(FileSystem *fileSystem, const VolumeInfo &volumeInfo, const String &rootPath=nullptr, Flags flags=0)
Construct an archive stream.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:132
int seekFrom(int offset, SeekOrigin origin) override
Change position in stream.
MimeType getMimeType() const override
Get MIME type for stream content.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:195
Delegate< bool(const Stat &stat)> FilterStatCallback
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:122
Delegate< IBlockEncoder *(FileInfo &file)> CreateEncoderCallback
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:123
bool isFinished() override
Check if all data has been read.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:190
bool isSuccess() const
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:200
Flag
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:55
@ IncludeMountPoints
Set to include mountpoints in archive.
void onFilterStat(FilterStatCallback callback)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:155
uint16_t readMemoryBlock(char *data, int bufSize) override
Read a block of memory.
const String & getCurrentPath() const
Get the current path being processed.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:181
virtual bool filterStat(const Stat &stat)
Override this method to filter items.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:150
BitSet< uint8_t, Flag, 1 > Flags
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:59
Implementation of firmware filing system using IFS.
Definition: Components/IFS/src/include/IFS/FWFS/FileSystem.h:97
Virtual base class to support (file) data encryption and compression.
Definition: BlockEncoder.h:40
Definition: FsBase.h:34
FileSystem * getFileSystem() const
Definition: FsBase.h:63
The String class.
Definition: WString.h:137
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:617
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:244
IFS::FileHandle FileHandle
Definition: Core/FileSystem.h:24
MimeType
Definition: WebConstants.h:53
Definition: DirectoryTemplate.h:37
struct ImplFileDir * DirHandle
Definition: IFileSystem.h:72
AttributeTag
Identifies a specific attribute.
Definition: Attribute.h:45
AttributeTag getUserAttributeTag(uint8_t value)
Definition: Attribute.h:85
int16_t FileHandle
File handle.
Definition: Stat.h:40
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:61
VolumeInfo & operator=(const IFileSystem::Info &fsinfo)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:66
TimeStamp creationTime
Volume creation time, default is current system time (UTC)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:64
String name
Volume Name.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:62
Type
Definition: Components/IFS/src/include/IFS/FWFS/Object.h:152
Basic information about filing system.
Definition: IFileSystem.h:122
TimeStamp creationTime
Definition: IFileSystem.h:132
uint32_t volumeID
Unique identifier for volume.
Definition: IFileSystem.h:128
NameBuffer name
Buffer for name.
Definition: IFileSystem.h:129
const char * c_str() const
Definition: NameBuffer.h:74
File Status structure.
Definition: Stat.h:52
Manage IFS timestamps stored as an unsigned 32-bit value.
Definition: TimeStamp.h:37