libamxc  1.10.3
C Generic Data Containers
variant_htable.c File Reference
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <amxc/amxc_string.h>
#include <amxc_variant_priv.h>

Go to the source code of this file.

Functions

static int variant_htable_init (amxc_var_t *const var)
 
void variant_htable_it_free (UNUSED const char *key, amxc_htable_it_t *it)
 
static void variant_htable_delete (amxc_var_t *var)
 
static int variant_htable_copy_htable (amxc_var_t *const dest, const amxc_htable_t *const src_htable)
 
static int variant_htable_copy (amxc_var_t *const dest, const amxc_var_t *const src)
 
static int variant_htable_move (amxc_var_t *const dest, amxc_var_t *const src)
 
static int variant_htable_to_string (amxc_var_t *const dest, const amxc_var_t *const src)
 
static int variant_htable_to_number (amxc_var_t *const dest, const amxc_var_t *const src)
 
static int variant_htable_to_bool (amxc_var_t *const dest, const amxc_var_t *const src)
 
static int variant_htable_to_llist (amxc_var_t *const dest, const amxc_var_t *const src)
 
static int variant_htable_convert_to (amxc_var_t *const dest, const amxc_var_t *const src)
 
static amxc_var_tvariant_htable_get_key (const amxc_var_t *const src, const char *const key, int flags)
 
static int variant_htable_set_key (amxc_var_t *const dest, amxc_var_t *const src, const char *const key, int flags)
 
static amxc_var_tvariant_htable_get_index (const amxc_var_t *const src, const int64_t index, int flags)
 
static int variant_htable_compare (const amxc_var_t *const lval, const amxc_var_t *const rval, int *const result)
 
static CONSTRUCTOR void amxc_var_htable_init (void)
 
static DESTRUCTOR void amxc_var_htable_cleanup (void)
 
amxc_htable_tamxc_var_get_amxc_htable_t (const amxc_var_t *const var)
 Conversion helper function. More...
 
const amxc_htable_tamxc_var_get_const_amxc_htable_t (const amxc_var_t *const var)
 Conversion helper function. More...
 
amxc_var_tamxc_var_add_new_amxc_htable_t (amxc_var_t *const var, const amxc_htable_t *htable)
 Conversion helper function. More...
 
amxc_var_tamxc_var_add_new_key_amxc_htable_t (amxc_var_t *const var, const char *key, const amxc_htable_t *htable)
 Conversion helper function. More...
 

Variables

static amxc_var_type_t amxc_variant_htable
 

Function Documentation

◆ amxc_var_htable_cleanup()

static DESTRUCTOR void amxc_var_htable_cleanup ( void  )
static

Definition at line 413 of file variant_htable.c.

413  {
415 }
int PRIVATE amxc_var_remove_type(amxc_var_type_t *const type)
static amxc_var_type_t amxc_variant_htable

◆ amxc_var_htable_init()

static CONSTRUCTOR void amxc_var_htable_init ( void  )
static

Definition at line 409 of file variant_htable.c.

409  {
411 }
uint32_t PRIVATE amxc_var_add_type(amxc_var_type_t *const type, const uint32_t index)
#define AMXC_VAR_ID_HTABLE
Ambiorix Hash Table variant id.
Definition: amxc_variant.h:212

◆ variant_htable_compare()

static int variant_htable_compare ( const amxc_var_t *const  lval,
const amxc_var_t *const  rval,
int *const  result 
)
static

Definition at line 353 of file variant_htable.c.

