view dowa/dowa.h @ 82:1ded13720541

Added new logos.
author June Park <parkjune1995@gmail.com>
date Thu, 01 Jan 2026 12:45:22 -0800
parents 4b96794c8d59
children 655ea0b661fd
line wrap: on
line source

#ifndef DOWA
#define DOWA

#include <stdio.h>
#include <string.h> // strdup, strlen, memcmp, memcpy
#include <stdlib.h> // malloc, free, realloc
#include <assert.h> // mostly for TODO
#include <stddef.h> // size_t

#ifdef DIRECTORY
// Only for linux and mac since window do not support.
// Maybe move this into seobeo file directly?
#include <dirent.h> // some functions loop through files
#endif

#include <math.h> // I am not re-writing stuff I guess...

#include <sys/stat.h>
#include <limits.h>

#include "dowa_internal.h"

// DLAPI macro for DLL export/import
#ifndef DLAPI
  #ifdef _WIN32
    #ifdef DOWA_EXPORTS
      #define DLAPI __declspec(dllexport)
    #else
      #define DLAPI __declspec(dllimport)
    #endif
  #else
    #define DLAPI extern
  #endif
#endif

#define HASH_KEY_NUMBER 5381
#define ONE_MEGA_BYTE   1048576
#define TRUE  1
#define FALSE 0
#define DOWA_HASH_BUCKET_SIZE 8
#define DOWA_HASH_CACHE_LINE_SIZE 64

#define Dowa_Free(p) do { \
  if (p) {                \
    free(p);              \
    (p) = NULL;           \
  }                       \
} while (0)

// Fixed-width integer types
typedef unsigned long long   uint64;
typedef long long            int64;
typedef unsigned int         uint32;
typedef int                  int32;
typedef unsigned short       uint16;
typedef short                int16;
typedef unsigned char        uint8;
typedef char                 int8;
typedef char                 boolean;

// --- Arena Allocator --- //
typedef struct {
  char   *buffer;
  size_t  offset;
  size_t  capacity;
} Dowa_Arena;

DLAPI Dowa_Arena *Dowa_Arena_Create(size_t capacity);
DLAPI void       *Dowa_Arena_Allocate(Dowa_Arena *p_arena, size_t size);
DLAPI void       *Dowa_Arena_Allocate_Aligned(Dowa_Arena *p_arena, size_t size, size_t alignment);
DLAPI void        Dowa_Arena_Free(Dowa_Arena *p_arena);
DLAPI void       *Dowa_Arena_Copy(Dowa_Arena *p_arena, const void *p_src, size_t size);
DLAPI void        Dowa_Arena_Reset(Dowa_Arena *p_arena);
DLAPI size_t      Dowa_Arena_Get_Used(Dowa_Arena *p_arena);
DLAPI size_t      Dowa_Arena_Get_Remaining(Dowa_Arena *p_arena);

// --- New stb_ds-style Data Structures --- //

// Allocator type enum
typedef enum {
  DOWA_ALLOCATOR_MALLOC = 0,
  DOWA_ALLOCATOR_ARENA = 1
} Dowa_Allocator_Type;

// Array header (prefix to actual array data)
typedef struct {
  size_t length;
  size_t capacity;
  uint8  allocator_type;
  Dowa_Arena* p_arena;
  void* p_hash;
} Dowa_Array_Header;

// Hash bucket (64 bytes for cache line alignment)
typedef struct {
  uint32 hash[DOWA_HASH_BUCKET_SIZE];
  uint32 index[DOWA_HASH_BUCKET_SIZE];
} Dowa_Hash_Bucket;

// Hash index structure (separate from value array)
typedef struct {
  size_t bucket_count;
  size_t item_count;
  size_t tombstone_count;
  uint8  allocator_type;
  Dowa_Arena* p_arena;
  Dowa_Hash_Bucket* p_buckets;
} Dowa_Hash_Index;

// Key-Value pair declaration macro
#define Dowa_KV(K, V) struct { K key; V value; }

// Internal header accessor
#define dowa__header(a) ((Dowa_Array_Header*)(a) - 1)

// --- Array Macros --- //

