add object module from corelib

This commit is contained in:
2024-10-24 19:24:54 +01:00
parent 7eb0fc5581
commit fa6ebe6a84
38 changed files with 5606 additions and 24 deletions

View File

View File

@@ -0,0 +1,304 @@
#ifndef BLUELIB_ARRAY_H_
#define BLUELIB_ARRAY_H_
#include <blue/core/iterator.h>
#include <blue/core/misc.h>
#include <blue/core/status.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
/**
* Cast a generic b_object pointer to an b_array pointer.
*/
#define B_ARRAY(p) ((b_array *)(p))
/**
* Iterate through each object in an b_array.
*
* This should be used for read-only iterations only. Adding or removing objects
* while iterating though an array using b_array_foreach is NOT supported.
*
* @param it A pointer to an b_array_iterator. This iterator will contain the
* current object reference for the current loop iteration.
* @param array A pointer to the b_array to iterate over.
*/
#define b_array_foreach(it, array) \
for (int z__b_unique_name() = b_array_iterator_begin(array, it); \
(it)->value != NULL; b_array_iterator_next(it))
#ifdef __cplusplus
extern "C" {
#endif
/**
* A heterogeneous array of objects. b_array only stores references
* to the objects that it contains, not the object data itself.
*
* b_array stores pointers to objects in a single contiguous array,
* but this is an implementation detail that may change in the future.
* Users of b_array should not rely on this being the case.
*/
typedef struct b_array b_array;
/**
* Iterator for traversing the contents of an b_array.
*
* The iterator provides the current b_object `value`, as well
* as the index `i` of that value within the array.
*
* Any members whose names begin with _ (underscore) are reserved
* and should not be accessed.
*/
typedef struct b_array_iterator {
b_iterator _base;
b_array *_a;
/** The index of the current value */
size_t i;
/** The current value */
b_object *value;
} b_array_iterator;
/**
* Creates an empty b_array.
*
* @return A pointer to the new array, or NULL if an error occurred.
*/
extern b_array *b_array_create(void);
/**
* Creates an b_array initialised with the contents of the provided b_object
* pointer array. The b_array will take a reference to each object specified in
* `values`, and will increment the reference count. The order of objects in the
* new b_array will be the same as the order of objects in `values`. Any NULL
* pointers in the `values` array will be ignored, and will not result in gaps
* in the created b_array. However, `nr_values` should be large enough to cover
* the final non-NULL pointer in `values`, including any NULL pointers
* in-between.
*
* @param values The list of object pointers which should make up the contents
* of the new b_array.
* @param nr_values The size of the `values` array.
* @return A pointer to the new b_array, or NULL if an error occurred.
*/
extern b_array *b_array_create_with_values(
b_object *const *values, size_t nr_values);
/**
* Increment the reference counter of an b_array.
*
* @param array The b_array to reference.
* @return The b_array pointer that was passed to the function.
*/
static inline b_array *b_array_retain(b_array *array)
{
return B_ARRAY(b_retain(B_OBJECT(array)));
}
/**
* Decrement the reference counter of an b_array, destroying the array if it reaches zero.
* @param array The b_array reference to release.
*/
static inline void b_array_release(b_array *array)
{
b_release(B_OBJECT(array));
}
/**
* Remove all object references from an b_array, resetting the size of the array to zero.
* The reference counts of all objects in the array will be decremented.
*
* @param array The b_array to clear.
*/
extern void b_array_clear(b_array *array);
/**
* Inserts an object at the end of an b_array. The reference count of the object
* will be incremented.
*
* @param array The b_array to append the object to.
* @param value The object to append.
* @return B_SUCCESS if the object was appended successfully, or an error code if an error occurred.
*/
extern b_status b_array_append(b_array *array, b_object *value);
/**
* Inserts an object at the beginning of an b_array. The reference count of the object
* will be incremented. All other objects in the array will be moved to make space
* for the object being pre-pended.
*
* @param array The b_array to prepend the object to.
* @param value The object to prepend.
* @return B_SUCCESS if the object was prepended successfully, or an error code if an error occurred.
*/
extern b_status b_array_prepend(b_array *array, b_object *value);
/**
* Inserts an object into an b_array at a given index. The reference count of the object
* will be incremented. If the specified index is at the beginning or mid-way through
* the array (i.e. not at the end), some or all of the objects already in the array will
* be moved to make space for the object being inserted.
*
* @param array The b_array to insert the object into.
* @param value The object to insert.
* @param at The index to insert the object at. If the index is `B_NPOS`, the object will
* be inserted at the end of the b_array.
* @return B_SUCCESS if the object was inserted, or a status code describing any error that occurred.
*/
extern b_status b_array_insert(b_array *array, b_object *value, size_t at);
/**
* Removes the object at the specified index from an b_array. The reference count
* of the removed object will be decremented. If the specified index is at the beginning
* or mid-way through the array (i.e. not at the end), the remaining objects will be moved
* to fill the empty space created by the object's removal.
*
* @param array The b_array to remove the object from.
* @param at The index of the object to be removed.
* @return B_SUCCESS if the object was removed, or a status code describing any error that occurred.
*/
extern b_status b_array_remove(b_array *array, size_t at);
/**
* Removes the object at the beginning of an b_array. The reference count
* of the removed object will be decremented. The remaining objects will be moved
* to fill the empty space created by the object's removal.
*
* @param array The b_array to remove the object from.
* @return B_SUCCESS if the object was removed, or a status code describing any error that occurred.
*/
extern b_status b_array_remove_front(b_array *array);
/**
* Removes the object at the end of an b_array. The reference count
* of the removed object will be decremented.
*
* @param array The b_array to remove the object from.
* @return B_SUCCESS if the object was removed, or a status code describing any error that occurred.
*/
extern b_status b_array_remove_back(b_array *array);
/**
* Removes the object at the specified index of an b_array, and returns a
* pointer to it. The reference count of the removed object will NOT be
* decremented. The caller becomes the owner of the array's reference to the
* object. If the specified index is at the beginning or mid-way through the
* array (i.e. not at the end), the remaining objects will be moved to fill the
* empty space created by the object's removal.
*
* @param array The b_array to remove the object from.
* @param at The index of the object to be removed.
* @return An pointer to the removed object. This pointer is owned by the
* caller. Returns NULL if an error occurred.
*/
extern b_object *b_array_pop(b_array *array, size_t at);
/**
* Removes the object at the beginning of an b_array, and returns a pointer to
* it. The reference count of the removed object will NOT be decremented. The
* caller becomes the owner of the array's reference to the object. The
* remaining objects in the b_array will be moved to fill the empty space left
* by the removed object.
*
* @param array The b_array to remove the object from.
* @return An pointer to the removed object. This pointer is owned by the
* caller. Returns NULL if an error occurred.
*/
extern b_object *b_array_pop_front(b_array *array);
/**
* Removes the object at the end of an b_array, and returns a pointer to it. The
* reference count of the removed object will NOT be decremented. The caller
* becomes the owner of the array's reference to the object.
*
* @param array The b_array to remove the object from.
* @return An pointer to the removed object. This pointer is owned by the
* caller. Returns NULL if an error occurred.
*/
extern b_object *b_array_pop_back(b_array *array);
/**
* Returns an unowned pointer to the object at the given index of an b_array.
* The caller does not own the returned pointer, and MUST NOT release it.
*
* @param array The b_array.
* @param at The index of the object to return.
* @return A pointer to the object at the given index. This pointer is NOT owned
* by the caller. Returns NULL if an error occurred.
*/
extern b_object *b_array_at(const b_array *array, size_t at);
/**
* Returns an owned pointer to the object at the given index of an b_array. The caller owns
* the returned pointer, and must release it when they are finished with it.
*
* @param array The b_array.
* @param at The index of the object to return.
* @return A pointer to the object at the given index. This pointer is owned by the caller.
* Returns NULL if an error occurred.
*/
extern b_object *b_array_get(b_array *array, size_t at);
/**
* Returns the number of objects contained in an b_array.
*
* @param array The b_array.
* @return The number of objects contained in the b_array.
*/
extern size_t b_array_size(const b_array *array);
/**
* Returns the current maximum capacity of an b_array. This represents the
* number of objects that can be stored in an b_array before its internal buffer
* would need to be re-sized.
*
* @param array The b_array.
* @return The maximum capacity of the b_array.
*/
extern size_t b_array_capacity(const b_array *array);
/**
* Initialise an b_array_iterator to pointer to the first object in an b_array.
* If the b_array is empty, then `it` will be an invalid iterator.
*
* @param array
* @param it
* @return Always returns 0.
*/
extern int b_array_iterator_begin(b_array *array, b_array_iterator *it);
/**
* Advances an b_array_iterator to pointer to the next object in an b_array.
* @param it The iterator to advance.
* @return True if the iterator contains a valid reference to an object, or
* False if the iterator has gone past the end of the array.
*/
extern bool b_array_iterator_next(b_array_iterator *it);
/**
* Removes the object pointed to by an b_array_iterator from its container
* b_array, and advances the iterator to the next object in the b_array.
*
* The reference count of the removed object will be decremented.
*
* @param it The iterator whose object should be removed.
* @return B_SUCCESS if the object was removed, or a status code describing the error that occurred.
*/
extern b_status b_array_iterator_erase(b_array_iterator *it);
/**
* Checks whether or not an iterator contains a valid reference to an object.
* An iterator will become invalid if it has moved past the end of the b_array
* it was iterating across, or if b_array_iterator_erase() was called on an
* iterator pointing to the last object in an b_array.
*
* @param it The iterator to check.
* @return True if the iterator is valid. False otherwise.
*/
extern bool b_array_iterator_is_valid(const b_array_iterator *it);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,34 @@
#ifndef BLUELIB_BITMAP_H_
#define BLUELIB_BITMAP_H_
#include <stdbool.h>
typedef unsigned long b_bitmap_word;
#define Z__B_BITS_PER_WORD (8 * sizeof(b_bitmap_word))
#define Z__B_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define B_BITMAP_WORDS(nbits) Z__B_DIV_ROUND_UP(nbits, Z__B_BITS_PER_WORD)
#define B_BITMAP_NPOS ((unsigned int)-1)
#define B_DECLARE_BITMAP(name, nbits) b_bitmap_word name[B_BITMAP_WORDS(nbits)]
extern void b_bitmap_zero(b_bitmap_word *map, unsigned long nbits);
extern void b_bitmap_fill(b_bitmap_word *map, unsigned long nbits);
extern void b_bitmap_set(b_bitmap_word *map, unsigned long bit);
extern void b_bitmap_clear(b_bitmap_word *map, unsigned long bit);
extern bool b_bitmap_check(const b_bitmap_word *map, unsigned long bit);
extern unsigned int b_bitmap_count_set(const b_bitmap_word *map, unsigned long nbits);
extern unsigned int b_bitmap_count_clear(const b_bitmap_word *map, unsigned long nbits);
extern unsigned int b_bitmap_highest_set(const b_bitmap_word *map, unsigned long nbits);
extern unsigned int b_bitmap_highest_clear(const b_bitmap_word *map, unsigned long nbits);
extern unsigned int b_bitmap_lowest_set(const b_bitmap_word *map, unsigned long nbits);
extern unsigned int b_bitmap_lowest_clear(const b_bitmap_word *map, unsigned long nbits);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,33 @@
#ifndef BLUELIB_BUFFER_H_
#define BLUELIB_BUFFER_H_
#include <blue/object/type.h>
#include <blue/object/object.h>
#include <blue/object/status.h>
#include <stddef.h>
#define B_BUFFER(p) ((b_buffer *)(p))
typedef struct b_buffer b_buffer;
extern b_buffer *b_buffer_create(size_t item_sz);
extern b_buffer *b_buffer_create_from_bytes(const void *p, size_t len);
extern b_buffer *b_buffer_create_from_array(const void *p, size_t item_sz, size_t len);
static inline b_buffer *b_buffer_retain(b_buffer *buf) { return B_BUFFER(b_retain(B_OBJECT(buf))); }
static inline void b_buffer_release(b_buffer *buf) { b_release(B_OBJECT(buf)); }
extern void *b_buffer_steal(b_buffer *buf);
extern b_status b_buffer_reserve(b_buffer *buf, size_t capacity);
extern b_status b_buffer_append(b_buffer *dest, const void *p, size_t count);
extern b_status b_buffer_prepend(b_buffer *dest, const void *p, size_t count);
extern b_status b_buffer_insert(b_buffer *dest, const void *p, size_t count, size_t at);
extern b_status b_buffer_clear(b_buffer *str);
extern size_t b_buffer_get_size(const b_buffer *str);
extern size_t b_buffer_get_item_size(const b_buffer *str);
extern size_t b_buffer_get_capacity(const b_buffer *str);
extern void *b_buffer_ptr(const b_buffer *str);
#endif

View File

@@ -0,0 +1,69 @@
#ifndef BLUELIB_DICT_H_
#define BLUELIB_DICT_H_
#include <blue/core/btree.h>
#include <blue/core/misc.h>
#include <blue/core/queue.h>
#include <blue/core/status.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
#define B_DICT(p) ((b_dict *)(p))
#define B_DICT_ITEM(k, v) \
{ \
.key = (k), .value = (v) \
}
#define B_DICT_ITEM_END \
{ \
.key = NULL, .value = NULL \
}
#define b_dict_foreach(it, dict) \
for (int z__b_unique_name() = b_dict_iterator_begin(dict, it); \
(it)->key != NULL; b_dict_iterator_next(it))
typedef struct b_dict b_dict;
typedef struct b_dict_iterator {
b_iterator _base;
size_t i;
const char *key;
b_object *value;
b_dict *_d;
b_btree_node *_cbn;
b_queue_entry *_cqe;
} b_dict_iterator;
typedef struct b_dict_item {
const char *key;
b_object *value;
} b_dict_item;
extern b_dict *b_dict_create(void);
extern b_dict *b_dict_create_with_items(const b_dict_item *items);
static inline b_dict *b_dict_retain(b_dict *dict)
{
return B_DICT(b_retain(B_OBJECT(dict)));
}
static inline void b_dict_release(b_dict *dict)
{
b_release(B_OBJECT(dict));
}
extern b_status b_dict_put(b_dict *dict, const char *key, b_object *value);
extern b_object *b_dict_at(const b_dict *dict, const char *key);
extern b_object *b_dict_get(b_dict *dict, const char *key);
extern bool b_dict_has_key(const b_dict *dict, const char *key);
extern size_t b_dict_get_size(const b_dict *dict);
extern bool b_dict_is_empty(const b_dict *dict);
extern int b_dict_iterator_begin(b_dict *dict, b_dict_iterator *it);
extern bool b_dict_iterator_next(b_dict_iterator *it);
extern b_status b_dict_iterator_erase(b_dict_iterator *it);
extern bool b_dict_iterator_is_valid(const b_dict_iterator *it);
#endif

View File

@@ -0,0 +1,92 @@
#ifndef BLUELIB_HASHMAP_H_
#define BLUELIB_HASHMAP_H_
#include <blue/core/btree.h>
#include <blue/core/misc.h>
#include <blue/core/queue.h>
#include <blue/core/status.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
#define B_HASHMAP(p) ((b_hashmap *)(p))
#define B_HASHMAP_KEY(k, ks) \
{ \
.key_data = (k), .key_size = (ks) \
}
#define B_HASHMAP_VALUE(v, vs) \
{ \
.value_data = (v), .value_size = (vs) \
}
#define B_HASHMAP_ITEM(k, ks, v, vs) \
{ \
.key = B_HASHMAP_KEY(k, ks), .value = B_HASHMAP_VALUE(v, vs) \
}
#define B_HASHMAP_ITEM_END \
{ \
.key = {}, .value = {} \
}
#define b_hashmap_foreach(it, hashmap) \
for (int z__b_unique_name() = b_hashmap_iterator_begin(hashmap, it); \
(it)->key != NULL; b_hashmap_iterator_next(it))
typedef struct b_hashmap b_hashmap;
typedef struct b_hashmap_key {
const void *key_data;
size_t key_size;
bool key_owned;
} b_hashmap_key;
typedef struct b_hashmap_value {
void *value_data;
size_t value_size;
bool value_owned;
} b_hashmap_value;
typedef struct b_hashmap_item {
b_hashmap_key key;
b_hashmap_value value;
} b_hashmap_item;
typedef struct b_hashmap_iterator {
b_iterator _base;
size_t i;
const b_hashmap_key *key;
const b_hashmap_value *value;
b_hashmap *_h;
b_btree_node *_cbn;
b_queue_entry *_cqe;
} b_hashmap_iterator;
extern b_hashmap *b_hashmap_create(void);
extern b_hashmap *b_hashmap_create_with_items(const b_hashmap_item *items);
static inline b_hashmap *b_hashmap_retain(b_hashmap *hashmap)
{
return B_HASHMAP(b_retain(B_OBJECT(hashmap)));
}
static inline void b_hashmap_release(b_hashmap *hashmap)
{
b_release(B_OBJECT(hashmap));
}
extern b_status b_hashmap_put(
b_hashmap *hashmap, const b_hashmap_key *key, const b_hashmap_value *value);
extern const b_hashmap_value *b_hashmap_get(
const b_hashmap *hashmap, const b_hashmap_key *key);
extern bool b_hashmap_has_key(const b_hashmap *hashmap, const b_hashmap_key *key);
extern size_t b_hashmap_get_size(const b_hashmap *hashmap);
extern bool b_hashmap_is_empty(const b_hashmap *hashmap);
extern int b_hashmap_iterator_begin(b_hashmap *hashmap, b_hashmap_iterator *it);
extern bool b_hashmap_iterator_next(b_hashmap_iterator *it);
extern b_status b_hashmap_iterator_erase(b_hashmap_iterator *it);
extern bool b_hashmap_iterator_is_valid(const b_hashmap_iterator *it);
#endif

View File

@@ -0,0 +1,285 @@
#ifndef BLUELIB_NUMBER_H
#define BLUELIB_NUMBER_H
#include <blue/object/object.h>
#include <blue/object/type.h>
#include <stdbool.h>
#define B_NUMBER(p) ((b_number *)(p))
#define B_INT8(v) (b_number_create_int8(v))
#define B_INT16(v) (b_number_create_int16(v))
#define B_INT32(v) (b_number_create_int32(v))
#define B_INT64(v) (b_number_create_int64(v))
#define B_FLOAT32(v) (b_number_create_float32(v))
#define B_FLOAT64(v) (b_number_create_float64(v))
#define B_CHAR(v) (b_number_create_char(v))
#define B_SHORT(v) (b_number_create_short(v))
#define B_INT(v) (b_number_create_int(v))
#define B_LONG(v) (b_number_create_long(v))
#define B_LONGLONG(v) (b_number_create_longlong(v))
#define B_FLOAT(v) (b_number_create_float(v))
#define B_DOUBLE(v) (b_number_create_double(v))
#define B_SIZE_T(v) (b_number_create_size_t(v))
#define B_RV_INT8(v) B_RV(b_number_create_int8(v))
#define B_RV_INT16(v) B_RV(b_number_create_int16(v))
#define B_RV_INT32(v) B_RV(b_number_create_int32(v))
#define B_RV_INT64(v) B_RV(b_number_create_int64(v))
#define B_RV_FLOAT32(v) B_RV(b_number_create_float32(v))
#define B_RV_FLOAT64(v) B_RV(b_number_create_float64(v))
#define B_RV_CHAR(v) B_RV(b_number_create_char(v))
#define B_RV_SHORT(v) B_RV(b_number_create_short(v))
#define B_RV_INT(v) B_RV(b_number_create_int(v))
#define B_RV_LONG(v) B_RV(b_number_create_long(v))
#define B_RV_LONGLONG(v) B_RV(b_number_create_longlong(v))
#define B_RV_FLOAT(v) B_RV(b_number_create_float(v))
#define B_RV_DOUBLE(v) B_RV(b_number_create_double(v))
#define B_RV_SIZE_T(v) B_RV(b_number_create_size_t(v))
#define B_NUMBER_IVAL(p) (b_number_get_size_t(p))
#define B_NUMBER_FVAL(p) (b_number_get_double(p))
typedef struct b_number b_number;
typedef enum b_number_type {
B_NUMBER_INT8,
B_NUMBER_INT16,
B_NUMBER_INT32,
B_NUMBER_INT64,
B_NUMBER_FLOAT32,
B_NUMBER_FLOAT64,
B_NUMBER_CHAR,
B_NUMBER_SHORT,
B_NUMBER_INT,
B_NUMBER_LONG,
B_NUMBER_LONGLONG,
B_NUMBER_FLOAT,
B_NUMBER_DOUBLE,
B_NUMBER_SIZE_T,
B_NUMBER_HANDLE,
B_NUMBER_TYPE_COUNT,
B_NUMBER_BYTE = B_NUMBER_INT8,
B_NUMBER_WORD = B_NUMBER_INT16,
B_NUMBER_DWORD = B_NUMBER_INT32,
B_NUMBER_QWORD = B_NUMBER_INT64,
} b_number_type;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint16_t)];
int16_t i_val;
uint16_t i_uval;
};
} b_i16;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint32_t)];
int32_t i_val;
uint32_t i_uval;
};
} b_i32;
typedef struct {
union {
unsigned char i_bytes[sizeof(uint64_t)];
int64_t i_val;
uint64_t i_uval;
};
} b_i64;
extern b_number *b_number_create(b_number_type type, void *value_ptr);
static inline b_number *b_number_retain(b_number *number)
{
return B_NUMBER(b_retain(B_OBJECT(number)));
}
static inline void b_number_release(b_number *number)
{
b_release(B_OBJECT(number));
}
static inline b_number *b_number_create_int8(int8_t value)
{
return b_number_create(B_NUMBER_INT8, &value);
}
static inline b_number *b_number_create_int16(int16_t value)
{
return b_number_create(B_NUMBER_INT16, &value);
}
static inline b_number *b_number_create_int32(int32_t value)
{
return b_number_create(B_NUMBER_INT32, &value);
}
static inline b_number *b_number_create_int64(int64_t value)
{
return b_number_create(B_NUMBER_INT64, &value);
}
static inline b_number *b_number_create_float32(float value)
{
return b_number_create(B_NUMBER_FLOAT32, &value);
}
static inline b_number *b_number_create_float64(double value)
{
return b_number_create(B_NUMBER_FLOAT64, &value);
}
static inline b_number *b_number_create_char(char value)
{
return b_number_create(B_NUMBER_CHAR, &value);
}
static inline b_number *b_number_create_short(short value)
{
return b_number_create(B_NUMBER_SHORT, &value);
}
static inline b_number *b_number_create_int(int value)
{
return b_number_create(B_NUMBER_INT, &value);
}
static inline b_number *b_number_create_long(long value)
{
return b_number_create(B_NUMBER_LONG, &value);
}
static inline b_number *b_number_create_longlong(long long value)
{
return b_number_create(B_NUMBER_LONGLONG, &value);
}
static inline b_number *b_number_create_float(float value)
{
return b_number_create(B_NUMBER_FLOAT, &value);
}
static inline b_number *b_number_create_double(double value)
{
return b_number_create(B_NUMBER_DOUBLE, &value);
}
static inline b_number *b_number_create_size_t(size_t value)
{
return b_number_create(B_NUMBER_SIZE_T, &value);
}
extern b_number_type b_number_get_type(const b_number *number);
extern int b_number_get_value(
const b_number *number, b_number_type type, void *value_ptr);
static inline int8_t b_number_get_int8(const b_number *number)
{
int8_t v;
b_number_get_value(number, B_NUMBER_INT8, &v);
return v;
}
static inline int16_t b_number_get_int16(const b_number *number)
{
int16_t v;
b_number_get_value(number, B_NUMBER_INT16, &v);
return v;
}
static inline int32_t b_number_get_int32(const b_number *number)
{
int32_t v;
b_number_get_value(number, B_NUMBER_INT32, &v);
return v;
}
static inline int64_t b_number_get_int64(const b_number *number)
{
int64_t v;
b_number_get_value(number, B_NUMBER_INT64, &v);
return v;
}
static inline float b_number_get_float32(const b_number *number)
{
float v;
b_number_get_value(number, B_NUMBER_FLOAT32, &v);
return v;
}
static inline double b_number_get_float64(const b_number *number)
{
double v;
b_number_get_value(number, B_NUMBER_FLOAT64, &v);
return v;
}
static inline char b_number_get_char(const b_number *number)
{
char v;
b_number_get_value(number, B_NUMBER_CHAR, &v);
return v;
}
static inline short b_number_get_short(const b_number *number)
{
short v;
b_number_get_value(number, B_NUMBER_SHORT, &v);
return v;
}
static inline int b_number_get_int(const b_number *number)
{
int v;
b_number_get_value(number, B_NUMBER_INT, &v);
return v;
}
static inline long b_number_get_long(const b_number *number)
{
long v;
b_number_get_value(number, B_NUMBER_LONG, &v);
return v;
}
static inline long long b_number_get_longlong(const b_number *number)
{
long long v;
b_number_get_value(number, B_NUMBER_LONGLONG, &v);
return v;
}
static inline float b_number_get_float(const b_number *number)
{
float v;
b_number_get_value(number, B_NUMBER_FLOAT, &v);
return v;
}
static inline double b_number_get_double(const b_number *number)
{
double v;
b_number_get_value(number, B_NUMBER_DOUBLE, &v);
return v;
}
static inline size_t b_number_get_size_t(const b_number *number)
{
size_t v;
b_number_get_value(number, B_NUMBER_SIZE_T, &v);
return v;
}
extern bool b_number_is_integer(const b_number *number);
extern bool b_number_is_float(const b_number *number);
extern size_t b_number_data_size(const b_number *number);
extern b_i16 b_i16_htob(uint16_t v);
extern b_i16 b_i16_htos(uint16_t v);
extern uint16_t b_i16_btoh(b_i16 v);
extern uint16_t b_i16_stoh(b_i16 v);
extern b_i32 b_i32_htob(uint32_t v);
extern b_i32 b_i32_htos(uint32_t v);
extern uint32_t b_i32_btoh(b_i32 v);
extern uint32_t b_i32_stoh(b_i32 v);
extern b_i64 b_i64_htob(uint64_t v);
extern b_i64 b_i64_htos(uint64_t v);
extern uint64_t b_i64_btoh(b_i64 v);
extern uint64_t b_i64_stoh(b_i64 v);
#endif

