summaryrefslogtreecommitdiff
path: root/xs.h
diff options
context:
space:
mode:
Diffstat (limited to 'xs.h')
-rw-r--r--xs.h110
1 files changed, 76 insertions, 34 deletions
diff --git a/xs.h b/xs.h
index f5c87ef..b46f0e1 100644
--- a/xs.h
+++ b/xs.h
@@ -21,8 +21,8 @@ typedef enum {
21 XSTYPE_FALSE = 0x15, /* Boolean */ 21 XSTYPE_FALSE = 0x15, /* Boolean */
22 XSTYPE_LIST = 0x1d, /* Sequence of LITEMs up to EOM (with size) */ 22 XSTYPE_LIST = 0x1d, /* Sequence of LITEMs up to EOM (with size) */
23 XSTYPE_LITEM = 0x1f, /* Element of a list (any type) */ 23 XSTYPE_LITEM = 0x1f, /* Element of a list (any type) */
24 XSTYPE_DICT = 0x1c, /* Sequence of DITEMs up to EOM (with size) */ 24 XSTYPE_DICT = 0x1c, /* Sequence of KEYVALs up to EOM (with size) */
25 XSTYPE_DITEM = 0x1e, /* Element of a dict (STRING key + any type) */ 25 XSTYPE_KEYVAL = 0x1e, /* key + value (STRING key + any type) */
26 XSTYPE_EOM = 0x19, /* End of Multiple (LIST or DICT) */ 26 XSTYPE_EOM = 0x19, /* End of Multiple (LIST or DICT) */
27 XSTYPE_DATA = 0x10 /* A block of anonymous data */ 27 XSTYPE_DATA = 0x10 /* A block of anonymous data */
28} xstype; 28} xstype;
@@ -32,6 +32,7 @@ typedef enum {
32typedef char xs_val; 32typedef char xs_val;
33typedef char xs_str; 33typedef char xs_str;
34typedef char xs_list; 34typedef char xs_list;
35typedef char xs_keyval;
35typedef char xs_dict; 36typedef char xs_dict;
36typedef char xs_number; 37typedef char xs_number;
37typedef char xs_data; 38typedef char xs_data;
@@ -96,7 +97,7 @@ xs_list *_xs_list_append(xs_list *list, const xs_val *vals[]);
96int xs_list_iter(xs_list **list, xs_val **value); 97int xs_list_iter(xs_list **list, xs_val **value);
97int xs_list_next(const xs_list *list, xs_val **value, int *ctxt); 98int xs_list_next(const xs_list *list, xs_val **value, int *ctxt);
98int xs_list_len(const xs_list *list); 99int xs_list_len(const xs_list *list);
99xs_val *xs_list_get(const xs_list *list, int num); 100const xs_val *xs_list_get(const xs_list *list, int num);
100xs_list *xs_list_del(xs_list *list, int num); 101xs_list *xs_list_del(xs_list *list, int num);
101xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data); 102xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data);
102xs_list *xs_list_set(xs_list *list, int num, const xs_val *data); 103xs_list *xs_list_set(xs_list *list, int num, const xs_val *data);
@@ -109,14 +110,20 @@ xs_list *xs_split_n(const char *str, const char *sep, int times);
109#define xs_split(str, sep) xs_split_n(str, sep, XS_ALL) 110#define xs_split(str, sep) xs_split_n(str, sep, XS_ALL)
110xs_list *xs_list_cat(xs_list *l1, const xs_list *l2); 111xs_list *xs_list_cat(xs_list *l1, const xs_list *l2);
111 112
113int xs_keyval_size(const xs_str *key, const xs_val *value);
114xs_str *xs_keyval_key(const xs_keyval *keyval);
115xs_val *xs_keyval_value(const xs_keyval *keyval);
116xs_keyval *xs_keyval_make(xs_keyval *keyval, const xs_str *key, const xs_val *value);
117
112xs_dict *xs_dict_new(void); 118xs_dict *xs_dict_new(void);
113xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value); 119xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value);
114xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value); 120xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value);
115int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt); 121int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt);
116xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def); 122const xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def);
117#define xs_dict_get(dict, key) xs_dict_get_def(dict, key, NULL) 123#define xs_dict_get(dict, key) xs_dict_get_def(dict, key, NULL)
118xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key); 124xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key);
119xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data); 125xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data);
126xs_dict *xs_dict_gc(xs_dict *dict);
120 127
121xs_val *xs_val_new(xstype t); 128xs_val *xs_val_new(xstype t);
122xs_number *xs_number_new(double f); 129xs_number *xs_number_new(double f);
@@ -244,7 +251,7 @@ xstype xs_type(const xs_val *data)
244 case XSTYPE_LIST: 251 case XSTYPE_LIST:
245 case XSTYPE_LITEM: 252 case XSTYPE_LITEM:
246 case XSTYPE_DICT: 253 case XSTYPE_DICT:
247 case XSTYPE_DITEM: 254 case XSTYPE_KEYVAL:
248 case XSTYPE_NUMBER: 255 case XSTYPE_NUMBER:
249 case XSTYPE_EOM: 256 case XSTYPE_EOM:
250 case XSTYPE_DATA: 257 case XSTYPE_DATA:
@@ -262,7 +269,7 @@ xstype xs_type(const xs_val *data)
262void _xs_put_size(xs_val *ptr, int i) 269void _xs_put_size(xs_val *ptr, int i)
263/* must match _XS_TYPE_SIZE */ 270/* must match _XS_TYPE_SIZE */
264{ 271{
265 memcpy(ptr, &i, sizeof(i)); 272 memcpy(ptr + 1, &i, sizeof(i));
266} 273}
267 274
268 275
@@ -296,7 +303,7 @@ int xs_size(const xs_val *data)
296 303
297 break; 304 break;
298 305
299 case XSTYPE_DITEM: 306 case XSTYPE_KEYVAL:
300 /* calculate the size of the key and the value */ 307 /* calculate the size of the key and the value */
301 p = data + 1; 308 p = data + 1;
302 p += xs_size(p); 309 p += xs_size(p);
@@ -380,7 +387,7 @@ xs_val *xs_expand(xs_val *data, int offset, int size)
380 if (xs_type(data) == XSTYPE_LIST || 387 if (xs_type(data) == XSTYPE_LIST ||
381 xs_type(data) == XSTYPE_DICT || 388 xs_type(data) == XSTYPE_DICT ||
382 xs_type(data) == XSTYPE_DATA) 389 xs_type(data) == XSTYPE_DATA)
383 _xs_put_size(data + 1, sz); 390 _xs_put_size(data, sz);
384 391
385 return data; 392 return data;
386} 393}
@@ -405,7 +412,7 @@ xs_val *xs_collapse(xs_val *data, int offset, int size)
405 if (xs_type(data) == XSTYPE_LIST || 412 if (xs_type(data) == XSTYPE_LIST ||
406 xs_type(data) == XSTYPE_DICT || 413 xs_type(data) == XSTYPE_DICT ||
407 xs_type(data) == XSTYPE_DATA) 414 xs_type(data) == XSTYPE_DATA)
408 _xs_put_size(data + 1, sz); 415 _xs_put_size(data, sz);
409 416
410 return xs_realloc(data, _xs_blk_size(sz)); 417 return xs_realloc(data, _xs_blk_size(sz));
411} 418}
@@ -666,10 +673,10 @@ xs_list *xs_list_new(void)
666{ 673{
667 int sz = 1 + _XS_TYPE_SIZE + 1; 674 int sz = 1 + _XS_TYPE_SIZE + 1;
668 xs_list *l = xs_realloc(NULL, sz); 675 xs_list *l = xs_realloc(NULL, sz);
669 memset(l, '\0', sz); 676 memset(l, XSTYPE_EOM, sz);
670 677
671 l[0] = XSTYPE_LIST; 678 l[0] = XSTYPE_LIST;
672 _xs_put_size(&l[1], sz); 679 _xs_put_size(l, sz);
673 680
674 return l; 681 return l;
675} 682}
@@ -802,7 +809,7 @@ int xs_list_len(const xs_list *list)
802} 809}
803 810
804 811
805xs_val *xs_list_get(const xs_list *list, int num) 812const xs_val *xs_list_get(const xs_list *list, int num)
806/* returns the element #num */ 813/* returns the element #num */
807{ 814{
808 XS_ASSERT_TYPE(list, XSTYPE_LIST); 815 XS_ASSERT_TYPE(list, XSTYPE_LIST);
@@ -830,7 +837,7 @@ xs_list *xs_list_del(xs_list *list, int num)
830{ 837{
831 XS_ASSERT_TYPE(list, XSTYPE_LIST); 838 XS_ASSERT_TYPE(list, XSTYPE_LIST);
832 839
833 xs_val *v; 840 const xs_val *v;
834 841
835 if ((v = xs_list_get(list, num)) != NULL) 842 if ((v = xs_list_get(list, num)) != NULL)
836 list = xs_collapse(list, v - 1 - list, xs_size(v - 1)); 843 list = xs_collapse(list, v - 1 - list, xs_size(v - 1));
@@ -844,7 +851,7 @@ xs_list *xs_list_insert(xs_list *list, int num, const xs_val *data)
844{ 851{
845 XS_ASSERT_TYPE(list, XSTYPE_LIST); 852 XS_ASSERT_TYPE(list, XSTYPE_LIST);
846 853
847 xs_val *v; 854 const xs_val *v;
848 int offset; 855 int offset;
849 856
850 if ((v = xs_list_get(list, num)) != NULL) 857 if ((v = xs_list_get(list, num)) != NULL)
@@ -999,6 +1006,40 @@ xs_list *xs_list_cat(xs_list *l1, const xs_list *l2)
999} 1006}
1000 1007
1001 1008
1009/** keyvals **/
1010
1011int xs_keyval_size(const xs_str *key, const xs_val *value)
1012/* returns the needed size for a keyval */
1013{
1014 return 1 + xs_size(key) + xs_size(value);
1015}
1016
1017
1018xs_str *xs_keyval_key(const xs_keyval *keyval)
1019/* returns a pointer to the key of the keyval */
1020{
1021 return (xs_str *)&keyval[1];
1022}
1023
1024
1025xs_val *xs_keyval_value(const xs_keyval *keyval)
1026/* returns a pointer to the value of the keyval */
1027{
1028 return (xs_val *)&keyval[1 + xs_size(xs_keyval_key(keyval))];
1029}
1030
1031
1032xs_keyval *xs_keyval_make(xs_keyval *keyval, const xs_str *key, const xs_val *value)
1033/* builds a keyval into mem (should have enough size) */
1034{
1035 keyval[0] = XSTYPE_KEYVAL;
1036 memcpy(xs_keyval_key(keyval), key, xs_size(key));
1037 memcpy(xs_keyval_value(keyval), value, xs_size(value));
1038
1039 return keyval;
1040}
1041
1042
1002/** dicts **/ 1043/** dicts **/
1003 1044
1004xs_dict *xs_dict_new(void) 1045xs_dict *xs_dict_new(void)
@@ -1006,34 +1047,27 @@ xs_dict *xs_dict_new(void)
1006{ 1047{
1007 int sz = 1 + _XS_TYPE_SIZE + 1; 1048 int sz = 1 + _XS_TYPE_SIZE + 1;
1008 xs_dict *d = xs_realloc(NULL, sz); 1049 xs_dict *d = xs_realloc(NULL, sz);
1009 memset(d, '\0', sz); 1050 memset(d, XSTYPE_EOM, sz);
1010 1051
1011 d[0] = XSTYPE_DICT; 1052 d[0] = XSTYPE_DICT;
1012 _xs_put_size(&d[1], sz); 1053 _xs_put_size(d, sz);
1013 1054
1014 return d; 1055 return d;
1015} 1056}
1016 1057
1017 1058
1018xs_dict *_xs_dict_write_ditem(xs_dict *dict, int offset, const xs_str *key, 1059xs_dict *_xs_dict_write_keyval(xs_dict *dict, int offset, const xs_str *key, const xs_val *value)
1019 const xs_val *data, int dsz) 1060/* adds a new keyval to the dict */
1020/* inserts a memory block into the dict */
1021{ 1061{
1022 XS_ASSERT_TYPE(dict, XSTYPE_DICT); 1062 XS_ASSERT_TYPE(dict, XSTYPE_DICT);
1023 XS_ASSERT_TYPE(key, XSTYPE_STRING); 1063 XS_ASSERT_TYPE(key, XSTYPE_STRING);
1024 1064
1025 if (data == NULL) { 1065 if (value == NULL)
1026 data = xs_stock(XSTYPE_NULL); 1066 value = xs_stock(XSTYPE_NULL);
1027 dsz = xs_size(data);
1028 }
1029
1030 int ksz = xs_size(key);
1031 1067
1032 dict = xs_expand(dict, offset, 1 + ksz + dsz); 1068 dict = xs_expand(dict, offset, xs_keyval_size(key, value));
1033 1069
1034 dict[offset] = XSTYPE_DITEM; 1070 xs_keyval_make(&dict[offset], key, value);
1035 memcpy(&dict[offset + 1], key, ksz);
1036 memcpy(&dict[offset + 1 + ksz], data, dsz);
1037 1071
1038 return dict; 1072 return dict;
1039} 1073}
@@ -1042,14 +1076,14 @@ xs_dict *_xs_dict_write_ditem(xs_dict *dict, int offset, const xs_str *key,
1042xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value) 1076xs_dict *xs_dict_append(xs_dict *dict, const xs_str *key, const xs_val *value)
1043/* appends a memory block to the dict */ 1077/* appends a memory block to the dict */
1044{ 1078{
1045 return _xs_dict_write_ditem(dict, xs_size(dict) - 1, key, value, xs_size(value)); 1079 return _xs_dict_write_keyval(dict, xs_size(dict) - 1, key, value);
1046} 1080}
1047 1081
1048 1082
1049xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value) 1083xs_dict *xs_dict_prepend(xs_dict *dict, const xs_str *key, const xs_val *value)
1050/* prepends a memory block to the dict */ 1084/* prepends a memory block to the dict */
1051{ 1085{
1052 return _xs_dict_write_ditem(dict, 1 + _XS_TYPE_SIZE, key, value, xs_size(value)); 1086 return _xs_dict_write_keyval(dict, 1 + _XS_TYPE_SIZE, key, value);
1053} 1087}
1054 1088
1055 1089
@@ -1070,7 +1104,7 @@ int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt)
1070 p += *ctxt; 1104 p += *ctxt;
1071 1105
1072 /* an element? */ 1106 /* an element? */
1073 if (xs_type(p) == XSTYPE_DITEM) { 1107 if (xs_type(p) == XSTYPE_KEYVAL) {
1074 p++; 1108 p++;
1075 1109
1076 *key = p; 1110 *key = p;
@@ -1091,7 +1125,7 @@ int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt)
1091} 1125}
1092 1126
1093 1127
1094xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def) 1128const xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def)
1095/* returns the value directed by key, or the default value */ 1129/* returns the value directed by key, or the default value */
1096{ 1130{
1097 XS_ASSERT_TYPE(dict, XSTYPE_DICT); 1131 XS_ASSERT_TYPE(dict, XSTYPE_DICT);
@@ -1150,6 +1184,14 @@ xs_dict *xs_dict_set(xs_dict *dict, const xs_str *key, const xs_val *data)
1150} 1184}
1151 1185
1152 1186
1187xs_dict *xs_dict_gc(xs_dict *dict)
1188/* collects garbage (leaked values) inside a dict */
1189{
1190 /* this kind of dicts does not get garbage */
1191 return dict;
1192}
1193
1194
1153/** other values **/ 1195/** other values **/
1154 1196
1155xs_val *xs_val_new(xstype t) 1197xs_val *xs_val_new(xstype t)
@@ -1235,7 +1277,7 @@ xs_data *xs_data_new(const void *data, int size)
1235 v = xs_realloc(NULL, _xs_blk_size(total_size)); 1277 v = xs_realloc(NULL, _xs_blk_size(total_size));
1236 v[0] = XSTYPE_DATA; 1278 v[0] = XSTYPE_DATA;
1237 1279
1238 _xs_put_size(v + 1, total_size); 1280 _xs_put_size(v, total_size);
1239 1281
1240 memcpy(&v[1 + _XS_TYPE_SIZE], data, size); 1282 memcpy(&v[1 + _XS_TYPE_SIZE], data, size);
1241 1283