v1.0.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 
119  int read(void *buffer, unsigned bufferSize, _SYSVolumeHandle volume = 0) const {
120  return _SYS_fs_objectRead(sys, (uint8_t*)buffer, bufferSize, volume);
121  }
122 
140  int write(const void *data, unsigned dataSize) const {
141  return _SYS_fs_objectWrite(sys, (const uint8_t*)data, dataSize);
142  }
143 
145  int erase() const {
146  return write(0, 0);
147  }
148 
155  template <typename T>
156  int read(T &buffer, _SYSVolumeHandle volume = 0) const {
157  return read((void*) &buffer, sizeof buffer, volume);
158  }
159 
161  template <typename T>
162  int readObject(T &buffer, _SYSVolumeHandle volume = 0) const {
163  return read((void*) &buffer, sizeof buffer, volume);
164  }
165 
172  template <typename T>
173  int write(const T &buffer) const {
174  return write((const void*) &buffer, sizeof buffer);
175  }
176 
178  template <typename T>
179  int writeObject(const T &buffer) const {
180  return write((const void*) &buffer, sizeof buffer);
181  }
182 
184  bool operator== (_SYSObjectKey other) const {
185  return sys == other;
186  }
187 
189  bool operator!= (_SYSObjectKey other) const {
190  return sys != other;
191  }
192 };
193 
194 
206 class Volume {
207 public:
208  _SYSVolumeHandle sys;
209 
211  enum Type {
212  T_GAME = _SYS_FS_VOL_GAME,
213  T_LAUNCHER = _SYS_FS_VOL_LAUNCHER,
214  };
215 
217  Volume() : sys(0) {}
218 
220  Volume(_SYSVolumeHandle vh) : sys(vh) {}
221 
223  operator const _SYSVolumeHandle () const { return sys; }
224 
230  template <unsigned T>
231  static void list(unsigned volType, Array<Volume, T> &volumes)
232  {
233  volumes.setCount(_SYS_fs_listVolumes(volType, &volumes.begin()->sys,
234  volumes.capacity()));
235  }
236 
257  void exec() const {
258  _SYS_elf_exec(sys);
259  }
260 
268  static Volume running() {
269  return (_SYSVolumeHandle) _SYS_fs_runningVolume();
270  }
271 
283  static Volume previous() {
284  return (_SYSVolumeHandle) _SYS_fs_previousVolume();
285  }
286 
288  bool operator== (_SYSVolumeHandle other) const {
289  return sys == other;
290  }
291 
293  bool operator!= (_SYSVolumeHandle other) const {
294  return sys != other;
295  }
296 };
297 
298 
317  Volume vol;
318  uint32_t offset;
319 
320  /*
321  * On debug builds, this ensures that only one MappedVolume exists
322  * at a time. On release builds, this has no effect and the static
323  * variable optimizes out.
324  */
325  void debugInstanceCounter(int delta) {
326  DEBUG_ONLY({
327  static int counter = 0;
328  counter += delta;
329  ASSERT(counter >= 0);
330  ASSERT(counter <= 1);
331  });
332  }
333 
334 public:
335  typedef _SYSUUID UUID;
336  typedef _SYSMetadataCubeRange CubeRange;
337 
338  static const unsigned MAX_BOOTSTRAP_GROUPS = _SYS_MAX_METADATA_ITEM_BYTES / sizeof(_SYSMetadataBootAsset);
339 
342 
345 
352  : vol(0), offset(0) {
353  debugInstanceCounter(1);
354  }
355 
362  explicit MappedVolume(Volume vol) {
363  debugInstanceCounter(1);
364  attach(vol);
365  }
366 
367  ~MappedVolume()
368  {
369  debugInstanceCounter(-1);
370 
371  // Reclaim a little bit of memory by unmapping
372  _SYS_elf_map(0);
373  }
374 
381  void attach(Volume vol)
382  {
383  if (this->vol != vol) {
384  this->vol = vol;
385  offset = _SYS_elf_map(vol);
386  }
387  }
388 
390  Volume volume() const {
391  return vol;
392  }
393 
408  void *metadata(unsigned key, unsigned minSize, unsigned *actualSize) const {
409  return _SYS_elf_metadata(vol, key, minSize, actualSize);
410  }
411 
427  template <typename T>
428  const T* metadata(unsigned key, unsigned *actualSize = NULL) const {
429  return reinterpret_cast<const T*>(metadata(key, sizeof(T), actualSize));
430  }
431 
440  template <typename T>
441  T* translate(T* va) const {
442  return reinterpret_cast<T*>(translate(reinterpret_cast<uint32_t>(va)));
443  }
444 
450  uint32_t translate(uint32_t va) const {
451  return va + offset;
452  }
453 
460  const char *title(const char *placeholder = "(untitled)") const {
461  const char *p = metadata<char>(_SYS_METADATA_TITLE_STR);
462  return p ? p : placeholder;
463  }
464 
471  const char *package(const char *placeholder = "(none)") const {
472  const char *p = metadata<char>(_SYS_METADATA_PACKAGE_STR);
473  return p ? p : placeholder;
474  }
475 
482  const char *version(const char *placeholder = "(none)") const {
483  const char *p = metadata<char>(_SYS_METADATA_VERSION_STR);
484  return p ? p : placeholder;
485  }
486 
492  const UUID *uuid() const {
493  const UUID *p = metadata<UUID>(_SYS_METADATA_UUID);
494  static UUID zero;
495  return p ? p : &zero;
496  }
497 
508  void translate(const _SYSMetadataBootAsset &meta, AssetGroup &group)
509  {
510  bzero(group);
511  group.sys.pHdr = translate(meta.pHdr);
512  }
513 
531  void translate(const _SYSMetadataImage *meta, AssetImage &image, AssetGroup &group)
532  {
533  bzero(group);
534  group.sys.pHdr = translate(meta->groupHdr);
535 
536  bzero(image);
537  image.sys.pAssetGroup = reinterpret_cast<uint32_t>(&group);
538  image.sys.width = meta->width;
539  image.sys.height = meta->height;
540  image.sys.frames = meta->frames;
541  image.sys.format = meta->format;
542  image.sys.pData = translate(meta->pData);
543  }
544 
550  {
551  uint32_t actual;
552  auto vec = metadata<_SYSMetadataBootAsset>(_SYS_METADATA_BOOT_ASSET, &actual);
553  if (!vec)
554  return;
555 
556  unsigned count = actual / sizeof *vec;
557  for (unsigned i = 0; i != count; ++i) {
558 
559  AssetGroup &group = groups.append();
560  translate(vec[i], group);
561 
562  config.append(vec[i].slot, group, volume());
563  }
564  }
565 };
566 
567 
580 {
581 public:
582  _SYSFilesystemInfo sys;
583 
590  void gather() {
591  _SYS_fs_info(&sys, sizeof sys);
592  }
593 
600  uint32_t allocationUnitSize() {
601  return sys.unitSize;
602  }
603 
605  uint32_t freeUnits() {
606  return sys.freeUnits;
607  }
608 
610  uint32_t freeBytes() {
611  return sys.freeUnits * sys.unitSize;
612  }
613 
615  uint32_t totalUnits() {
616  return sys.totalUnits;
617  }
618 
620  uint32_t totalBytes() {
621  return sys.totalUnits * sys.unitSize;
622  }
623 
631  uint32_t systemUnits() {
632  return sys.systemUnits;
633  }
634 
636  uint32_t systemBytes() {
637  return sys.systemUnits * sys.unitSize;
638  }
639 
641  uint32_t launcherElfUnits() {
642  return sys.launcherElfUnits;
643  }
644 
646  uint32_t launcherElfBytes() {
647  return sys.launcherElfUnits * sys.unitSize;
648  }
649 
651  uint32_t launcherObjUnits() {
652  return sys.launcherObjUnits;
653  }
654 
656  uint32_t launcherObjBytes() {
657  return sys.launcherObjUnits * sys.unitSize;
658  }
659 
661  uint32_t gameElfUnits() {
662  return sys.gameElfUnits;
663  }
664 
666  uint32_t gameElfBytes() {
667  return sys.gameElfUnits * sys.unitSize;
668  }
669 
671  uint32_t gameObjUnits() {
672  return sys.gameObjUnits;
673  }
674 
676  uint32_t gameObjBytes() {
677  return sys.gameObjUnits * sys.unitSize;
678  }
679 
681  uint32_t selfElfUnits() {
682  return sys.selfElfUnits;
683  }
684 
686  uint32_t selfElfBytes() {
687  return sys.selfElfUnits * sys.unitSize;
688  }
689 
691  uint32_t selfObjUnits() {
692  return sys.selfObjUnits;
693  }
694 
696  uint32_t selfObjBytes() {
697  return sys.selfObjUnits * sys.unitSize;
698  }
699 };
700 
701 
706 } // namespace Sifteo