quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_htable_vpstr.c (4469B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 2024 Brad House
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #include "ares_private.h"
     27 #include "ares_htable.h"
     28 #include "ares_htable_vpstr.h"
     29 
     30 struct ares_htable_vpstr {
     31   ares_htable_t *hash;
     32 };
     33 
     34 typedef struct {
     35   void                *key;
     36   char                *val;
     37   ares_htable_vpstr_t *parent;
     38 } ares_htable_vpstr_bucket_t;
     39 
     40 void ares_htable_vpstr_destroy(ares_htable_vpstr_t *htable)
     41 {
     42   if (htable == NULL) {
     43     return; /* LCOV_EXCL_LINE: DefensiveCoding */
     44   }
     45 
     46   ares_htable_destroy(htable->hash);
     47   ares_free(htable);
     48 }
     49 
     50 static unsigned int hash_func(const void *key, unsigned int seed)
     51 {
     52   return ares_htable_hash_FNV1a((const unsigned char *)&key, sizeof(key), seed);
     53 }
     54 
     55 static const void *bucket_key(const void *bucket)
     56 {
     57   const ares_htable_vpstr_bucket_t *arg = bucket;
     58   return arg->key;
     59 }
     60 
     61 static void bucket_free(void *bucket)
     62 {
     63   ares_htable_vpstr_bucket_t *arg = bucket;
     64 
     65   ares_free(arg->val);
     66 
     67   ares_free(arg);
     68 }
     69 
     70 static ares_bool_t key_eq(const void *key1, const void *key2)
     71 {
     72   if (key1 == key2) {
     73     return ARES_TRUE;
     74   }
     75 
     76   return ARES_FALSE;
     77 }
     78 
     79 ares_htable_vpstr_t *ares_htable_vpstr_create(void)
     80 {
     81   ares_htable_vpstr_t *htable = ares_malloc(sizeof(*htable));
     82   if (htable == NULL) {
     83     goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
     84   }
     85 
     86   htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq);
     87   if (htable->hash == NULL) {
     88     goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
     89   }
     90 
     91   return htable;
     92 
     93 /* LCOV_EXCL_START: OutOfMemory */
     94 fail:
     95   if (htable) {
     96     ares_htable_destroy(htable->hash);
     97     ares_free(htable);
     98   }
     99   return NULL;
    100   /* LCOV_EXCL_STOP */
    101 }
    102 
    103 ares_bool_t ares_htable_vpstr_insert(ares_htable_vpstr_t *htable, void *key,
    104                                      const char *val)
    105 {
    106   ares_htable_vpstr_bucket_t *bucket = NULL;
    107 
    108   if (htable == NULL) {
    109     goto fail;
    110   }
    111 
    112   bucket = ares_malloc(sizeof(*bucket));
    113   if (bucket == NULL) {
    114     goto fail;
    115   }
    116 
    117   bucket->parent = htable;
    118   bucket->key    = key;
    119   bucket->val    = ares_strdup(val);
    120   if (bucket->val == NULL) {
    121     goto fail;
    122   }
    123 
    124   if (!ares_htable_insert(htable->hash, bucket)) {
    125     goto fail;
    126   }
    127 
    128   return ARES_TRUE;
    129 
    130 fail:
    131   if (bucket) {
    132     ares_free(bucket->val);
    133     ares_free(bucket);
    134   }
    135   return ARES_FALSE;
    136 }
    137 
    138 ares_bool_t ares_htable_vpstr_get(const ares_htable_vpstr_t *htable,
    139                                   const void *key, const char **val)
    140 {
    141   const ares_htable_vpstr_bucket_t *bucket = NULL;
    142 
    143   if (val) {
    144     *val = NULL;
    145   }
    146 
    147   if (htable == NULL) {
    148     return ARES_FALSE;
    149   }
    150 
    151   bucket = ares_htable_get(htable->hash, key);
    152   if (bucket == NULL) {
    153     return ARES_FALSE;
    154   }
    155 
    156   if (val) {
    157     *val = bucket->val;
    158   }
    159   return ARES_TRUE;
    160 }
    161 
    162 const char *ares_htable_vpstr_get_direct(const ares_htable_vpstr_t *htable,
    163                                          const void                *key)
    164 {
    165   const char *val = NULL;
    166   ares_htable_vpstr_get(htable, key, &val);
    167   return val;
    168 }
    169 
    170 ares_bool_t ares_htable_vpstr_remove(ares_htable_vpstr_t *htable,
    171                                      const void          *key)
    172 {
    173   if (htable == NULL) {
    174     return ARES_FALSE;
    175   }
    176 
    177   return ares_htable_remove(htable->hash, key);
    178 }
    179 
    180 size_t ares_htable_vpstr_num_keys(const ares_htable_vpstr_t *htable)
    181 {
    182   if (htable == NULL) {
    183     return 0;
    184   }
    185   return ares_htable_num_keys(htable->hash);
    186 }