View File

@@ -0,0 +1,38 @@
#ifndef BLUELIB_OBJECT_H_
#define BLUELIB_OBJECT_H_
#include <blue/object/type.h>
#define B_OBJECT(p) ((b_object *)(p))
#define B_TYPEOF(object) ((struct b_object *)(object)->ob_type)
#define B_TYPEID(object) (b_typeid(B_OBJECT(object)))
#define B_RV(p) (b_make_rvalue(B_OBJECT(p)))
#define B_RVT(t, p) ((t *)(b_make_rvalue(B_OBJECT(p))))
struct b_string;
struct b_stringstream;
typedef enum b_comparison_result {
B_LESS = -1,
B_EQUAL = 0,
B_GREATER = 1,
} b_comparison_result_t;
typedef struct b_object {
unsigned int ob_ref;
const struct b_object_type *ob_type;
} b_object;
extern b_object *b_make_rvalue(b_object *obj);
extern b_object *b_retain(b_object *obj);
extern void b_release(b_object *obj);
extern void b_to_string(b_object *obj, struct b_stringstream *out);
extern b_object_type_id b_typeid(const b_object *obj);
extern b_comparison_result_t b_compare(const b_object *a, const b_object *b);
#endif

View File

@@ -0,0 +1,77 @@
#ifndef BLUELIB_STRING_H_
#define BLUELIB_STRING_H_
#include <blue/core/status.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
#define B_STRING(p) ((b_string *)(p))
#define B_CSTR(s) (b_string_create_from_cstr(s))
#define B_RV_CSTR(s) (B_RV(b_string_create_from_cstr(s)))
typedef struct b_string b_string;
typedef enum b_strlen_flags {
B_STRLEN_NORMAL = 0,
B_STRLEN_IGNORE_ESC = 0x01u,
} b_strlen_flags;
typedef struct b_strv_builder {
char *strv_buf;
size_t strv_len;
size_t strv_max;
unsigned char strv_alloc;
} b_strv_builder;
extern b_string *b_string_create(void);
extern b_string *b_string_create_from_cstr(const char *s);
extern b_string *b_string_create_from_c(char c, size_t count);
static inline b_string *b_string_retain(b_string *str)
{
return B_STRING(b_retain(B_OBJECT(str)));
}
static inline void b_string_release(b_string *str)
{
b_release(B_OBJECT(str));
}
extern char *b_string_steal(b_string *str);
extern b_status b_string_reserve(b_string *str, size_t capacity);
extern void b_string_append_s(b_string *dest, const b_string *src);
extern void b_string_append_cstr(b_string *dest, const char *src);
extern void b_string_append_cstrf(b_string *dest, const char *format, ...);
extern void b_string_prepend_s(b_string *dest, const b_string *src);
extern void b_string_prepend_cstr(b_string *dest, const char *src);
extern void b_string_prepend_cstrf(b_string *dest, const char *format, ...);
extern void b_string_insert_s(b_string *dest, const b_string *src, size_t at);
extern void b_string_insert_cstr(b_string *dest, const char *src, size_t at);
extern void b_string_insert_cstrn(
b_string *dest, const char *src, size_t len, size_t at);
extern void b_string_insert_cstrf(
b_string *dest, size_t at, const char *format, ...);
extern void b_string_clear(b_string *str);
extern size_t b_string_get_size(const b_string *str, b_strlen_flags flags);
extern size_t b_string_get_capacity(const b_string *str);
extern const char *b_string_ptr(const b_string *str);
extern void b_strv_builder_begin(b_strv_builder *strv, char *buf, size_t max);
extern void b_strv_builder_begin_dynamic(b_strv_builder *strv);
extern b_status b_strv_builder_add(b_strv_builder *strv, const char *str);
extern b_status b_strv_builder_addf(b_strv_builder *strv, const char *format, ...);
extern b_status b_strv_builder_addv(b_strv_builder *strv, const char **strs);
extern b_status b_strv_builder_addvl(
b_strv_builder *strv, const char **strs, size_t count);
extern b_status b_strv_builder_add_many(b_strv_builder *strv, ...);
extern char *b_strv_builder_end(b_strv_builder *strv);
extern char *b_strdup(const char *s);
extern size_t b_strlen(const char *s, b_strlen_flags flags);
extern uint64_t b_cstr_hash(const char *s);
#endif

