Browse Source

Add more bank functionality

master
cancel 6 years ago
parent
commit
5eae81300b
  1. 2
      Makefile
  2. 72
      bank.c
  3. 48
      bank.h

2
Makefile

@ -1,4 +1,4 @@
basic_flags := -std=c99 -pipe -Wall -Wpedantic -Wextra -Wconversion -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=int-conversion -D_XOPEN_SOURCE_EXTENDED=1
basic_flags := -std=c99 -pipe -Wall -Wpedantic -Wextra -Wconversion -Werror=implicit-function-declaration -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -D_XOPEN_SOURCE_EXTENDED=1
debug_flags := -DDEBUG -ggdb
sanitize_flags := -fsanitize=address -fsanitize=undefined
# note: -fsanitize=leak not available on at least Mac 10.12

72
bank.c

@ -1,5 +1,18 @@
#include "bank.h"
#define ORCA_BANK_ENTRY_HEADER (sizeof(U32) + sizeof(U8))
#define ORCA_BANK_ENTRY_ALIGN sizeof(Bank_entry)
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_padding(Usz glyph_count) {
return ORCA_BANK_ENTRY_ALIGN -
(ORCA_BANK_ENTRY_HEADER + glyph_count) % ORCA_BANK_ENTRY_ALIGN;
}
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_size(Usz glyph_count) {
return ORCA_BANK_ENTRY_HEADER + bank_entry_padding(glyph_count);
}
void bank_init(Bank* bank) {
bank->data = NULL;
bank->capacity = 0;
@ -21,3 +34,62 @@ void bank_reserve(Bank* bank, Usz entries, Usz avg_count) {
bank->data = realloc(bank->data, new_cap);
}
}
Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Glyph* restrict glyphs, Usz glyph_count) {
assert(index <= ORCA_BANK_INDEX_MAX);
assert(glyph_count <= ORCA_BANK_ENTRY_GLYPHS_MAX);
// no overflow check
Usz new_size = cur_size + bank_entry_size(glyph_count);
if (new_size > bank->capacity)
bank_enlarge_to(bank, new_size);
char* data = bank->data;
Bank_entry* entry =
(Bank_entry*)ORCA_ASSUME_ALIGNED(data, ORCA_BANK_ENTRY_ALIGN);
entry->index = (U32)index;
entry->size = (U8)glyph_count;
data += ORCA_BANK_ENTRY_HEADER;
memcpy(data, glyphs, glyph_count);
#ifndef NDEBUG
Usz padding = bank_entry_padding(glyph_count);
memset(data + glyph_count, 0x1c, padding);
#endif
return new_size;
}
Usz bank_read(char const* bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, Usz num_to_read,
Glyph* restrict dest, Usz dest_count) {
assert(index <= ORCA_BANK_INDEX_MAX);
assert(num_to_read <= ORCA_BANK_ENTRY_GLYPHS_MAX);
Usz offset = *cursor;
Bank_entry* entry;
Usz entry_index;
Usz entry_size;
Usz num_to_copy;
next:
if (offset == bank_size)
goto fail;
entry = (Bank_entry*)ORCA_ASSUME_ALIGNED(bank_data + offset,
ORCA_BANK_ENTRY_ALIGN);
entry_index = entry->index;
if (entry_index > index)
goto fail;
entry_size = entry->size;
if (entry_index < index) {
offset += ORCA_BANK_ENTRY_HEADER + entry_size;
goto next;
}
num_to_copy = dest_count < entry_size ? dest_count : entry_size;
memcpy(dest, bank_data + offset + ORCA_BANK_ENTRY_HEADER, num_to_copy);
if (num_to_copy < dest_count)
memset(dest, '.', dest_count - num_to_copy);
*cursor = ORCA_BANK_ENTRY_HEADER + entry_size;
return num_to_copy;
fail:
memset(dest, '.', dest_count);
*cursor = offset;
return 0;
}

48
bank.h

@ -1,7 +1,7 @@
#include "base.h"
typedef struct {
U32 grid_index;
U32 index;
U8 size;
} Bank_entry;
@ -12,49 +12,17 @@ typedef struct {
typedef size_t Bank_cursor;
#define ORCA_BANK_GRID_INDEX_MAX UINT32_MAX
#define ORCA_BANK_INDEX_MAX UINT32_MAX
#define ORCA_BANK_ENTRY_GLYPHS_MAX UINT8_MAX
#define ORCA_BANK_ENTRY_HEADER (sizeof(U32) + sizeof(U8))
#define ORCA_BANK_ENTRY_ALIGN sizeof(Bank_entry)
void bank_init(Bank* bank);
void bank_deinit(Bank* bank);
void bank_enlarge_to(Bank* bank, Usz bytes);
void bank_reserve_average(Bank* bank, Usz num_entries, Usz avg_glyph_count);
static inline void bank_cursor_reset(Bank_cursor* cursor) { *cursor = 0; }
static inline Usz bank_append(Bank* restrict bank, Usz cur_size, Usz grid_index,
Glyph* restrict glyphs, Usz glyph_count);
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_padding(Usz glyph_count) {
return ORCA_BANK_ENTRY_ALIGN -
(ORCA_BANK_ENTRY_HEADER + glyph_count) % ORCA_BANK_ENTRY_ALIGN;
}
ORCA_FORCE_STATIC_INLINE
Usz bank_entry_size(Usz glyph_count) {
return ORCA_BANK_ENTRY_HEADER + bank_entry_padding(glyph_count);
}
static inline Usz bank_append(Bank* restrict bank, Usz cur_size, Usz grid_index,
Glyph* restrict glyphs, Usz glyph_count) {
assert(grid_index <= ORCA_BANK_GRID_INDEX_MAX);
assert(glyph_count <= ORCA_BANK_ENTRY_GLYPHS_MAX);
// no overflow check
Usz new_size = cur_size + bank_entry_size(glyph_count);
if (new_size > bank->capacity)
bank_enlarge_to(bank, new_size);
char* data = bank->data;
{
Bank_entry* entry =
(Bank_entry*)ORCA_ASSUME_ALIGNED(data, ORCA_BANK_ENTRY_ALIGN);
entry->grid_index = (U32)grid_index;
entry->size = (U8)glyph_count;
}
data += ORCA_BANK_ENTRY_HEADER;
memcpy(data, glyphs, glyph_count);
#ifndef NDEBUG
Usz padding = bank_entry_padding(glyph_count);
memset(data + glyph_count, 0x1c, padding);
#endif
return new_size;
}
Usz bank_append(Bank* restrict bank, Usz cur_size, Usz index,
Glyph* restrict glyphs, Usz glyph_count);
Usz bank_read(char const* bank_data, Usz bank_size,
Bank_cursor* restrict cursor, Usz index, Usz num_to_read,
Glyph* restrict dest, Usz dest_count);

Loading…
Cancel
Save