Object.h
Go to the documentation of this file.
1 
73 #pragma once
74 
75 #include "TimeStamp.h"
76 #include "FileAttributes.h"
77 #include "Compression.h"
78 #include "UserRole.h"
79 
80 namespace IFS
81 {
82 /*
83  * Helper template function to get the next object pointer at (current + offset)
84  * casting as required for the given return type.
85  */
86 template <typename T> static T at_offset(const void* current, int offset)
87 {
88  auto p = reinterpret_cast<const uint8_t*>(current) + offset;
89  return reinterpret_cast<T>(p);
90 }
91 
92 template <typename T> static T at_offset(void* current, int offset)
93 {
94  auto p = reinterpret_cast<uint8_t*>(current) + offset;
95  return reinterpret_cast<T>(p);
96 }
97 
98 // Images start with a single word to identify this as a Firmware Filesystem image
99 #define FWFILESYS_START_MARKER 0x53465746 // "FWFS"
100 
101 // Image end marker (reverse of magic)
102 #define FWFILESYS_END_MARKER 0x46574653 // "SFWF"
103 
104 // Everything in this header must be portable (at least, with other little-endian systems) so byte-align and pack it
105 #pragma pack(1)
106 
114 #define FWFS_OBJTYPE_MAP(XX) \
115  XX(0, End, "The system image footer") \
116  XX(1, Data8, "Data, max 255 bytes") \
117  XX(2, ID32, "32-bit identifier") \
118  XX(3, ObjAttr, "Object attributes") \
119  XX(4, Compression, "Compression descriptor") \
120  XX(5, ReadACE, "minimum UserRole for read access") \
121  XX(6, WriteACE, "minimum UserRole for write access") \
122  XX(7, ObjectStore, "Identifier for object store") \
123  XX(8, Md5Hash, "MD5 Hash Value") \
124  XX(32, Data16, "Data, max 64K - 1") \
125  XX(33, Volume, "Volume, top-level container object") \
126  XX(34, MountPoint, "Root for another filesystem") \
127  XX(35, Directory, "Directory entry") \
128  XX(36, File, "File entry") \
129  XX(64, Data24, "Data, max 16M - 1")
130 
137 struct Object {
138  uint8_t typeData;
139 
143  using ID = uint16_t;
144 
145  enum class Type {
146 #define XX(value, tag, text) tag = value,
148 #undef XX
149  };
150 
151  // Top bit of object type set to indicate a reference
152  static constexpr uint8_t FWOBT_REF{0x80};
153 
158  enum class Attribute {
162  ReadOnly,
166  Archive,
167  //
168  MAX
169  };
170 
172 
173  Type type() const
174  {
175  return static_cast<Type>(typeData & 0x7f);
176  }
177 
178  bool isRef() const
179  {
180  return (typeData & FWOBT_REF) != 0;
181  }
182 
183  bool isNamed() const
184  {
185  return type() >= Type::Volume && type() < Type::Data24;
186  }
187 
188  bool isData() const
189  {
190  return type() == Type::Data8 || type() == Type::Data16 || type() == Type::Data24;
191  }
192 
193  bool isDir() const
194  {
195  return type() == Type::Directory;
196  }
197 
198  bool isMountPoint() const
199  {
200  return type() == Type::MountPoint;
201  }
202 
203  union {
204  // Data8 - 8-bit size, max. 255 bytes
205  struct {
206  uint8_t _contentSize;
207  // uint8_t data[];
208 
209  unsigned contentOffset() const
210  {
211  return offsetof(Object, data8) + 1;
212  }
213 
214  unsigned contentSize() const
215  {
216  return _contentSize;
217  }
218 
219  union {
220  // An object reference: the contents are stored externally (on the same volume)
221  struct {
223  } ref;
224 
225  // ID32
226  struct {
227  uint32_t value;
228  } id32;
229 
230  // Object attributes
231  struct {
232  uint8_t attr; // Attributes
234 
235  // Compression descriptor
236  struct {
238  uint32_t originalSize;
239  } compression;
240 
241  // ReadACE, WriteACE
242  struct {
244  } ace;
245 
246  // Identifies an object store, contained in a mount point
247  struct {
248  uint8_t storenum;
249  } objectStore;
250 
251  // END - immediately followed by end marker
252  struct {
253  uint32_t checksum;
254  } end;
255  };
256  } data8;
257 
258  // Data16 - 16-bit size, max. (64KB - 1)
259  struct {
261  // uint8_t data[];
262 
263  unsigned contentOffset() const
264  {
265  return offsetof(Object, data16) + 2;
266  }
267 
268  uint32_t contentSize() const
269  {
270  return _contentSize;
271  }
272 
273  uint32_t size() const
274  {
275  return contentOffset() + contentSize();
276  }
277 
278  union {
279  /*
280  * named object
281  *
282  * child objects can be contained or referenced (flag in _id)
283  * object attributes are optional so can be another object/attribute
284  * objects are word aligned
285  */
286  struct {
287  uint8_t namelen;
288  TimeStamp mtime; // Object modification time
289  // char name[namelen];
290  // Object children[]; // __aligned
291 
292  // Offset to object name relative to content start
293  unsigned nameOffset() const
294  {
295  return sizeof(Object::data16.named);
296  }
297 
298  // Offset to start of child object table
299  unsigned childTableOffset() const
300  {
301  return nameOffset() + ALIGNUP4(namelen);
302  }
303 
304  } named;
305  };
306  } data16;
307 
308  // Data24 - 24-bit size, max. (16MB - 1)
309  struct {
312  // uint8_t data[];
313 
314  size_t contentOffset() const
315  {
316  return offsetof(Object, data24) + 3;
317  }
318 
319  uint32_t contentSize() const
320  {
321  return (_contentSizeHigh << 16) | _contentSize;
322  }
323 
324  void setContentSize(uint32_t value)
325  {
326  _contentSize = value & 0xffff;
327  _contentSizeHigh = value >> 16;
328  }
329 
330  uint32_t size() const
331  {
332  return contentOffset() + contentSize();
333  }
334  } data24;
335  };
336 
339  size_t contentOffset() const
340  {
341  if(isRef() || (type() < Type::Data16)) {
342  return data8.contentOffset();
343  } else if(type() < Type::Data24) {
344  return data16.contentOffset();
345  } else {
346  return data24.contentOffset();
347  }
348  }
349 
354  uint32_t contentSize() const
355  {
356  if(isRef() || (type() < Type::Data16)) {
357  return data8.contentSize();
358  } else if(type() < Type::Data24) {
359  return data16.contentSize();
360  } else {
361  return data24.contentSize();
362  }
363  }
364 
365  uint32_t childTableOffset() const
366  {
367  assert(isNamed());
368  return data16.contentOffset() + data16.named.childTableOffset();
369  }
370 
371  uint32_t childTableSize() const
372  {
373  assert(isNamed());
374  return data16.contentSize() - data16.named.childTableOffset();
375  }
376 
381  uint32_t size() const
382  {
383  return contentOffset() + contentSize();
384  }
385 
386  uint32_t sizeAligned() const
387  {
388  return ALIGNUP4(size());
389  }
390 };
391 
392 static_assert(sizeof(Object) == 8, "Object alignment wrong!");
393 
394 #pragma pack()
395 
396 } // namespace IFS
397 
#define MAX(a, b)
Definition: spiffs_nucleus.h:541
uint32_t contentSize() const
return size of object content, excluding header and size fields
Definition: Object.h:354
Type
Definition: Compression.h:39
struct IFS::Object::@17::@19::@22::@24 ref
uint32_t checksum
Definition: Object.h:253
uint16_t _contentSize
Object size (excluding this header)
Definition: Object.h:260
XX(value, tag, text)
#define FWFS_OBJTYPE_MAP(XX)
Object type identifiers.
Definition: Object.h:114
struct IFS::Object::@17::@19 data8
Compression::Type type
Definition: Object.h:237
Object structure.
Definition: Object.h:137
uint8_t attr
Definition: Object.h:232
uint32_t size() const
total size this object occupies in the image
Definition: Object.h:381
size_t contentOffset() const
return offset to start of object content
Definition: Object.h:339
bool isNamed() const
Definition: Object.h:183
bool isRef() const
Definition: Object.h:178
uint8_t typeData
Stored type plus flag.
Definition: Object.h:138
String toString(IFS::Object::Type obt)
Get descriptive String for an object type.
struct IFS::Object::@17::@20 data16
The String class.
Definition: WString.h:136
TimeStamp mtime
Definition: Object.h:288
ID id
Definition: Object.h:222
bool isData() const
Definition: Object.h:188
struct IFS::Object::@17::@19::@22::@26 objectAttributes
Definition: DirectoryTemplate.h:36
Manage IFS timestamps stored as an unsigned 32-bit value.
Definition: TimeStamp.h:35
uint8_t namelen
Length of object name.
Definition: Object.h:287
uint32_t childTableOffset() const
Definition: Object.h:365
uint8_t _contentSizeHigh
Allows data up to 16MByte.
Definition: Object.h:311
uint8_t storenum
Definition: Object.h:248
struct IFS::Object::@17::@19::@22::@27 compression
static constexpr uint8_t FWOBT_REF
Definition: Object.h:152
Attribute
Object attributes.
Definition: Object.h:158
struct IFS::Object::@17::@21 data24
UserRole
Definition: UserRole.h:36
UserRole role
Definition: Object.h:243
struct IFS::Object::@17::@19::@22::@28 ace
bool isDir() const
Definition: Object.h:193
struct IFS::Object::@17::@19::@22::@25 id32
uint32_t value
32-bit identifier, e.g. volume ID
Definition: Object.h:227
struct IFS::Object::@17::@19::@22::@29 objectStore
struct IFS::Object::@17::@20::@31::@33 named
static T at_offset(const void *current, int offset)
Definition: Object.h:86
struct IFS::Object::@17::@19::@22::@30 end
uint32_t childTableSize() const
Definition: Object.h:371
Type
Definition: Object.h:145
uint8_t _contentSize
Definition: Object.h:206
uint32_t sizeAligned() const
Definition: Object.h:386
Type type() const
Definition: Object.h:173
#define ALIGNUP4(n)
Align a size up to the nearest word boundary.
Definition: FakePgmSpace.h:39
uint32_t originalSize
Definition: Object.h:238
bool isMountPoint() const
Definition: Object.h:198