355  {
356  int ret = 0;
359  size_t size_l = amxc_array_size(keys_l);
360  size_t size_r = amxc_array_size(keys_r);
361 
362  if(size_l > size_r) {
363  *result = 1;
364  goto exit;
365  } else if(size_l < size_r) {
366  *result = -1;
367  goto exit;
368  }
369 
370  for(size_t i = 0; i < size_l; i++) {
371  const char* key_l = (const char*) amxc_array_get_data_at(keys_l, i);
372  const char* key_r = (const char*) amxc_array_get_data_at(keys_r, i);
373 
374  if((key_l == NULL) || (key_r == NULL)) {
375  continue;
376  }
377  *result = strcmp(key_l, key_r);
378  when_false(*result == 0, exit);
379 
382  result);
383  when_false((ret == 0) && (*result == 0), exit);
384  }
385 
386 exit:
387  amxc_array_delete(&keys_l, NULL);
388  amxc_array_delete(&keys_r, NULL);
389  return ret;
390 }
#define when_false(x, l)
Definition: amxc_macros.h:138
size_t amxc_array_size(const amxc_array_t *const array)
Calculates the number of used items in the array.
Definition: amxc_array.c:415
AMXC_INLINE void * amxc_array_get_data_at(const amxc_array_t *const array, const unsigned int index)
Gets the data pointer of the item at the given index.
Definition: amxc_array.h:711
void amxc_array_delete(amxc_array_t **array, const amxc_array_it_delete_t func)
Frees the previously allocated array.
Definition: amxc_array.c:213
amxc_array_t * amxc_htable_get_sorted_keys(const amxc_htable_t *const htable)
Creates an array containing all keys of the hash table.
Definition: amxc_htable.c:339
#define AMXC_VAR_FLAG_DEFAULT
The default flag, do not copy, use variant as is.
Definition: amxc_variant.h:392
amxc_var_t * amxc_var_get_key(const amxc_var_t *const var, const char *const key, const int flags)
Get a reference to a part of composed variant using a key.
Definition: amxc_variant.c:449
int amxc_var_compare(const amxc_var_t *const var1, const amxc_var_t *const var2, int *const result)
Compares two variants.
Definition: amxc_variant.c:397
#define amxc_var_constcast(type, var)
Takes the content from a variant.
Definition: amxc_variant.h:722
The array structure.
Definition: amxc_array.h:162
The hash table structure.
Definition: amxc_htable.h:175

◆ variant_htable_convert_to()

static int variant_htable_convert_to ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 217 of file variant_htable.c.

218  {
219  int retval = -1;
220 
237  NULL,
238  NULL,
242  };
243 
244  if(dest->type_id >= AMXC_VAR_ID_CUSTOM_BASE) {
245  goto exit;
246  }
247 
248  if(convfn[dest->type_id] != NULL) {
249  if(dest->type_id == AMXC_VAR_ID_ANY) {
251  }
252  retval = convfn[dest->type_id](dest, src);
253  }
254 
255 exit:
256  return retval;
257 }
int PRIVATE amxc_var_default_convert_to_null(amxc_var_t *const dest, const amxc_var_t *const src)
#define AMXC_VAR_ID_CUSTOM_BASE
Base variant id for custom variants.
Definition: amxc_variant.h:257
#define AMXC_VAR_ID_ANY
Special variant id, typically used in cast or conversion functions.
Definition: amxc_variant.h:247
int(* amxc_var_convert_fn_t)(amxc_var_t *const dest, const amxc_var_t *const src)
Variant type callback function prototype for dynamically converting one type to another.
int amxc_var_set_type(amxc_var_t *const var, const uint32_t type)
Change the variant data type.
Definition: amxc_variant.c:261
uint32_t type_id
Definition: amxc_variant.h:864
static int variant_htable_to_bool(amxc_var_t *const dest, const amxc_var_t *const src)
static int variant_htable_to_number(amxc_var_t *const dest, const amxc_var_t *const src)
static int variant_htable_to_llist(amxc_var_t *const dest, const amxc_var_t *const src)
static int variant_htable_to_string(amxc_var_t *const dest, const amxc_var_t *const src)
static int variant_htable_copy(amxc_var_t *const dest, const amxc_var_t *const src)

◆ variant_htable_copy()

static int variant_htable_copy ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 98 of file variant_htable.c.

99  {
100  const amxc_htable_t* htable = &src->data.vm;
101  return variant_htable_copy_htable(dest, htable);
102 }
void * data
Definition: amxc_variant.h:883
static amxc_htable_t * htable
static int variant_htable_copy_htable(amxc_var_t *const dest, const amxc_htable_t *const src_htable)

◆ variant_htable_copy_htable()

static int variant_htable_copy_htable ( amxc_var_t *const  dest,
const amxc_htable_t *const  src_htable 
)
static

Definition at line 75 of file variant_htable.c.

