btcs

bitcoin script parser/evaluator/compiler/decompiler
git clone git://jb55.com/btcs
Log | Files | Refs | README | LICENSE

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 /* } */