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 {
62  String name;
63  uint32_t id{0};
64  TimeStamp creationTime{0};
65 
66  VolumeInfo& operator=(const IFileSystem::Info& fsinfo)
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 
86  FileSystem* getFileSystem() const
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 
131  ArchiveStream(FileSystem* fileSystem, VolumeInfo volumeInfo, String rootPath = nullptr, Flags flags = 0)
132  : FsBase(fileSystem), currentPath(rootPath), volumeInfo(volumeInfo), flags(flags)
133  {
134  }
135 
137  {
138  reset();
139  }
140 
148  virtual bool filterStat(const Stat& stat)
149  {
150  return filterStatCallback ? filterStatCallback(stat) : true;
151  }
152 
153  void onFilterStat(FilterStatCallback callback)
154  {
155  filterStatCallback = callback;
156  }
157 
167  {
168  return createEncoderCallback ? createEncoderCallback(file) : nullptr;
169  }
170 
172  {
173  createEncoderCallback = callback;
174  }
175 
179  const String& getCurrentPath() const
180  {
181  return currentPath;
182  }
183 
184  uint16_t readMemoryBlock(char* data, int bufSize) override;
185 
186  int seekFrom(int offset, SeekOrigin origin) override;
187 
188  bool isFinished() override
189  {
190  return state >= State::done;
191  }
192 
193  MimeType getMimeType() const override
194  {
195  return MimeType::BINARY;
196  }
197 
198  bool isSuccess() const
199  {
200  return state == State::done;
201  }
202 
206  void reset();
207 
208 private:
209  enum class State {
210  idle,
211  start,
212  dataHeader,
213  dataContent,
214  fileHeader,
215  dirHeader,
216  volumeHeader,
217  end,
218  done,
219  error,
220  };
221 
222  struct DirInfo {
223  DirHandle handle;
224  std::unique_ptr<ObjectBuffer> content; // Directory or object content
225  Object::Type type; // Differentiate between e.g. Directory and MountPoint
226  uint8_t namelen; // Used to track current path
227 
228  void reset()
229  {
230  assert(handle == nullptr);
231  namelen = 0;
232  handle = nullptr;
233  content.reset();
234  }
235 
236  void createContent()
237  {
238  content.reset(new ObjectBuffer);
239  }
240 
241  int addAttribute(AttributeTag tag, const void* data, size_t size);
242  };
243 
244  bool fillBuffers();
245  void queueStream(IDataSourceStream* stream, State newState);
246  bool openRootDirectory();
247  void openDirectory(const Stat& stat);
248  bool readDirectory();
249  bool readFileEntry(const Stat& stat);
250  void sendDataHeader();
251  void sendDataContent();
252  void sendFileHeader();
253  int getAttributes(FileHandle file, DirInfo& entry);
254  void closeDirectory();
255  void getVolume();
256 
257  String currentPath;
258  VolumeInfo volumeInfo;
259  FilterStatCallback filterStatCallback;
260  CreateEncoderCallback createEncoderCallback;
261  ObjectBuffer buffer;
262  std::unique_ptr<IBlockEncoder> encoder;
263  IDataSourceStream* dataBlock{nullptr};
264  IDataSourceStream* source{nullptr};
265  unsigned level{0};
266  static constexpr size_t maxLevels{16};
267  DirInfo directories[maxLevels]{};
268  uint32_t streamOffset{0};
269  uint32_t queuedSize{0};
270  Flags flags{};
271  State state{};
272 };
273 
274 } // namespace FWFS
275 } // namespace IFS
Base class for read-only stream.
Definition: DataSourceStream.h:45
virtual bool filterStat(const Stat &stat)
Override this method to filter items.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:199
Implementation of firmware filing system using IFS.
Definition: Components/IFS/src/include/IFS/FWFS/FileSystem.h:136
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:217
void reset()
Reset stream to beginning.
MimeType
Definition: WebConstants.h:53
The String class.
Definition: WString.h:136
@ IncludeMountPoints
Set to include mountpoints in archive.
FileSystem * getFileSystem() const
Definition: FsBase.h:81
const String & getCurrentPath() const
Get the current path being processed.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:230
ArchiveStream(FileSystem *fileSystem, VolumeInfo volumeInfo, String rootPath=nullptr, Flags flags=0)
Construct an archive stream.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:182
AttributeTag getUserAttributeTag(uint8_t value)
Definition: Attribute.h:104
int16_t FileHandle
File handle.
Definition: Stat.h:59
Definition: DirectoryTemplate.h:36
Supports direct streaming into FWFS archive format.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:84
BitSet< uint8_t, Flag, 1 > Flags
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:110
Passed to callbacks to allow modification of output data.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:129
File Status structure.
Definition: Stat.h:71
MimeType getMimeType() const override
Get MIME type for stream content.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:244
FileInfo(ArchiveStream &stream, DirInfo &dir, FileHandle handle, const Stat &stat)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:132
Type
Definition: Components/IFS/src/include/IFS/FWFS/Object.h:292
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:616
Definition: FsBase.h:51
VolumeInfo & operator=(const IFileSystem::Info &fsinfo)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:117
struct ImplFileDir * DirHandle
Definition: IFileSystem.h:72
const Stat & stat
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:166
Class to manage writing object data into a stream.
Definition: ObjectBuffer.h:66
TimeStamp creationTime
Volume creation time, default is current system time (UTC)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:115
~ArchiveStream()
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:187
String name
Volume Name.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:113
AttributeTag
Identifies a specific attribute.
Definition: Attribute.h:64
Definition: Core/Data/Stream/IFS/ArchiveStream.h:19
FsBase(IFileSystem *filesys=nullptr)
Definition: FsBase.h:54
IFS::FileHandle FileHandle
Definition: Core/FileSystem.h:24
FileSystem * getFileSystem() const
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:137
SeekOrigin
Stream/file seek origins.
Definition: SeekOrigin.h:18
bool isFinished() override
Check if all data has been read.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:239
void onCreateEncoder(CreateEncoderCallback callback)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:222
uint16_t readMemoryBlock(char *data, int bufSize) override
Read a block of memory.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:112
void onFilterStat(FilterStatCallback callback)
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:204
bool isSuccess() const
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:249
int setAttribute(AttributeTag tag, const void *data, size_t size)
Set an additional attribute on the file.
int setUserAttribute(uint8_t tagValue, ParamTypes... params)
Set an additional user attribute.
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:160
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:243
Flag
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:106
Virtual base class to support (file) data encryption and compression.
Definition: BlockEncoder.h:73
const FileHandle handle
Definition: Components/IFS/src/include/IFS/FWFS/ArchiveStream.h:165
int seekFrom(int offset, SeekOrigin origin) override
Change position in stream.