76  {
77  int retval = -1;
78 
79  amxc_htable_for_each(it, src_htable) {
80  amxc_var_t* var = NULL;
82  const char* key = amxc_htable_it_get_key(it);
83  when_null(item, exit);
84  when_failed(amxc_var_new(&var), exit);
85  if(amxc_var_copy(var, item) != 0) {
87  goto exit;
88  }
89  amxc_htable_insert(&dest->data.vm, key, &var->hit);
90  }
91 
92  retval = 0;
93 
94 exit:
95  return retval;
96 }
#define when_failed(x, l)
Definition: amxc_macros.h:142
#define when_null(x, l)
Definition: amxc_macros.h:126
#define amxc_var_from_htable_it(ht_it)
Get the variant pointer from an amxc htable iterator.
Definition: amxc_variant.h:790
AMXC_INLINE const char * amxc_htable_it_get_key(const amxc_htable_it_t *const it)
Gets the key from the iterator.
Definition: amxc_htable.h:672
int amxc_htable_insert(amxc_htable_t *const htable, const char *const key, amxc_htable_it_t *const it)
Inserts an item in the hash table.
Definition: amxc_htable.c:237
#define amxc_htable_for_each(it, htable)
Loops over items in the hash table.
Definition: amxc_htable.h:102
int amxc_var_new(amxc_var_t **var)
Allocates a variant and initializes it to the null variant type.
Definition: amxc_variant.c:194
int amxc_var_copy(amxc_var_t *const dest, const amxc_var_t *const src)
Copy the type and data from one variant (source) in another variant (destination).
Definition: amxc_variant.c:285
void amxc_var_delete(amxc_var_t **var)
Frees the previously allocated variant.
Definition: amxc_variant.c:207
The variant struct definition.
Definition: amxc_variant.h:861
amxc_htable_it_t hit
Definition: amxc_variant.h:863
static amxc_htable_it_t it[2000]
static amxc_var_t * var
Definition: test_issue_58.c:77

◆ variant_htable_delete()

static void variant_htable_delete ( amxc_var_t var)
static

Definition at line 71 of file variant_htable.c.

71  {
73 }
void amxc_htable_clean(amxc_htable_t *const htable, amxc_htable_it_delete_t func)
Removes all items from the hash table.
Definition: amxc_htable.c:200
void variant_htable_it_free(UNUSED const char *key, amxc_htable_it_t *it)

◆ variant_htable_get_index()

static amxc_var_t* variant_htable_get_index ( const amxc_var_t *const  src,
const int64_t  index,
int  flags 
)
static

Definition at line 321 of file variant_htable.c.

323  {
324  amxc_var_t* retval = NULL;
325  const amxc_htable_t* htable = &src->data.vm;
326  amxc_htable_it_t* found_hit = NULL;
327  amxc_var_t* src_var = NULL;
328  int64_t pos = 0;
329 
330  when_true(index < 0, exit);
331  when_true(index > (int64_t) amxc_htable_size(htable), exit);
333  if(pos == index) {
334  found_hit = hit;
335  break;
336  }
337  pos++;
338  }
339  when_null(found_hit, exit);
340 
341  src_var = amxc_var_from_htable_it(found_hit);
342  if((flags & AMXC_VAR_FLAG_COPY) == AMXC_VAR_FLAG_COPY) {
343  when_failed(amxc_var_new(&retval), exit);
344  when_failed(amxc_var_copy(retval, src_var), exit);
345  } else {
346  retval = src_var;
347  }
348 
349 exit:
350  return retval;
351 }
#define when_true(x, l)
Definition: amxc_macros.h:134
AMXC_INLINE size_t amxc_htable_size(const amxc_htable_t *const htable)
Calculates the size of the hash table.
Definition: amxc_htable.h:334
#define amxc_htable_iterate(it, htable)
Loops over items in the hash table.
Definition: amxc_htable.h:119
#define AMXC_VAR_FLAG_COPY
Copy the variant, creates a new variant, leaves the source variant untouched.
Definition: amxc_variant.h:398
The hash table iterator structure.
Definition: amxc_htable.h:138

◆ variant_htable_get_key()

static amxc_var_t* variant_htable_get_key ( const amxc_var_t *const  src,
const char *const  key,
int  flags 
)
static

Definition at line 259 of file variant_htable.c.

261  {
262  amxc_var_t* retval = NULL;
263  const amxc_htable_t* htable = &src->data.vm;
265  amxc_var_t* src_var = NULL;
266 
267  when_null(hit, exit);
268 
269  src_var = amxc_htable_it_get_data(hit, amxc_var_t, hit);
270  if((flags & AMXC_VAR_FLAG_COPY) == AMXC_VAR_FLAG_COPY) {
271  when_failed(amxc_var_new(&retval), exit);
272  when_failed(amxc_var_copy(retval, src_var), exit);
273  } else {
274  retval = src_var;
275  }
276 
277 exit:
278  return retval;
279 }
#define amxc_htable_it_get_data(it, type, member)
Gets the data pointer from an hash table iterator.
Definition: amxc_htable.h:87
amxc_htable_it_t * amxc_htable_get(const amxc_htable_t *const htable, const char *const key)
Gets a hash table iterator from the hash table.
Definition: amxc_htable.c:278

◆ variant_htable_init()

static int variant_htable_init ( amxc_var_t *const  var)
static

Definition at line 62 of file variant_htable.c.

