shithub: orca

Download patch

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);