View File

@@ -0,0 +1,25 @@
#ifndef BLUELIB_STRING_FORMATTER_H
#define BLUELIB_STRING_FORMATTER_H
#include <blue/object/string.h>
#include <stdarg.h>
typedef struct b_stringstream b_stringstream;
extern b_stringstream *b_stringstream_create(void);
extern b_string *b_stringstream_end(b_stringstream *f);
extern void b_stringstream_destroy(b_stringstream *f);
extern const b_string *b_stringstream_str(b_stringstream *f);
extern const char *b_stringstream_cstr(b_stringstream *f);
extern void b_stringstream_clear(b_stringstream *f);
extern void b_stringstream_push_indent(b_stringstream *f, int indent);
extern void b_stringstream_push_indent_abs(b_stringstream *f, int indent);
extern void b_stringstream_pop_indent(b_stringstream *f);
extern void b_stringstream_add(b_stringstream *f, const char *s);
extern void b_stringstream_addf(b_stringstream *f, const char *format, ...);
extern void b_stringstream_addvf(b_stringstream *f, const char *format, va_list arg);
extern void b_stringstream_add_str(b_stringstream *f, const b_string *str);
#endif

View File

@@ -0,0 +1,72 @@
#ifndef BLUELIB_TREE_H_
#define BLUELIB_TREE_H_
#include <blue/core/misc.h>
#include <blue/core/queue.h>
#include <blue/object/string.h>
#define B_TREE(p) ((b_tree *)(p))
#define B_TREE_NODE_INIT ((b_tree_node) {})
#define B_TREE_CONTAINER(t, m, v) \
((void *)((v) ? (uintptr_t)(v) - (offsetof(t, m)) : 0))
typedef struct b_tree b_tree;
#define b_tree_node_foreach(it, node) \
for (int z__b_unique_name() = b_tree_iterator_begin_at_node(node, it); \
(it)->node != NULL; b_tree_iterator_next(it))
#define b_tree_node_foreach_recursive(it, node) \
for (int z__b_unique_name() \
= b_tree_iterator_begin_at_node_recursive(node, it); \
(it)->node != NULL; b_tree_iterator_next(it))
#define b_tree_foreach(it, tree) \
for (int z__b_unique_name() = b_tree_iterator_begin(tree, it); \
(it)->node != NULL; b_tree_iterator_next(it))
typedef struct b_tree_node {
struct b_tree_node *__p01, *__p02, *__p03;
struct b_queue_entry __q01;
// struct b_tree_node *parent;
// struct b_tree_node *first_child, *next_sibling;
} b_tree_node;
typedef struct b_tree_iterator {
b_iterator _base;
size_t i, depth;
b_tree_node *node;
unsigned char _f01;
} b_tree_iterator;
extern b_tree *b_tree_create(void);
static inline b_tree *b_tree_retain(b_tree *tree)
{
return B_TREE(b_retain(B_OBJECT(tree)));
}
static inline void b_tree_release(b_tree *tree)
{
b_release(B_OBJECT(tree));
}
extern void b_tree_set_root(b_tree *tree, struct b_tree_node *node);
extern void b_tree_node_add_child(b_tree_node *parent, b_tree_node *child);
extern void b_tree_node_add_sibling(b_tree_node *node, b_tree_node *to_add);
extern b_tree_node *b_tree_node_get_child(b_tree_node *node, size_t at);
extern b_tree_node *b_tree_node_get_parent(b_tree_node *node);
extern int b_tree_iterator_begin(b_tree *tree, b_tree_iterator *it);
extern int b_tree_iterator_begin_at_node(b_tree_node *node, b_tree_iterator *it);
extern int b_tree_iterator_begin_at_node_recursive(
b_tree_node *node, b_tree_iterator *it);
extern bool b_tree_iterator_next(b_tree_iterator *it);
extern b_status b_tree_iterator_erase(b_tree_iterator *it);
extern bool b_tree_iterator_is_valid(const b_tree_iterator *it);
#endif

