Decode a single node of a Simplicity dag from 'stream' into 'dag'['i']. * Returns 'SIMPLICITY_ERR_FAIL_CODE' if the encoding of a fail expression is encountered * (all fail subexpressions ought to have been pruned prior to serialization). * Returns 'SIMPLICITY_ERR_RESERVED_CODE' if a reserved codeword is encountered. * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has a HIDDEN child in
| 55 | * NULL != stream |
| 56 | */ |
| 57 | static simplicity_err decodeNode(dag_node* dag, simplicity_callback_decodeJet decodeJet, uint_fast32_t i, bitstream* stream) { |
| 58 | int32_t bit = read1Bit(stream); |
| 59 | if (bit < 0) return (simplicity_err)bit; |
| 60 | dag[i] = (dag_node){0}; |
| 61 | if (bit) { |
| 62 | bit = read1Bit(stream); |
| 63 | if (bit < 0) return (simplicity_err)bit; |
| 64 | if (bit) { |
| 65 | return decodeJet(&dag[i], stream); |
| 66 | } else { |
| 67 | /* Decode WORD. */ |
| 68 | int32_t depth = simplicity_decodeUptoMaxInt(stream); |
| 69 | if (depth < 0) return (simplicity_err)depth; |
| 70 | if (32 < depth) return SIMPLICITY_ERR_DATA_OUT_OF_RANGE; |
| 71 | { |
| 72 | simplicity_err error = simplicity_readBitstring(&dag[i].compactValue, (size_t)1 << (depth - 1), stream); |
| 73 | if (!IS_OK(error)) return error; |
| 74 | } |
| 75 | dag[i].tag = WORD; |
| 76 | dag[i].targetIx = (size_t)depth; |
| 77 | dag[i].cmr = simplicity_computeWordCMR(&dag[i].compactValue, (size_t)(depth - 1)); |
| 78 | } |
| 79 | } else { |
| 80 | int32_t code = simplicity_readNBits(2, stream); |
| 81 | if (code < 0) return (simplicity_err)code; |
| 82 | int32_t subcode = simplicity_readNBits(code < 3 ? 2 : 1, stream); |
| 83 | if (subcode < 0) return (simplicity_err)subcode; |
| 84 | for (int32_t j = 0; j < 2 - code; ++j) { |
| 85 | int32_t ix = simplicity_decodeUptoMaxInt(stream); |
| 86 | if (ix < 0) return (simplicity_err)ix; |
| 87 | if (i < (uint_fast32_t)ix) return SIMPLICITY_ERR_DATA_OUT_OF_RANGE; |
| 88 | dag[i].child[j] = i - (uint_fast32_t)ix; |
| 89 | } |
| 90 | switch (code) { |
| 91 | case 0: |
| 92 | switch (subcode) { |
| 93 | case 0: dag[i].tag = COMP; break; |
| 94 | case 1: |
| 95 | dag[i].tag = (HIDDEN == dag[dag[i].child[0]].tag) ? ASSERTR |
| 96 | : (HIDDEN == dag[dag[i].child[1]].tag) ? ASSERTL |
| 97 | : CASE; |
| 98 | break; |
| 99 | case 2: dag[i].tag = PAIR; break; |
| 100 | case 3: dag[i].tag = DISCONNECT; break; |
| 101 | } |
| 102 | break; |
| 103 | case 1: |
| 104 | switch (subcode) { |
| 105 | case 0: dag[i].tag = INJL; break; |
| 106 | case 1: dag[i].tag = INJR; break; |
| 107 | case 2: dag[i].tag = TAKE; break; |
| 108 | case 3: dag[i].tag = DROP; break; |
| 109 | } |
| 110 | break; |
| 111 | case 2: |
| 112 | switch (subcode) { |
| 113 | case 0: dag[i].tag = IDEN; break; |
| 114 | case 1: dag[i].tag = UNIT; break; |
no test coverage detected