Finish working phonebook.
This commit is contained in:
67
TLV.cc
67
TLV.cc
@@ -9,7 +9,7 @@ namespace TLV {
|
||||
|
||||
|
||||
static bool
|
||||
space_available(Arena &arena, uint8_t *cursor, uint8_t len)
|
||||
spaceAvailable(Arena &arena, uint8_t *cursor, uint8_t len)
|
||||
{
|
||||
uintptr_t remaining = 0;
|
||||
|
||||
@@ -17,76 +17,95 @@ space_available(Arena &arena, uint8_t *cursor, uint8_t len)
|
||||
return false;
|
||||
}
|
||||
|
||||
remaining = (uintptr_t)cursor - (uintptr_t)arena.store;
|
||||
remaining = arena.size - remaining;
|
||||
remaining = (uintptr_t)cursor - (uintptr_t)arena.Store;
|
||||
remaining = arena.Size - remaining;
|
||||
return ((size_t)remaining >= ((size_t)len+2));
|
||||
}
|
||||
|
||||
static inline void
|
||||
clearUnused(Record &rec)
|
||||
{
|
||||
uint8_t trail = TLV_MAX_LEN-rec.Len;
|
||||
|
||||
memset(rec.Val+rec.Len, 0, trail);
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
write_to_memory(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
WriteToMemory(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
{
|
||||
// If cursor is NULL, the user needs us to select an empty
|
||||
// slot for the record. If we can't find one, that's an
|
||||
// error.
|
||||
//
|
||||
// If, however, the user gives us a cursor, we'll trust it
|
||||
// (though space_available will sanity check that cursor).
|
||||
// (though spaceAvailable will sanity check that cursor).
|
||||
if (cursor == NULL) {
|
||||
cursor = find_empty(arena, cursor);
|
||||
cursor = FindEmpty(arena, cursor);
|
||||
if (cursor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!space_available(arena, cursor, rec.Len)) {
|
||||
if (!spaceAvailable(arena, cursor, rec.Len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(cursor, &rec, REC_SIZE(rec));
|
||||
cursor = skip_record(rec, cursor);
|
||||
cursor = SkipRecord(rec, cursor);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_record(Record &rec, uint8_t tag, uint8_t len, const char *val)
|
||||
SetRecord(Record &rec, uint8_t tag, uint8_t len, const char *val)
|
||||
{
|
||||
uint8_t trail = TLV_MAX_LEN-len;
|
||||
|
||||
rec.Tag = tag;
|
||||
rec.Len = len;
|
||||
memcpy(rec.Val, val, len);
|
||||
memset(rec.Val+len, 0, trail);
|
||||
clearUnused(rec);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
read_from_memory(Record &rec, uint8_t *cursor)
|
||||
ReadFromMemory(Record &rec, uint8_t *cursor)
|
||||
{
|
||||
rec.Tag = cursor[0];
|
||||
rec.Len = cursor[1];
|
||||
memcpy(rec.Val, cursor+2, rec.Len);
|
||||
clearUnused(rec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns a pointer to memory where the record was found,
|
||||
* e.g. find_tag(...)[0] is the tag of the found record.
|
||||
* e.g. FindTag(...)[0] is the tag of the found record.
|
||||
*/
|
||||
uint8_t *
|
||||
find_tag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
FindTag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
{
|
||||
cursor = LocateTag(arena, cursor, rec);
|
||||
if (rec.Tag != TAG_EMPTY) {
|
||||
cursor = SkipRecord(rec, cursor);
|
||||
}
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
LocateTag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
{
|
||||
uint8_t tag, len;
|
||||
|
||||
if (cursor == NULL) {
|
||||
cursor = arena.store;
|
||||
cursor = arena.Store;
|
||||
}
|
||||
|
||||
while ((tag = cursor[0]) != rec.Tag) {
|
||||
len = cursor[1];
|
||||
if (!space_available(arena, cursor, len)) {
|
||||
if (!spaceAvailable(arena, cursor, len)) {
|
||||
return NULL;
|
||||
}
|
||||
cursor += len;
|
||||
@@ -98,40 +117,38 @@ find_tag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
}
|
||||
|
||||
if (tag != TAG_EMPTY) {
|
||||
read_from_memory(rec, cursor);
|
||||
cursor = skip_record(rec, cursor);
|
||||
ReadFromMemory(rec, cursor);
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
find_empty(Arena &arena, uint8_t *cursor) {
|
||||
FindEmpty(Arena &arena, uint8_t *cursor) {
|
||||
Record rec;
|
||||
|
||||
rec.Tag = TAG_EMPTY;
|
||||
return find_tag(arena, cursor, rec);
|
||||
return FindTag(arena, cursor, rec);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t *
|
||||
skip_record(Record &rec, uint8_t *cursor)
|
||||
SkipRecord(Record &rec, uint8_t *cursor)
|
||||
{
|
||||
return (uint8_t *)((uintptr_t)cursor + rec.Len + 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_record(Arena &arena, uint8_t *cursor)
|
||||
DeleteRecord(Arena &arena, uint8_t *cursor)
|
||||
{
|
||||
//
|
||||
if (cursor == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t len = cursor[1] + 2;
|
||||
uint8_t *stop = arena.store + arena.size;
|
||||
uint8_t *stop = arena.Store + arena.Size;
|
||||
|
||||
stop -= len;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user