View File

@@ -0,0 +1,51 @@
#ifndef BLUELIB_TYPE_H_
#define BLUELIB_TYPE_H_
#include <blue/core/queue.h>
#include <blue/core/status.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define B_NPOS ((size_t)INTPTR_MAX)
struct b_object;
struct b_stringstream;
typedef uintptr_t b_object_type_id;
typedef enum b_fundamental_type_id {
B_OBJECT_TYPE_NONE = 0,
B_OBJECT_TYPE_ANY,
B_OBJECT_TYPE_ARRAY,
B_OBJECT_TYPE_BUFFER,
B_OBJECT_TYPE_DICT,
B_OBJECT_TYPE_ERROR,
B_OBJECT_TYPE_HASHMAP,
B_OBJECT_TYPE_NUMBER,
B_OBJECT_TYPE_STRING,
B_OBJECT_TYPE_TREE,
B_OBJECT_TYPE_UUID,
B_OBJECT_TYPE_FILE,
B_OBJECT_TYPE_DIRECTORY,
} b_fundamental_type_id;
typedef enum b_object_type_flags {
B_OBJECT_FUNDAMENTAL = 0x01u,
} b_object_type_flags;
typedef struct b_object_type {
b_object_type_flags t_flags;
char t_name[64];
size_t t_instance_size;
b_object_type_id t_id;
b_queue_entry t_entry;
void (*t_init)(struct b_object *);
void (*t_release)(struct b_object *);
void (*t_to_string)(struct b_object *, struct b_stringstream *);
} b_object_type;
extern b_status b_object_type_register(b_object_type *type);
extern struct b_object *b_object_type_instantiate(const b_object_type *type);
#endif

