|
1 | | - |
2 | 1 | // SPDX-License-Identifier: MIT |
3 | 2 | pragma solidity ^0.8.28; |
4 | 3 |
|
5 | 4 | import "./CidCbor.sol"; |
6 | 5 |
|
7 | 6 | library TreeNodeCbor { |
8 | | - using CBORDecoder for bytes; |
9 | | - |
10 | | - struct TreeNode { |
11 | | - CidCbor.Cid left; |
12 | | - TreeNodeEntry[] entries; |
13 | | - } |
| 7 | + using CBORDecoder for bytes; |
14 | 8 |
|
15 | | - struct TreeNodeEntry { |
16 | | - string key; |
17 | | - CidCbor.Cid value; |
18 | | - CidCbor.Cid tree; |
19 | | - } |
20 | | - |
21 | | - struct TreeNodeE { |
22 | | - uint8 p; // prefixlen |
23 | | - bytes k; // keysuffix |
24 | | - CidCbor.Cid v; // value |
25 | | - CidCbor.Cid t; // tree |
26 | | - } |
| 9 | + struct TreeNode { |
| 10 | + CidCbor.Cid left; |
| 11 | + TreeNodeEntry[] entries; |
| 12 | + } |
27 | 13 |
|
28 | | - function readNodeE(bytes memory cborData, uint byteIdx) internal pure returns (TreeNodeE[] memory ret, uint) { |
29 | | - uint arrayLen; |
30 | | - (arrayLen, byteIdx) = cborData.readFixedArray(byteIdx); |
| 14 | + struct TreeNodeEntry { |
| 15 | + string key; |
| 16 | + CidCbor.Cid value; |
| 17 | + CidCbor.Cid tree; |
| 18 | + } |
31 | 19 |
|
32 | | - ret = new TreeNodeE[](arrayLen); |
33 | | - for(uint i = 0; i < arrayLen; i++) { |
34 | | - (ret[i], byteIdx) = readE(cborData, byteIdx); |
| 20 | + struct TreeNodeE { |
| 21 | + uint8 p; // prefixlen |
| 22 | + bytes k; // keysuffix |
| 23 | + CidCbor.Cid v; // value |
| 24 | + CidCbor.Cid t; // tree |
35 | 25 | } |
36 | 26 |
|
37 | | - return (ret, byteIdx); |
38 | | - } |
| 27 | + function readNodeE(bytes memory cborData, uint byteIdx) internal pure returns (TreeNodeE[] memory ret, uint) { |
| 28 | + uint arrayLen; |
| 29 | + (arrayLen, byteIdx) = cborData.readFixedArray(byteIdx); |
39 | 30 |
|
40 | | - function readE(bytes memory cborData, uint byteIdx) internal pure returns (TreeNodeE memory ret, uint) { |
41 | | - uint mapLen; |
42 | | - (mapLen, byteIdx) = cborData.readFixedMap(byteIdx); |
| 31 | + ret = new TreeNodeE[](arrayLen); |
| 32 | + for (uint i = 0; i < arrayLen; i++) { |
| 33 | + (ret[i], byteIdx) = readE(cborData, byteIdx); |
| 34 | + } |
43 | 35 |
|
44 | | - require(mapLen == 4, "expected 4 fields in node entry"); |
45 | | - for(uint i = 0; i < mapLen; i++) { |
46 | | - string memory mapKey; |
47 | | - (mapKey, byteIdx) = cborData.readString(byteIdx); |
48 | | - if(Compare.stringsMatch(mapKey, "p")) { |
49 | | - (ret.p, byteIdx) = cborData.readUInt8(byteIdx); |
50 | | - } |
51 | | - else if(Compare.stringsMatch(mapKey, "k")) { |
52 | | - (ret.k, byteIdx) = cborData.readBytes(byteIdx); |
53 | | - } |
54 | | - else if(Compare.stringsMatch(mapKey, 't')) { |
55 | | - (ret.t, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
56 | | - } |
57 | | - else if(Compare.stringsMatch(mapKey, 'v')) { |
58 | | - (ret.v, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
59 | | - } |
| 36 | + return (ret, byteIdx); |
60 | 37 | } |
61 | 38 |
|
62 | | - return (ret, byteIdx); |
63 | | - } |
| 39 | + function readE(bytes memory cborData, uint byteIdx) internal pure returns (TreeNodeE memory ret, uint) { |
| 40 | + uint mapLen; |
| 41 | + (mapLen, byteIdx) = cborData.readFixedMap(byteIdx); |
| 42 | + |
| 43 | + require(mapLen == 4, "expected 4 fields in node entry"); |
| 44 | + for (uint i = 0; i < mapLen; i++) { |
| 45 | + string memory mapKey; |
| 46 | + (mapKey, byteIdx) = cborData.readString(byteIdx); |
| 47 | + if (Compare.stringsMatch(mapKey, "p")) { |
| 48 | + (ret.p, byteIdx) = cborData.readUInt8(byteIdx); |
| 49 | + } else if (Compare.stringsMatch(mapKey, "k")) { |
| 50 | + (ret.k, byteIdx) = cborData.readBytes(byteIdx); |
| 51 | + } else if (Compare.stringsMatch(mapKey, "t")) { |
| 52 | + (ret.t, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
| 53 | + } else if (Compare.stringsMatch(mapKey, "v")) { |
| 54 | + (ret.v, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
| 55 | + } |
| 56 | + } |
64 | 57 |
|
65 | | - function buildEntryKeys(TreeNodeE[] memory e) internal pure returns (TreeNodeEntry[] memory entries) { |
66 | | - entries = new TreeNodeEntry[](e.length); |
67 | | - bytes memory previousKey = new bytes(0); |
68 | | - for(uint i = 0; i < e.length; i++) { |
69 | | - uint8 p = e[i].p; |
70 | | - bytes memory k = e[i].k; |
71 | | - bytes memory key = new bytes(p + k.length); |
72 | | - for(uint j = 0; j < p; j++) { |
73 | | - key[j] = previousKey[j]; |
74 | | - } |
75 | | - for(uint j = p; j < p + k.length; j++) { |
76 | | - key[j] = k[j - p]; |
77 | | - } |
78 | | - entries[i].key = string(key); |
79 | | - previousKey = key; |
| 58 | + return (ret, byteIdx); |
80 | 59 | } |
81 | | - return entries; |
82 | | - } |
83 | 60 |
|
84 | | - function readTreeNode(bytes memory cborData, uint byteIdx) internal pure returns (TreeNode memory node, uint) { |
85 | | - uint mapLen; |
86 | | - (mapLen, byteIdx) = cborData.readFixedMap(byteIdx); |
87 | | - require(mapLen == 2, "expected 2 fields in node"); |
88 | | - for(uint i = 0; i < mapLen; i++) { |
89 | | - string memory mapKey; |
90 | | - (mapKey, byteIdx) = cborData.readString(byteIdx); |
91 | | - if(Compare.stringsMatch(mapKey, "l")) { |
92 | | - (node.left, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
93 | | - } |
94 | | - else if(Compare.stringsMatch(mapKey, "e")) { |
95 | | - TreeNodeE[] memory e; |
96 | | - (e, byteIdx) = readNodeE(cborData, byteIdx); |
97 | | - node.entries = buildEntryKeys(e); |
98 | | - } |
| 61 | + function buildEntryKeys(TreeNodeE[] memory e) internal pure returns (TreeNodeEntry[] memory entries) { |
| 62 | + entries = new TreeNodeEntry[](e.length); |
| 63 | + bytes memory previousKey = new bytes(0); |
| 64 | + for (uint i = 0; i < e.length; i++) { |
| 65 | + uint8 p = e[i].p; |
| 66 | + bytes memory k = e[i].k; |
| 67 | + bytes memory key = new bytes(p + k.length); |
| 68 | + for (uint j = 0; j < p; j++) { |
| 69 | + key[j] = previousKey[j]; |
| 70 | + } |
| 71 | + for (uint j = p; j < p + k.length; j++) { |
| 72 | + key[j] = k[j - p]; |
| 73 | + } |
| 74 | + entries[i].key = string(key); |
| 75 | + previousKey = key; |
| 76 | + } |
| 77 | + return entries; |
99 | 78 | } |
100 | | - return (node, byteIdx); |
101 | | - } |
102 | 79 |
|
| 80 | + function readTreeNode(bytes memory cborData, uint byteIdx) internal pure returns (TreeNode memory node, uint) { |
| 81 | + uint mapLen; |
| 82 | + (mapLen, byteIdx) = cborData.readFixedMap(byteIdx); |
| 83 | + require(mapLen == 2, "expected 2 fields in node"); |
| 84 | + for (uint i = 0; i < mapLen; i++) { |
| 85 | + string memory mapKey; |
| 86 | + (mapKey, byteIdx) = cborData.readString(byteIdx); |
| 87 | + if (Compare.stringsMatch(mapKey, "l")) { |
| 88 | + (node.left, byteIdx) = CidCbor.readCid(cborData, byteIdx, false); |
| 89 | + } else if (Compare.stringsMatch(mapKey, "e")) { |
| 90 | + TreeNodeE[] memory e; |
| 91 | + (e, byteIdx) = readNodeE(cborData, byteIdx); |
| 92 | + node.entries = buildEntryKeys(e); |
| 93 | + } |
| 94 | + } |
| 95 | + return (node, byteIdx); |
| 96 | + } |
103 | 97 | } |
0 commit comments