val.c (2913B)
1 2 #include <assert.h> 3 #include "op.h" 4 #include "val.h" 5 #include "alloc.h" 6 #include "script_num.h" 7 8 static const char intbytes[] = { 9 OP_1NEGATE, 10 OP_0, 11 OP_1, OP_2, OP_3, OP_4, OP_5, 12 OP_6, OP_7, OP_8, OP_9, OP_10, 13 OP_11, OP_12, OP_13, OP_14, OP_15, 14 OP_16 15 }; 16 17 struct val 18 val_from_int(s64 intval) { 19 struct val val; 20 struct num *sn; 21 u16 ind; 22 sn = num_pool_new(&ind); 23 val.type = VT_SCRIPTNUM; 24 val.ind = ind; 25 sn->ind = ind; 26 sn->val = intval; 27 return val; 28 } 29 30 // TODO maybe replace this with serialize 31 void val_bytes(struct val val, u32 *len, u8 *buf, int bufsize) { 32 if (val.type == VT_DATA) 33 val.type = VT_RAW; 34 val_serialize(val, len, buf, bufsize); 35 } 36 37 void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) { 38 struct num *sn; 39 int n; 40 u16 valsize; 41 switch (val.type) { 42 case VT_SCRIPTNUM: 43 sn = num_pool_get(val.ind); 44 assert(sn); 45 46 /// TODO: if serialize_minimal 47 sn_serialize(sn, buf, bufsize, &valsize); 48 assert(valsize <= 0xFF); 49 *len = valsize; 50 return; 51 case VT_OP: 52 *len = 1; 53 *buf = val.ind & 0xFF; 54 return; 55 case VT_DATA: 56 case VT_RAW: { 57 u8 *p; 58 p = byte_pool_get(val.ind, len); 59 memcpy(buf, p, *len); 60 return; 61 } 62 case VT_SMALLINT: 63 assert(0); 64 *len = 1; 65 n = val.ind; 66 if (n >= -1 && n <= 16) { 67 val.type = VT_SMALLINT; 68 assert(bufsize >= 1); 69 *buf = intbytes[n+1]; 70 } 71 else { 72 assert(!"non-small VT_SMALLINT"); 73 } 74 return; 75 } 76 77 assert(!"val_serialize missing implementation"); 78 } 79 80 81 int val_eq(struct val a, struct val b) { 82 u32 alen = 0, blen = 0; 83 int eq = 0; 84 85 static const int tmpsize = 4096; 86 static u8 tmpa[4096]; 87 static u8 tmpb[4096]; 88 89 // TODO: do I need to serialize to compare? 90 /* abytes = val_serialize(a, &alen, require_minimal); */ 91 /* bbytes = val_serialize(b, &blen, require_minimal); */ 92 val_serialize(a, &alen, tmpa, tmpsize); 93 val_serialize(b, &blen, tmpb, tmpsize); 94 // TODO: what if they're semantically equivalent? or does that matter 95 // (eg. minimal vs not miniminal)? 96 97 if (alen != blen) 98 return 0; 99 100 eq = memcmp(tmpa, tmpb, alen) == 0; 101 102 return eq; 103 } 104 105 struct val 106 val_copy(struct val a) { 107 u32 len; 108 u16 newind; 109 u8 *src, *dst; 110 struct num *nsrc, *ndst; 111 112 switch (a.type) { 113 case VT_SMALLINT: 114 return a; 115 case VT_RAW: 116 case VT_DATA: 117 src = byte_pool_get(a.ind, &len); 118 dst = byte_pool_new(len, &newind); 119 memcpy(dst, src, len); 120 a.ind = newind; 121 return a; 122 case VT_SCRIPTNUM: 123 nsrc = num_pool_get(a.ind); 124 ndst = num_pool_new(&newind); 125 ndst->val = nsrc->val; 126 return sn_to_val(ndst); 127 default: 128 assert(!"unhandle val_copy enum"); 129 } 130 } 131 132 u32 133 val_size(struct val val) { 134 u32 len; 135 136 switch (val.type) { 137 case VT_DATA: { 138 byte_pool_get(val.ind, &len); 139 return len; 140 } 141 default: 142 return 1; 143 } 144 } 145 146 /* struct val */ 147 /* val_int(s64 n) { */ 148 /* struct val val; */ 149 /* } */