#ifndef _MODULE_STORAGE_h #define _MODULE_STORAGE_h #include "watchos_consts.h" #include "watchos_types.h" #include "Task.h" // We pre-allocate a table for tracking storage allocations. This defines how // many entries that supports. #define MODULE_STORAGE_MAX_ENTRIES 16 struct StorageEntry; /// /// Module providing a coherent interface for persisting data /// class Module_Storage : public Task { /// /// To validate that the storage we're reading is initialized, we store two bytes of magic /// at the beginning. /// uint16_t m_magic; /// /// Storage tracks a version number to allow non-backward-compatible updates to be made /// to the format in the future. /// byte m_version; /// /// One byte of storage is reserved to track top-level flags/options /// byte m_options; /// /// In-memory list of all storage allocations /// StorageEntry* m_entry[MODULE_STORAGE_MAX_ENTRIES]; /// /// Convert a kernel well-known handle into a byte in the range 0-63 /// /// /// Well known handles are used as a bitmask, so each distinct handle /// only sets a single bit. In order to save on storage, internally we map /// those to a single byte in the range 0-63. /// /// well known handle; one of the WATCHOS_MODULE_* consts /// a byte with a number in the range 0-63 byte wellKnownHandleToByte(well_known_handle_t handle); /// /// Get the offset of a specific module's data within storage /// /// id of the module to get offset for /// offset, in bytes, of the module's data int getOffset(byte module); public: void initialize(); void start(); void suspend(); /// /// Check whether the underlying storage contains valid and initialized storage /// /// true if valid; false if invalid bool isValid(); /// /// Load the storage allocations from persistent storage /// void load(); /// /// Commit the storage allocations to persistent storage /// void commit(); /// /// Reset all storage allocations and write an empty allocation /// table to persistent storage. /// void reset(); /// /// Allocate storage for a module /// /// module's handle /// number of bytes of storage to allocate /// /// true if an allocation was performed; false if an allocation already existed for the given module + size bool allocate(well_known_handle_t module, uint16_t size, byte options = 0); /// /// Write data to a module's storage /// /// module to write for /// offset, in bytes, within module's storage /// value to write at offset void write(well_known_handle_t module, uint16_t offset, byte value); /// /// Fetch data from a module's storage /// /// module to read for /// offset, in bytes, within module's storage /// the value previously stored at that address byte read(well_known_handle_t module, uint16_t offset); /// /// Allocate storage for a module /// /// module's handle /// number of bytes of storage to allocate /// /// true if an allocation was performed; false if an allocation already existed for the given module + size bool allocate(byte module, uint16_t size, byte options = 0); /// /// Write data to a module's storage /// /// module to write for /// offset, in bytes, within module's storage /// value to write at offset void write(byte module, uint16_t offset, byte value); /// /// Fetch data from a module's storage /// /// module to read for /// offset, in bytes, within module's storage /// the value previously stored at that address byte read(byte module, uint16_t offset); }; #endif