62  {
63  return amxc_htable_init(&var->data.vm, 10);
64 }
int amxc_htable_init(amxc_htable_t *const htable, const size_t reserve)
Initializes a hash table.
Definition: amxc_htable.c:185

◆ variant_htable_it_free()

void variant_htable_it_free ( UNUSED const char *  key,
amxc_htable_it_t it 
)

Definition at line 66 of file variant_htable.c.

66  {
69 }

◆ variant_htable_move()

static int variant_htable_move ( amxc_var_t *const  dest,
amxc_var_t *const  src 
)
static

Definition at line 104 of file variant_htable.c.

105  {
106  int retval = 0;
107  amxc_htable_t* src_htable = &src->data.vm;
108  amxc_htable_t* dst_htable = &dest->data.vm;
109  retval = amxc_htable_move(dst_htable, src_htable);
110  return retval;
111 }
int amxc_htable_move(amxc_htable_t *const dest, amxc_htable_t *const src)
Moves all items from one hash table to another hash table.
Definition: amxc_htable.c:363

◆ variant_htable_set_key()

static int variant_htable_set_key ( amxc_var_t *const  dest,
amxc_var_t *const  src,
const char *const  key,
int  flags 
)
static

Definition at line 281 of file variant_htable.c.

284  {
285  int retval = -1;
286  amxc_var_t* dest_var = NULL;
287  amxc_htable_t* htable = &dest->data.vm;
288  amxc_htable_it_t* current_hit = amxc_htable_take(htable, key);
289 
290  if((current_hit != NULL) &&
291  ((flags & AMXC_VAR_FLAG_UPDATE) == 0)) {
292  amxc_htable_insert(htable, key, current_hit);
293  goto exit;
294  }
295 
296  if((flags & AMXC_VAR_FLAG_COPY) == AMXC_VAR_FLAG_COPY) {
297  if(current_hit != NULL) {
298  dest_var = amxc_htable_it_get_data(current_hit, amxc_var_t, hit);
299  } else {
300  when_failed(amxc_var_new(&dest_var), exit);
301  }
302 
303  when_failed(amxc_htable_insert(htable, key, &dest_var->hit), exit);
304  when_failed(amxc_var_copy(dest_var, src), exit);
305  } else {
306  when_failed(amxc_htable_insert(htable, key, &src->hit), exit);
307  if(current_hit != NULL) {
309  }
310  }
311 
312  retval = 0;
313 
314 exit:
315  if((current_hit == NULL) && (retval != 0)) {
316  amxc_var_delete(&dest_var);
317  }
318  return retval;
319 }
void amxc_htable_it_clean(amxc_htable_it_t *const it, amxc_htable_it_delete_t func)
Removes the iterator from the htable and frees allocated memory.
amxc_htable_it_t * amxc_htable_take(amxc_htable_t *const htable, const char *const key)
Removes a hash table iterator from the hash table.
Definition: amxc_htable.c:304
#define AMXC_VAR_FLAG_UPDATE
Replaces the value of the variant, leaves the source variant untouched.
Definition: amxc_variant.h:404

◆ variant_htable_to_bool()

static int variant_htable_to_bool ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 184 of file variant_htable.c.

185  {
186  dest->data.b = !amxc_htable_is_empty(&src->data.vm);
187 
188  return 0;
189 }
AMXC_INLINE bool amxc_htable_is_empty(const amxc_htable_t *const htable)
Checks that the hash table is empty.
Definition: amxc_htable.h:311

◆ variant_htable_to_llist()

static int variant_htable_to_llist ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 191 of file variant_htable.c.

192  {
193  int retval = -1;
194  const amxc_htable_t* htable = &src->data.vm;
195 
197  amxc_var_t* copy = NULL;
199 
200  when_failed(amxc_var_new(&copy), exit);
201  if(amxc_var_copy(copy, item) != 0) {
202  amxc_var_delete(&copy);
203  goto exit;
204  }
205  if(amxc_llist_append(&dest->data.vl, &copy->lit) != 0) {
206  amxc_var_delete(&copy);
207  goto exit;
208  }
209  }
210 
211  retval = 0;
212 
213 exit:
214  return retval;
215 }
int amxc_llist_append(amxc_llist_t *const llist, amxc_llist_it_t *const it)
Adds an item to the end of the linked list.
Definition: amxc_llist.c:169
amxc_llist_it_t lit
Definition: amxc_variant.h:862

◆ variant_htable_to_number()

static int variant_htable_to_number ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 171 of file variant_htable.c.