#define Dowa_Array_Length(a)   ((a) ? dowa__header(a)->length : 0)
#define Dowa_Array_Capacity(a) ((a) ? dowa__header(a)->capacity : 0)

#define Dowa_Array_Push(a, v) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), 0, NULL), \
   (a)[dowa__header(a)->length++] = (v))

#define Dowa_Array_Push_Arena(a, v, arena) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), 0, (arena)), \
   (a)[dowa__header(a)->length++] = (v))

#define Dowa_Array_Pop(a) ((a)[--dowa__header(a)->length])

#define Dowa_Array_Clear(a) ((a) ? (dowa__header(a)->length = 0) : 0)

#define Dowa_Array_Free(a) ((a) ? (dowa__array_free((a)), (a) = NULL) : 0)

#define Dowa_Array_Reserve(a, n) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), (n), NULL))

#define Dowa_Array_Reserve_Arena(a, n, arena) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), (n), (arena)))

// --- HashMap Macros --- //

#define Dowa_HashMap_Get(m, k) \
  dowa__hashmap_get((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Get_Ptr(m, k) \
  dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Push(m, k, v) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), strlen(k) + 1, NULL); \
    void* p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Push_Arena(m, k, v, arena) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), strlen(k) + 1, (arena)); \
    void* p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Has_Key(m, k) \
  dowa__hashmap_has_key((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Delete(m, k) \
  dowa__hashmap_delete((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Clear(m) dowa__hashmap_clear((m), sizeof(*(m)))

#define Dowa_HashMap_Free(m) ((m) ? (dowa__hashmap_free((m)), (m) = NULL) : 0)

#define Dowa_HashMap_Count(m) dowa__hashmap_count(m)

#define Dowa_HashMap_Get_Binary(m, k, ksize) \
  dowa__hashmap_get((m), sizeof(*(m)), (k), (ksize))

#define Dowa_HashMap_Get_Ptr_Binary(m, k, ksize) \
  dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize))

#define Dowa_HashMap_Push_Binary(m, k, ksize, v) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), (ksize), NULL); \
    void* p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize)); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Push_Binary_Arena(m, k, ksize, v, arena) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), (ksize), (arena)); \
    void* p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize)); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

// --- Array Core Functions --- //

DLAPI void* dowa__array_grow(void* p_array, size_t element_size, size_t minimum_capacity, Dowa_Arena* p_arena);
DLAPI void  dowa__array_free(void* p_array);

// --- HashMap Core Functions --- //

DLAPI uint32  dowa__hash_bytes(void* p_key, size_t key_size);
DLAPI void*   dowa__hashmap_get(void* p_map, size_t element_size, void* p_key, size_t key_size);
DLAPI void*   dowa__hashmap_get_ptr(void* p_map, size_t element_size, void* p_key, size_t key_size);
DLAPI void*   dowa__hashmap_push(void* p_map, size_t element_size, void* p_key, size_t key_size, Dowa_Arena* p_arena);
DLAPI boolean dowa__hashmap_has_key(void* p_map, size_t element_size, void* p_key, size_t key_size);
DLAPI void    dowa__hashmap_delete(void* p_map, size_t element_size, void* p_key, size_t key_size);
DLAPI void    dowa__hashmap_clear(void* p_map, size_t element_size);
DLAPI void    dowa__hashmap_free(void* p_map);
DLAPI size_t  dowa__hashmap_count(void* p_map);

// --- String Manipulation --- //

DLAPI  char      *Dowa_String_Slice(char *from, size_t start, size_t end, Dowa_Arena *p_arena);
DLAPI  char     **Dowa_String_Split(char *from, char *token, int32 from_length, int32 token_length, Dowa_Arena *p_arena);
DLAPI  char      *Dowa_String_Copy_Arena(char *from, Dowa_Arena *p_arena);
DLAPI int32       Dowa_String_Pos_Find(const char *p_from, const char *p_value, const size_t from_length, const size_t value_length);
DLAPI char       *Dowa_String_Find(const char *p_from, const char *p_value, const size_t from_length, const size_t value_length);
DLAPI int32       Dowa_String_Pos_Find_Char(const char *p_from, int c, int32 from_length);
DLAPI char       *Dowa_String_Find_Char(const char *p_from, int c, int32 from_length);


#endif