PebbleOS
Loading...
Searching...
No Matches
Data Structures | Macros | Functions
Settings file raw iterator

On-flash format of settings files and a cursor over their records. More...

Data Structures

struct  SettingsFileHeader
 Settings file header. More...
 
struct  SettingsRecordHeader
 Record header. More...
 
struct  SettingsRawIter
 Cursor over the records of a settings file. More...
 

Macros

#define SETTINGS_FILE_MAGIC   "set"
 Magic at the start of every settings file.
 
#define SETTINGS_FILE_VERSION   1
 Current settings file format version.
 
#define SETTINGS_FLAG_WRITE_COMPLETE   (1 << 0)
 Record header, key and value are completely written.
 
#define SETTINGS_FLAG_OVERWRITE_STARTED   (1 << 1)
 A newer record for the same key is being written.
 
#define SETTINGS_FLAG_OVERWRITE_COMPLETE   (1 << 2)
 A newer record for the same key is complete; this one is dead.
 
#define SETTINGS_FLAG_SYNCED   (1 << 3)
 Record is in sync with the phone.
 
#define SETTINGS_KEY_MAX_LEN   127
 Maximum key length in bytes.
 
#define SETTINGS_VAL_MAX_LEN   (SETTINGS_EOF_MARKER - 1)
 Maximum value length in bytes.
 
#define KEY_LEN_BITS   7
 Width of the key length field of a record header.
 
#define VAL_LEN_BITS   11
 Width of the value length field of a record header.
 
#define FLAGS_BITS   6
 Width of the flags field of a record header.
 
#define SETTINGS_EOF_MARKER   ((1 << VAL_LEN_BITS) - 1)
 Value length of the all-ones header that marks the end of the records.
 

Functions

void settings_raw_iter_init (SettingsRawIter *iter, int fd, const char *file_name)
 Initialize an iterator and read the file header.
 
void settings_raw_iter_write_file_header (SettingsRawIter *iter, SettingsFileHeader *file_hdr)
 Write the file header, for newly created files.
 
void settings_raw_iter_begin (SettingsRawIter *iter)
 Move to the first record.
 
void settings_raw_iter_resume (SettingsRawIter *iter)
 Start a search from the current record.
 
void settings_raw_iter_next (SettingsRawIter *iter)
 Move to the next record.
 
bool settings_raw_iter_end (SettingsRawIter *iter)
 Check whether the iterator is past the last record.
 
int settings_raw_iter_get_current_record_pos (SettingsRawIter *iter)
 Get the current record position.
 
void settings_raw_iter_set_current_record_pos (SettingsRawIter *iter, int pos)
 Move to a position from settings_raw_iter_get_current_record_pos().
 
int settings_raw_iter_get_resumed_record_pos (SettingsRawIter *iter)
 Get the position the current search started from.
 
void settings_raw_iter_read_key (SettingsRawIter *iter, uint8_t *key)
 Read the key of the current record.
 
void settings_raw_iter_read_val (SettingsRawIter *iter, uint8_t *val, int val_len)
 Read the value of the current record.
 
void settings_raw_iter_read_key_val (SettingsRawIter *iter, uint8_t *key_val_out)
 Read the key and value of the current record in one PFS call.
 
void settings_raw_iter_write_header (SettingsRawIter *iter, SettingsRecordHeader *hdr)
 Write the header of the current record.
 
void settings_raw_iter_write_key (SettingsRawIter *iter, const uint8_t *key)
 Write the key of the current record, using the length from its header.
 
void settings_raw_iter_write_val (SettingsRawIter *iter, const uint8_t *val)
 Write the value of the current record, using the length from its header.
 
void settings_raw_iter_write_key_val (SettingsRawIter *iter, const uint8_t *key_val)
 Write the key and value of the current record in one PFS call.
 
void settings_raw_iter_write_byte (SettingsRawIter *iter, int offset, uint8_t byte)
 Write one byte of the value of the current record in place.
 
void settings_raw_iter_deinit (SettingsRawIter *iter)
 Close the underlying file.
 

Detailed Description

On-flash format of settings files and a cursor over their records.

