platform for developing on SQFMI's Watchy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

132 lines
4.6 KiB

#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;
/// <summary>
/// Module providing a coherent interface for persisting data
/// </summary>
class Module_Storage : public Task
{
/// <summary>
/// To validate that the storage we're reading is initialized, we store two bytes of magic
/// at the beginning.
/// </summary>
uint16_t m_magic;
/// <summary>
/// Storage tracks a version number to allow non-backward-compatible updates to be made
/// to the format in the future.
/// </summary>
byte m_version;
/// <summary>
/// One byte of storage is reserved to track top-level flags/options
/// </summary>
byte m_options;
/// <summary>
/// In-memory list of all storage allocations
/// </summary>
StorageEntry* m_entry[MODULE_STORAGE_MAX_ENTRIES];
/// <summary>
/// Convert a kernel well-known handle into a byte in the range 0-63
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
/// <param name="handle">well known handle; one of the WATCHOS_MODULE_* consts</param>
/// <returns>a byte with a number in the range 0-63</returns>
byte wellKnownHandleToByte(well_known_handle_t handle);
/// <summary>
/// Get the offset of a specific module's data within storage
/// </summary>
/// <param name="module">id of the module to get offset for</param>
/// <returns>offset, in bytes, of the module's data</returns>
int getOffset(byte module);
public:
void initialize();
void start();
void suspend();
/// <summary>
/// Check whether the underlying storage contains valid and initialized storage
/// </summary>
/// <returns>true if valid; false if invalid</returns>
bool isValid();
/// <summary>
/// Load the storage allocations from persistent storage
/// </summary>
void load();
/// <summary>
/// Commit the storage allocations to persistent storage
/// </summary>
void commit();
/// <summary>
/// Reset all storage allocations and write an empty allocation
/// table to persistent storage.
/// </summary>
void reset();
/// <summary>
/// Allocate storage for a module
/// </summary>
/// <param name="module">module's handle</param>
/// <param name="size">number of bytes of storage to allocate</param>
/// <param name="options"></param>
/// <returns>true if an allocation was performed; false if an allocation already existed for the given module + size</returns>
bool allocate(well_known_handle_t module, uint16_t size, byte options = 0);
/// <summary>
/// Write data to a module's storage
/// </summary>
/// <param name="module">module to write for</param>
/// <param name="offset">offset, in bytes, within module's storage</param>
/// <param name="value">value to write at offset</param>
void write(well_known_handle_t module, uint16_t offset, byte value);
/// <summary>
/// Fetch data from a module's storage
/// </summary>
/// <param name="module">module to read for</param>
/// <param name="offset">offset, in bytes, within module's storage</param>
/// <returns>the value previously stored at that address</returns>
byte read(well_known_handle_t module, uint16_t offset);
/// <summary>
/// Allocate storage for a module
/// </summary>
/// <param name="module">module's handle</param>
/// <param name="size">number of bytes of storage to allocate</param>
/// <param name="options"></param>
/// <returns>true if an allocation was performed; false if an allocation already existed for the given module + size</returns>
bool allocate(byte module, uint16_t size, byte options = 0);
/// <summary>
/// Write data to a module's storage
/// </summary>
/// <param name="module">module to write for</param>
/// <param name="offset">offset, in bytes, within module's storage</param>
/// <param name="value">value to write at offset</param>
void write(byte module, uint16_t offset, byte value);
/// <summary>
/// Fetch data from a module's storage
/// </summary>
/// <param name="module">module to read for</param>
/// <param name="offset">offset, in bytes, within module's storage</param>
/// <returns>the value previously stored at that address</returns>
byte read(byte module, uint16_t offset);
};
#endif