dtype.c

Dynamic-ish typing library
git clone git://git.finwo.net/lib/dtype.c
Log | Files | Refs | README | LICENSE

dtype.h (2676B)


      1 #ifndef __FINWO_DTYPE_H__
      2 #define __FINWO_DTYPE_H__
      3 
      4 #include <stdio.h>
      5 
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "tidwall/buf.h"
     10 
     11 enum dtype_typ {
     12   DTYPE_NULL,
     13   DTYPE_STRING,
     14   DTYPE_INTEGER,
     15   DTYPE_DOUBLE,
     16   DTYPE_BUFFER,
     17   DTYPE_UNKNOWN,
     18 };
     19 
     20 struct dtype_value {
     21   union {
     22     void       *val_null;
     23     char       *val_string;
     24     int         val_integer;
     25     double      val_double;
     26     struct buf *val_buffer;
     27     void       *val_unknown;
     28   };
     29   enum dtype_typ type;
     30 };
     31 
     32 #define dtype_type(x) ((x)->type)
     33 
     34 struct dtype_value * dtype_copy(const struct dtype_value *subject) {
     35   struct dtype_value *output = (struct dtype_value *)calloc(1, sizeof(struct dtype_value));
     36   memcpy(output, subject, sizeof(struct dtype_value));
     37   if (dtype_type(output) == DTYPE_STRING) {
     38     output->val_string = strdup(output->val_string);
     39   } else if (dtype_type(subject) == DTYPE_BUFFER) {
     40     output->val_buffer = malloc(sizeof(struct buf));
     41     memcpy(output->val_buffer, subject->val_buffer, sizeof(struct buf));
     42     output->val_buffer->data = malloc(output->val_buffer->cap);
     43     memcpy(output->val_buffer->data, subject->val_buffer->data, subject->val_buffer->len);
     44   }
     45   return output;
     46 }
     47 
     48 #define dtype_init_null()     dtype_copy(&((const struct dtype_value){ .type = DTYPE_NULL                      }))
     49 #define dtype_init_string(x)  dtype_copy(&((const struct dtype_value){ .type = DTYPE_STRING , .val_string  = x }))
     50 #define dtype_init_integer(x) dtype_copy(&((const struct dtype_value){ .type = DTYPE_INTEGER, .val_integer = x }))
     51 #define dtype_init_double(x)  dtype_copy(&((const struct dtype_value){ .type = DTYPE_DOUBLE , .val_double  = x }))
     52 #define dtype_init_buffer(x)  dtype_copy(&((const struct dtype_value){ .type = DTYPE_BUFFER , .val_buffer  = x }))
     53 #define dtype_init_unknown(x) dtype_copy(&((const struct dtype_value){ .type = DTYPE_UNKNOWN, .val_unknown = x }))
     54 
     55 #define dtype_buf_append(x,data,len) buf_append(x->val_buffer, data, len)
     56 #define dtype_buf_append_byte(x,c)   buf_append_byte(x->val_buffer, c)
     57 #define dtype_buf_clear(x)           buf_clear(x->val_buffer)
     58 
     59 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
     60 #define dtype_init(x) _Generic((x), \
     61     char *      : dtype_init_string, \
     62     int         : dtype_init_integer, \
     63     double      : dtype_init_double, \
     64     void *      : dtype_init_unknown, \
     65     struct buf *: dtype_init_buffer \
     66   )(x)
     67 #endif
     68 
     69 void dtype_free(struct dtype_value *subject) {
     70   if (dtype_type(subject) == DTYPE_STRING) {
     71     free(subject->val_string);
     72   } else if (dtype_type(subject) == DTYPE_BUFFER) {
     73     buf_clear((struct buf *)subject);
     74   }
     75   free(subject);
     76 }
     77 
     78 #endif // __FINWO_DTYPE_H__