Internal to the settings file implementation; use settings_file_each() instead.

A settings file is a SettingsFileHeader followed by records, each a SettingsRecordHeader, the key and the value. Unwritten flash (all ones) marks the end. Record flags are active low: a flag is set by clearing its bit, so it can be written in place.

Any PFS error during iteration is treated as a fatal logic error: the file is removed and the system reboots, so that the corruption cannot cause a reboot loop.


Data Structure Documentation

◆ SettingsFileHeader

struct SettingsFileHeader

Settings file header.

Data Fields
uint16_t flags Unused, all ones.
uint32_t magic SETTINGS_FILE_MAGIC, including the NUL terminator.
uint16_t version Format version, see SETTINGS_FILE_VERSION.

◆ SettingsRecordHeader

struct SettingsRecordHeader

Record header.

Data Fields
uint8_t flags: FLAGS_BITS Active-low SETTINGS_FLAG_* bits.
uint8_t key_hash pbl_crc8_reversed() of the key, to skip non-matching records quickly.
unsigned int key_len: KEY_LEN_BITS Key length in bytes.
uint32_t last_modified Modification time, UTC seconds.
unsigned int val_len: VAL_LEN_BITS Value length in bytes, 0 for a deleted record.

◆ SettingsRawIter

struct SettingsRawIter

Cursor over the records of a settings file.

Guarantees the upper layers never lose track of their position in the file (reading data as a header, or past the end of a key or value), and turns unexpected conditions from bad logic or corruption into a controlled failure.

Data Fields
int fd PFS file descriptor.
SettingsFileHeader file_hdr File header.
const char * file_name File name, for diagnostics.
SettingsRecordHeader hdr Header of the current record.
int hdr_pos Offset of the current record header.
int resumed_pos Offset of the record a search began or resumed from, so a search can wrap around from the end to the beginning.

Only changed by settings_raw_iter_begin() and settings_raw_iter_resume().

Macro Definition Documentation

◆ FLAGS_BITS

#define FLAGS_BITS   6

Width of the flags field of a record header.

◆ KEY_LEN_BITS

#define KEY_LEN_BITS   7

Width of the key length field of a record header.

◆ SETTINGS_EOF_MARKER

#define SETTINGS_EOF_MARKER   ((1 << VAL_LEN_BITS) - 1)

Value length of the all-ones header that marks the end of the records.

◆ SETTINGS_FILE_MAGIC

#define SETTINGS_FILE_MAGIC   "set"

Magic at the start of every settings file.

◆ SETTINGS_FILE_VERSION

#define SETTINGS_FILE_VERSION   1

Current settings file format version.

◆ SETTINGS_FLAG_OVERWRITE_COMPLETE

#define SETTINGS_FLAG_OVERWRITE_COMPLETE   (1 << 2)

A newer record for the same key is complete; this one is dead.

◆ SETTINGS_FLAG_OVERWRITE_STARTED

#define SETTINGS_FLAG_OVERWRITE_STARTED   (1 << 1)

A newer record for the same key is being written.

◆ SETTINGS_FLAG_SYNCED

#define SETTINGS_FLAG_SYNCED   (1 << 3)

Record is in sync with the phone.

◆ SETTINGS_FLAG_WRITE_COMPLETE

#define SETTINGS_FLAG_WRITE_COMPLETE   (1 << 0)

Record header, key and value are completely written.

◆ SETTINGS_KEY_MAX_LEN

#define SETTINGS_KEY_MAX_LEN   127

Maximum key length in bytes.

◆ SETTINGS_VAL_MAX_LEN

#define SETTINGS_VAL_MAX_LEN   (SETTINGS_EOF_MARKER - 1)

Maximum value length in bytes.

◆ VAL_LEN_BITS

#define VAL_LEN_BITS   11

Width of the value length field of a record header.

Function Documentation

◆ settings_raw_iter_begin()

void settings_raw_iter_begin ( SettingsRawIter *  iter)

Move to the first record.

Parameters
iterIterator.

◆ settings_raw_iter_deinit()

void settings_raw_iter_deinit ( SettingsRawIter *  iter)

Close the underlying file.

