diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 7bc6b46d7..d124758fc 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -44,134 +44,28 @@ HB_BEGIN_DECLS #endif +/* reference_count */ + +typedef struct { + hb_atomic_int_t ref_count; + +#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) +#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} + + inline void init (int v) { ref_count = v; /* non-atomic is fine */ } + inline int inc (void) { return hb_atomic_int_fetch_and_add (ref_count, 1); } + inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); } + inline void set (int v) { hb_atomic_int_set (ref_count, v); } + + inline int get (void) const { return hb_atomic_int_get (ref_count); } + inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; } + +} hb_reference_count_t; + + /* user_data */ -HB_END_DECLS - - -template -struct hb_static_array_t { - - unsigned int len; - unsigned int allocated; - Type *array; - Type static_array[StaticSize]; - - void finish (void) { for (unsigned i = 0; i < len; i++) array[i].finish (); } - - inline Type& operator [] (unsigned int i) - { - return array[i]; - } - - inline Type *push (void) - { - if (!array) { - array = static_array; - allocated = ARRAY_LENGTH (static_array); - } - if (likely (len < allocated)) - return &array[len++]; - /* Need to reallocate */ - unsigned int new_allocated = allocated + (allocated >> 1) + 8; - Type *new_array; - if (array == static_array) { - new_array = (Type *) calloc (new_allocated, sizeof (Type)); - if (new_array) { - memcpy (new_array, array, len * sizeof (Type)); - array = new_array; - } - } else { - bool overflows = new_allocated >= ((unsigned int) -1) / sizeof (Type); - if (unlikely (overflows)) - new_array = NULL; - else - new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); - if (new_array) { - free (array); - array = new_array; - } - } - if ((len < allocated)) - return &array[len++]; - else - return NULL; - } - - inline void pop (void) - { - len--; - /* TODO: shrink array if needed */ - } -}; - -template -struct hb_array_t : hb_static_array_t {}; - - -template -struct hb_map_t -{ - struct item_t { - Key key; - /* unsigned int hash; */ - Value value; - - void finish (void) { value.finish (); } - }; - - hb_array_t items; - - private: - - inline item_t *find (Key key) { - if (unlikely (!key)) return NULL; - for (unsigned int i = 0; i < items.len; i++) - if (key == items[i].key) - return &items[i]; - return NULL; - } - - public: - - inline bool set (Key key, - Value &value) - { - if (unlikely (!key)) return NULL; - item_t *item; - item = find (key); - if (item) - item->finish (); - else - item = items.push (); - if (unlikely (!item)) return false; - item->key = key; - item->value = value; - return true; - } - - inline void unset (Key &key) - { - item_t *item; - item = find (key); - if (!item) return; - - item->finish (); - items[items.len - 1] = *item; - items.pop (); - } - - inline Value *get (Key key) - { - item_t *item = find (key); - return item ? &item->value : NULL; - } - - void finish (void) { items.finish (); } -}; - - -HB_BEGIN_DECLS +/* XXX make this thread-safe, somehow! */ typedef struct { void *data; @@ -204,6 +98,7 @@ struct hb_user_data_array_t { }; +/* object_header */ typedef struct _hb_object_header_t hb_object_header_t; @@ -273,6 +168,9 @@ struct _hb_object_header_t { HB_END_DECLS + +/* object */ + template static inline void hb_object_trace (const Type *obj, const char *function) { @@ -303,6 +201,21 @@ static inline bool hb_object_destroy (Type *obj) hb_object_trace (obj, HB_FUNC); return obj->header.destroy (); } +template +static inline bool hb_object_set_user_data (Type *obj, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy) +{ + return obj->header.set_user_data (key, data, destroy); +} + +template +static inline void *hb_object_get_user_data (Type *obj, + hb_user_data_key_t *key) +{ + return obj->header.get_user_data (key); +} HB_BEGIN_DECLS diff --git a/src/hb-private.hh b/src/hb-private.hh index fc06e7056..ce09d1825 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -258,23 +258,135 @@ typedef volatile int hb_mutex_t; #endif -/* A reference count */ +HB_END_DECLS -typedef struct { - hb_atomic_int_t ref_count; -#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) -#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} +/* arrays and maps */ - inline void init (int v) { ref_count = v; /* non-atomic is fine */ } - inline int inc (void) { return hb_atomic_int_fetch_and_add (ref_count, 1); } - inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); } - inline void set (int v) { hb_atomic_int_set (ref_count, v); } - inline int get (void) const { return hb_atomic_int_get (ref_count); } - inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; } +template +struct hb_static_array_t { -} hb_reference_count_t; + unsigned int len; + unsigned int allocated; + Type *array; + Type static_array[StaticSize]; + + void finish (void) { for (unsigned i = 0; i < len; i++) array[i].finish (); } + + inline Type& operator [] (unsigned int i) + { + return array[i]; + } + + inline Type *push (void) + { + if (!array) { + array = static_array; + allocated = ARRAY_LENGTH (static_array); + } + if (likely (len < allocated)) + return &array[len++]; + /* Need to reallocate */ + unsigned int new_allocated = allocated + (allocated >> 1) + 8; + Type *new_array; + if (array == static_array) { + new_array = (Type *) calloc (new_allocated, sizeof (Type)); + if (new_array) { + memcpy (new_array, array, len * sizeof (Type)); + array = new_array; + } + } else { + bool overflows = new_allocated >= ((unsigned int) -1) / sizeof (Type); + if (unlikely (overflows)) + new_array = NULL; + else + new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); + if (new_array) { + free (array); + array = new_array; + } + } + if ((len < allocated)) + return &array[len++]; + else + return NULL; + } + + inline void pop (void) + { + len--; + /* TODO: shrink array if needed */ + } +}; + +template +struct hb_array_t : hb_static_array_t {}; + + +template +struct hb_map_t +{ + struct item_t { + Key key; + /* unsigned int hash; */ + Value value; + + void finish (void) { value.finish (); } + }; + + hb_array_t items; + + private: + + inline item_t *find (Key key) { + if (unlikely (!key)) return NULL; + for (unsigned int i = 0; i < items.len; i++) + if (key == items[i].key) + return &items[i]; + return NULL; + } + + public: + + inline bool set (Key key, + Value &value) + { + if (unlikely (!key)) return NULL; + item_t *item; + item = find (key); + if (item) + item->finish (); + else + item = items.push (); + if (unlikely (!item)) return false; + item->key = key; + item->value = value; + return true; + } + + inline void unset (Key &key) + { + item_t *item; + item = find (key); + if (!item) return; + + item->finish (); + items[items.len - 1] = *item; + items.pop (); + } + + inline Value *get (Key key) + { + item_t *item = find (key); + return item ? &item->value : NULL; + } + + void finish (void) { items.finish (); } +}; + + +HB_BEGIN_DECLS /* Big-endian handling */