v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
filesystem.h
1 /*
2  * This file is part of the public interface to the Sifteo SDK.
3  * Copyright <c> 2012 Sifteo, Inc. All rights reserved.
4  */
5 
6 #pragma once
7 #ifdef NOT_USERSPACE
8 # error This is a userspace-only header, not allowed by the current build.
9 #endif
10 
11 #include <sifteo/array.h>
12 #include <sifteo/asset/loader.h>
13 #include <sifteo/abi.h>
14 
15 namespace Sifteo {
16 
55 class StoredObject {
56 public:
57  _SYSObjectKey sys;
58 
60  static const unsigned LIMIT = _SYS_FS_MAX_OBJECT_KEYS - 1;
61 
63  static const unsigned MAX_SIZE = _SYS_FS_MAX_OBJECT_SIZE;
64 
66  StoredObject(_SYSObjectKey k) : sys(k) {}
67 
69  StoredObject(int k) : sys(k) {
70  ASSERT(k >= 0 && k <= LIMIT);
71  }
72 
74  StoredObject(unsigned k) : sys(k) {
75  ASSERT(k <= LIMIT);
76  }
77 
79  operator const _SYSObjectKey () const { return sys; }
80 
93  return StoredObject(LIMIT - _SYS_lti_counter("Sifteo.StoredObject", 0));
94  }
95 
125  int read(void *buffer, unsigned bufferSize, _SYSVolumeHandle volume = 0) const {
126  return _SYS_fs_objectRead(sys, (uint8_t*)buffer, bufferSize, volume);
127  }
128 
152  int write(const void *data, unsigned dataSize) const {
153  return _SYS_fs_objectWrite(sys, (const uint8_t*)data, dataSize);
154  }
155 
157  int erase() const {
158  return write(0, 0);
159  }
160 
167  template <typename T>
168  int read(T &buffer, _SYSVolumeHandle volume = 0) const {
169  return read((void*) &buffer, sizeof buffer, volume);
170  }
171 
173  template <typename T>
174  int readObject(T &buffer, _SYSVolumeHandle volume = 0) const {
175  return read((void*) &buffer, sizeof buffer, volume);
176  }
177 
184  template <typename T>
185  int write(const T &buffer) const {
186  return write((const void*) &buffer, sizeof buffer);
187  }
188 
190  template <typename T>
191  int writeObject(const T &buffer) const {
192  return write((const void*) &buffer, sizeof buffer);
193  }
194 
196  bool operator== (_SYSObjectKey other) const {
197  return sys == other;
198  }
199 
201  bool operator!= (_SYSObjectKey other) const {
202  return sys != other;
203  }
204 };
205 
206 
218 class Volume {
219 public:
220  _SYSVolumeHandle sys;
221 
223  enum Type {
224  T_GAME = _SYS_FS_VOL_GAME,
225  T_LAUNCHER = _SYS_FS_VOL_LAUNCHER,
226  };
227 
229  Volume() : sys(0) {}
230 
232  Volume(_SYSVolumeHandle vh) : sys(vh) {}
233 
235  operator const _SYSVolumeHandle () const { return sys; }
236 
242  template <unsigned T>
243  static void list(unsigned volType, Array<Volume, T> &volumes)
244  {
245  volumes.setCount(_SYS_fs_listVolumes(volType, &volumes.begin()->sys,
246  volumes.capacity()));
247  }
248 
269  void exec() const {
270  _SYS_elf_exec(sys);
271  }
272 
280  static Volume running() {
281  return (_SYSVolumeHandle) _SYS_fs_runningVolume();
282  }
283 
295  static Volume previous() {
296  return (_SYSVolumeHandle) _SYS_fs_previousVolume();
297  }
298 
300  bool operator== (_SYSVolumeHandle other) const {
301  return sys == other;
302  }
303 
305  bool operator!= (_SYSVolumeHandle other) const {
306  return sys != other;
307  }
308 };
309 
310 
329  Volume vol;
330  uint32_t offset;
331 
332  /*
333  * On debug builds, this ensures that only one MappedVolume exists
334  * at a time. On release builds, this has no effect and the static
335  * variable optimizes out.
336  */
337  void debugInstanceCounter(int delta) {
338  DEBUG_ONLY({
339  static int counter = 0;
340  counter += delta;
341  ASSERT(counter >= 0);
342  ASSERT(counter <= 1);
343  });
344  }
345 
346 public:
347  typedef _SYSUUID UUID;
348  typedef _SYSMetadataCubeRange CubeRange;
349 
350  static const unsigned MAX_BOOTSTRAP_GROUPS = _SYS_MAX_METADATA_ITEM_BYTES / sizeof(_SYSMetadataBootAsset);
351 
354 
357 
364  : vol(0), offset(0) {
365  debugInstanceCounter(1);
366  }
367 
374  explicit MappedVolume(Volume vol) {
375  debugInstanceCounter(1);
376  attach(vol);
377  }
378 
379  ~MappedVolume()
380  {
381  debugInstanceCounter(-1);
382 
383  // Reclaim a little bit of memory by unmapping
384  _SYS_elf_map(0);
385  }
386 
393  void attach(Volume vol)
394  {
395  if (this->vol != vol) {
396  this->vol = vol;
397  offset = _SYS_elf_map(vol);
398  }
399  }
400 
402  Volume volume() const {
403  return vol;
404  }
405 
420  void *metadata(unsigned key, unsigned minSize, unsigned *actualSize) const {
421  return _SYS_elf_metadata(vol, key, minSize, actualSize);
422  }
423 
439  template <typename T>
440  const T* metadata(unsigned key, unsigned *actualSize = NULL) const {
441  return reinterpret_cast<const T*>(metadata(key, sizeof(T), actualSize));
442  }
443 
452  template <typename T>
453  T* translate(T* va) const {
454  return reinterpret_cast<T*>(translate(reinterpret_cast<uint32_t>(va)));
455  }
456 
462  uint32_t translate(uint32_t va) const {
463  return va + offset;
464  }
465 
472  const char *title(const char *placeholder = "(untitled)") const {
473  const char *p = metadata<char>(_SYS_METADATA_TITLE_STR);
474  return p ? p : placeholder;
475  }
476 
483  const char *package(const char *placeholder = "(none)") const {
484  const char *p = metadata<char>(_SYS_METADATA_PACKAGE_STR);
485  return p ? p : placeholder;
486  }
487 
494  const char *version(const char *placeholder = "(none)") const {
495  const char *p = metadata<char>(_SYS_METADATA_VERSION_STR);
496  return p ? p : placeholder;
497  }
498 
504  const UUID *uuid() const {
505  const UUID *p = metadata<UUID>(_SYS_METADATA_UUID);
506  static UUID zero;
507  return p ? p : &zero;
508  }
509 
520  void translate(const _SYSMetadataBootAsset &meta, AssetGroup &group)
521  {
522  bzero(group);
523  group.sys.pHdr = translate(meta.pHdr);
524  }
525 
543  void translate(const _SYSMetadataImage *meta, AssetImage &image, AssetGroup &group)
544  {
545  bzero(group);
546  group.sys.pHdr = translate(meta->groupHdr);
547 
548  bzero(image);
549  image.sys.pAssetGroup = reinterpret_cast<uint32_t>(&group);
550  image.sys.width = meta->width;
551  image.sys.height = meta->height;
552  image.sys.frames = meta->frames;
553  image.sys.format = meta->format;
554  image.sys.pData = translate(meta->pData);
555  }
556 
562  {
563  uint32_t actual;
564  auto vec = metadata<_SYSMetadataBootAsset>(_SYS_METADATA_BOOT_ASSET, &actual);
565  if (!vec)
566  return;
567 
568  unsigned count = actual / sizeof *vec;
569  for (unsigned i = 0; i != count; ++i) {
570 
571  AssetGroup &group = groups.append();
572  translate(vec[i], group);
573 
574  config.append(vec[i].slot, group, volume());
575  }
576  }
577 };
578 
579 
592 {
593 public:
594  _SYSFilesystemInfo sys;
595 
602  void gather() {
603  _SYS_fs_info(&sys, sizeof sys);
604  }
605 
612  uint32_t allocationUnitSize() {
613  return sys.unitSize;
614  }
615 
617  uint32_t freeUnits() {
618  return sys.freeUnits;
619  }
620 
622  uint32_t freeBytes() {
623  return sys.freeUnits * sys.unitSize;
624  }
625 
627  uint32_t totalUnits() {
628  return sys.totalUnits;
629  }
630 
632  uint32_t totalBytes() {
633  return sys.totalUnits * sys.unitSize;
634  }
635 
643  uint32_t systemUnits() {
644  return sys.systemUnits;
645  }
646 
648  uint32_t systemBytes() {
649  return sys.systemUnits * sys.unitSize;
650  }
651 
653  uint32_t launcherElfUnits() {
654  return sys.launcherElfUnits;
655  }
656 
658  uint32_t launcherElfBytes() {
659  return sys.launcherElfUnits * sys.unitSize;
660  }
661 
663  uint32_t launcherObjUnits() {
664  return sys.launcherObjUnits;
665  }
666 
668  uint32_t launcherObjBytes() {
669  return sys.launcherObjUnits * sys.unitSize;
670  }
671 
673  uint32_t gameElfUnits() {
674  return sys.gameElfUnits;
675  }
676 
678  uint32_t gameElfBytes() {
679  return sys.gameElfUnits * sys.unitSize;
680  }
681 
683  uint32_t gameObjUnits() {
684  return sys.gameObjUnits;
685  }
686 
688  uint32_t gameObjBytes() {
689  return sys.gameObjUnits * sys.unitSize;
690  }
691 
693  uint32_t selfElfUnits() {
694  return sys.selfElfUnits;
695  }
696 
698  uint32_t selfElfBytes() {
699  return sys.selfElfUnits * sys.unitSize;
700  }
701 
703  uint32_t selfObjUnits() {
704  return sys.selfObjUnits;
705  }
706 
708  uint32_t selfObjBytes() {
709  return sys.selfObjUnits * sys.unitSize;
710  }
711 };
712 
713 
718 } // namespace Sifteo