Parameters
iterIterator.

◆ settings_raw_iter_end()

bool settings_raw_iter_end ( SettingsRawIter *  iter)

Check whether the iterator is past the last record.

Parameters
iterIterator.
Returns
true at the end of the records.

◆ settings_raw_iter_get_current_record_pos()

int settings_raw_iter_get_current_record_pos ( SettingsRawIter *  iter)

Get the current record position.

Parameters
iterIterator.
Returns
Position, for settings_raw_iter_set_current_record_pos().

◆ settings_raw_iter_get_resumed_record_pos()

int settings_raw_iter_get_resumed_record_pos ( SettingsRawIter *  iter)

Get the position the current search started from.

Parameters
iterIterator.
Returns
Record position.

◆ settings_raw_iter_init()

void settings_raw_iter_init ( SettingsRawIter *  iter,
int  fd,
const char *  file_name 
)

Initialize an iterator and read the file header.

Parameters
[out]iterIterator.
fdOpen PFS file.
file_nameFile name, for diagnostics. Must outlive the iterator.

◆ settings_raw_iter_next()

void settings_raw_iter_next ( SettingsRawIter *  iter)

Move to the next record.

Parameters
iterIterator.

◆ settings_raw_iter_read_key()

void settings_raw_iter_read_key ( SettingsRawIter *  iter,
uint8_t *  key 
)

Read the key of the current record.

Parameters
iterIterator.
[out]keyBuffer of at least the key length.

◆ settings_raw_iter_read_key_val()

void settings_raw_iter_read_key_val ( SettingsRawIter *  iter,
uint8_t *  key_val_out 
)

Read the key and value of the current record in one PFS call.

Parameters
iterIterator.
[out]key_val_outBuffer of at least key length plus value length bytes; receives the key followed by the value.

◆ settings_raw_iter_read_val()

void settings_raw_iter_read_val ( SettingsRawIter *  iter,
uint8_t *  val,
int  val_len 
)

Read the value of the current record.

Parameters
iterIterator.
[out]valValue buffer.
val_lenBytes to read, at most the value length.

◆ settings_raw_iter_resume()

void settings_raw_iter_resume ( SettingsRawIter *  iter)

Start a search from the current record.

Parameters
iterIterator.

◆ settings_raw_iter_set_current_record_pos()

void settings_raw_iter_set_current_record_pos ( SettingsRawIter *  iter,
int  pos 
)

Move to a position from settings_raw_iter_get_current_record_pos().

Parameters
iterIterator.
posRecord position.

◆ settings_raw_iter_write_byte()

void settings_raw_iter_write_byte ( SettingsRawIter *  iter,
int  offset,
uint8_t  byte 
)

Write one byte of the value of the current record in place.

Parameters
iterIterator.
offsetOffset within the value.
byteByte to write.

◆ settings_raw_iter_write_file_header()

void settings_raw_iter_write_file_header ( SettingsRawIter *  iter,
SettingsFileHeader *  file_hdr 
)

Write the file header, for newly created files.

Parameters
iterIterator.
file_hdrHeader to write.

◆ settings_raw_iter_write_header()

void settings_raw_iter_write_header ( SettingsRawIter *  iter,
SettingsRecordHeader *  hdr 
)

Write the header of the current record.

Parameters
iterIterator.
hdrHeader to write; becomes the current header.

◆ settings_raw_iter_write_key()

void settings_raw_iter_write_key ( SettingsRawIter *  iter,
const uint8_t *  key 
)

Write the key of the current record, using the length from its header.

Parameters
iterIterator.
keyKey.

◆ settings_raw_iter_write_key_val()

void settings_raw_iter_write_key_val ( SettingsRawIter *  iter,
const uint8_t *  key_val 
)

Write the key and value of the current record in one PFS call.

Parameters
iterIterator.
key_valKey followed by value, as read by settings_raw_iter_read_key_val().

◆ settings_raw_iter_write_val()

void settings_raw_iter_write_val ( SettingsRawIter *  iter,
const uint8_t *  val 
)

Write the value of the current record, using the length from its header.

Parameters
iterIterator.
valValue.