172  {
173  int retval = -1;
174 
175  amxc_var_t intermediate;
176  intermediate.type_id = AMXC_VAR_ID_UINT64;
177  intermediate.data.ui64 = amxc_htable_size(&src->data.vm);
178 
179  retval = amxc_var_convert(dest, &intermediate, dest->type_id);
180 
181  return retval;
182 }
#define AMXC_VAR_ID_UINT64
Unsigned 64 bit integer variant id.
Definition: amxc_variant.h:182
int amxc_var_convert(amxc_var_t *const dest, const amxc_var_t *src, const uint32_t type_id)
Converts one variant (source) to another variant(destination) using the specified variant type id.
Definition: amxc_variant.c:333

◆ variant_htable_to_string()

static int variant_htable_to_string ( amxc_var_t *const  dest,
const amxc_var_t *const  src 
)
static

Definition at line 114 of file variant_htable.c.

115  {
116  int retval = -1;
117  const amxc_htable_t* htable = &src->data.vm;
118  amxc_string_t string;
119  amxc_var_t intermediate;
120  const char* sep = "";
121 
122  amxc_var_init(&intermediate);
123  when_failed(amxc_string_init(&string, 100), exit);
124 
127  const char* key = amxc_htable_it_get_key(it);
128  size_t length = 0;
129  size_t key_length = 0;
130  if(amxc_var_convert(&intermediate, item, AMXC_VAR_ID_CSTRING) != 0) {
131  amxc_string_clean(&string);
132  goto exit;
133  }
134  if(*sep != 0) {
135  if(amxc_string_append(&string, sep, strlen(sep)) != 0) {
136  amxc_string_clean(&string);
137  goto exit;
138  }
139  }
140  key_length = strlen(key);
141  if(key_length != 0) {
142  if(amxc_string_append(&string, key, key_length) != 0) {
143  amxc_string_clean(&string);
144  goto exit;
145  }
146  }
147  if(amxc_string_append(&string, ":", 1) != 0) {
148  amxc_string_clean(&string);
149  goto exit;
150  }
151  length = intermediate.data.s == NULL ? 0 : strlen(intermediate.data.s);
152  if(length == 0) {
153  continue;
154  }
155  if(amxc_string_append(&string, intermediate.data.s, length) != 0) {
156  amxc_string_clean(&string);
157  goto exit;
158  }
159  sep = ",";
160  }
161 
162  string.buffer[string.last_used] = 0;
163  dest->data.s = string.buffer;
164  retval = 0;
165 
166 exit:
167  amxc_var_clean(&intermediate);
168  return retval;
169 }
AMXC_INLINE int amxc_string_append(amxc_string_t *const string, const char *const text, const size_t length)
Appends text to the end of the current content of the string buffer.
Definition: amxc_string.h:920
int amxc_string_init(amxc_string_t *const string, const size_t length)
Initializes a string.
Definition: amxc_string.c:163
void amxc_string_clean(amxc_string_t *const string)
Frees the string buffer and reset length attributes.
Definition: amxc_string.c:189
#define AMXC_VAR_ID_CSTRING
C-string variant id (aka char *), null terminated string.
Definition: amxc_variant.h:134
int amxc_var_init(amxc_var_t *const var)
Initializes a variant.
Definition: amxc_variant.c:223
void amxc_var_clean(amxc_var_t *const var)
Clean-up and reset variant.
Definition: amxc_variant.c:237
The string structure.
Definition: amxc_string.h:103

Variable Documentation

◆ amxc_variant_htable

amxc_var_type_t amxc_variant_htable
static
Initial value:
= {
.convert_from = NULL,
.set_index = NULL,
.type_id = 0,
.hit = { .ait = NULL, .key = NULL, .next = NULL },
}
#define AMXC_VAR_NAME_HTABLE
Provides a name for variant id AMXC_VAR_ID_HTABLE.
Definition: amxc_variant.h:354
static int variant_htable_move(amxc_var_t *const dest, amxc_var_t *const src)
static int variant_htable_set_key(amxc_var_t *const dest, amxc_var_t *const src, const char *const key, int flags)
static int variant_htable_convert_to(amxc_var_t *const dest, const amxc_var_t *const src)
static void variant_htable_delete(amxc_var_t *var)
static amxc_var_t * variant_htable_get_index(const amxc_var_t *const src, const int64_t index, int flags)
static int variant_htable_init(amxc_var_t *const var)
static int variant_htable_compare(const amxc_var_t *const lval, const amxc_var_t *const rval, int *const result)
static amxc_var_t * variant_htable_get_key(const amxc_var_t *const src, const char *const key, int flags)

Definition at line 392 of file variant_htable.c.