ref: 5eae81300b4e025bba2aa6185be9e5a6d67861d2
parent: 7636f011e455a9d8a7e3ef6a0222801443886b45
author: cancel <cancel@cancel.fm>
date: Wed Nov 28 06:11:12 EST 2018
Add more bank functionality
--- a/Makefile
+++ b/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
--- a/bank.c
+++ b/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;
@@ -20,4 +33,63 @@
Usz new_cap = orca_round_up_power2(total_bytes);
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;
}
--- a/bank.h
+++ b/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 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);