View File

@@ -0,0 +1,52 @@
#ifndef BLUELIB_UUID_H_
#define BLUELIB_UUID_H_
#include <blue/core/status.h>
#include <blue/object/object.h>
#include <blue/object/type.h>
#define B_UUID(p) ((b_uuid *)(p))
#define B_UUID_NBYTES 16
#define B_UUID_STRING_MAX 37
struct b_string;
struct b_strv_builder;
typedef struct b_uuid b_uuid;
typedef struct b_uuid_bytes {
unsigned char uuid_bytes[B_UUID_NBYTES];
} b_uuid_bytes;
extern b_uuid *b_uuid_create(void);
extern b_uuid *b_uuid_create_from_bytes(
unsigned char u00, unsigned char u01, unsigned char u02,
unsigned char u03, unsigned char u04, unsigned char u05,
unsigned char u06, unsigned char u07, unsigned char u08,
unsigned char u09, unsigned char u10, unsigned char u11, unsigned char u12,
unsigned char u13, unsigned char u14, unsigned char u15);
extern b_uuid *b_uuid_create_from_bytev(const unsigned char bytes[B_UUID_NBYTES]);
extern b_uuid *b_uuid_create_from_uuid_bytes(const b_uuid_bytes *bytes);
extern b_uuid *b_uuid_create_from_string(const struct b_string *string);
extern b_uuid *b_uuid_create_from_cstr(const char *s);
static inline b_uuid *b_uuid_retain(b_uuid *uuid)
{
return B_UUID(b_retain(B_OBJECT(uuid)));
}
static inline void b_uuid_release(b_uuid *uuid)
{
b_release(B_OBJECT(uuid));
}
extern b_status b_uuid_to_string(const b_uuid *uuid, struct b_string *out);
extern b_status b_uuid_to_cstr(const b_uuid *uuid, char out[B_UUID_STRING_MAX]);
extern b_status b_uuid_to_strv_builder(
const b_uuid *uuid, struct b_strv_builder *out);
extern void b_uuid_get_bytes(
const b_uuid *uuid, unsigned char bytes[B_UUID_NBYTES]);
extern void b_uuid_get_uuid_bytes(const b_uuid *uuid, b_uuid_bytes *bytes);
extern b_uuid_bytes *b_uuid_ptr(b_uuid *uuid);
#endif