TrieCommon.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file TrieCommon.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include "TrieCommon.h"
  19. namespace dev
  20. {
  21. /*
  22. * Hex-prefix Notation. First nibble has flags: oddness = 2^0 & termination = 2^1
  23. * NOTE: the "termination marker" and "leaf-node" specifier are completely equivalent.
  24. * [0,0,1,2,3,4,5] 0x10012345
  25. * [0,1,2,3,4,5] 0x00012345
  26. * [1,2,3,4,5] 0x112345
  27. * [0,0,1,2,3,4] 0x00001234
  28. * [0,1,2,3,4] 0x101234
  29. * [1,2,3,4] 0x001234
  30. * [0,0,1,2,3,4,5,T] 0x30012345
  31. * [0,0,1,2,3,4,T] 0x20001234
  32. * [0,1,2,3,4,5,T] 0x20012345
  33. * [1,2,3,4,5,T] 0x312345
  34. * [1,2,3,4,T] 0x201234
  35. */
  36. std::string hexPrefixEncode(bytes const& _hexVector, bool _leaf, int _begin, int _end)
  37. {
  38. unsigned begin = _begin;
  39. unsigned end = _end < 0 ? _hexVector.size() + 1 + _end : _end;
  40. bool odd = ((end - begin) % 2) != 0;
  41. std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16);
  42. if (odd)
  43. {
  44. ret[0] |= _hexVector[begin];
  45. ++begin;
  46. }
  47. for (unsigned i = begin; i < end; i += 2)
  48. ret += _hexVector[i] * 16 + _hexVector[i + 1];
  49. return ret;
  50. }
  51. std::string hexPrefixEncode(bytesConstRef _data, bool _leaf, int _beginNibble, int _endNibble, unsigned _offset)
  52. {
  53. unsigned begin = _beginNibble + _offset;
  54. unsigned end = (_endNibble < 0 ? ((int)(_data.size() * 2 - _offset) + 1) + _endNibble : _endNibble) + _offset;
  55. bool odd = (end - begin) & 1;
  56. std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16);
  57. ret.reserve((end - begin) / 2 + 1);
  58. unsigned d = odd ? 1 : 2;
  59. for (auto i = begin; i < end; ++i, ++d)
  60. {
  61. byte n = nibble(_data, i);
  62. if (d & 1) // odd
  63. ret.back() |= n; // or the nibble onto the back
  64. else
  65. ret.push_back(n << 4); // push the nibble on to the back << 4
  66. }
  67. return ret;
  68. }
  69. std::string hexPrefixEncode(bytesConstRef _d1, unsigned _o1, bytesConstRef _d2, unsigned _o2, bool _leaf)
  70. {
  71. unsigned begin1 = _o1;
  72. unsigned end1 = _d1.size() * 2;
  73. unsigned begin2 = _o2;
  74. unsigned end2 = _d2.size() * 2;
  75. bool odd = (end1 - begin1 + end2 - begin2) & 1;
  76. std::string ret(1, ((_leaf ? 2 : 0) | (odd ? 1 : 0)) * 16);
  77. ret.reserve((end1 - begin1 + end2 - begin2) / 2 + 1);
  78. unsigned d = odd ? 1 : 2;
  79. for (auto i = begin1; i < end1; ++i, ++d)
  80. {
  81. byte n = nibble(_d1, i);
  82. if (d & 1) // odd
  83. ret.back() |= n; // or the nibble onto the back
  84. else
  85. ret.push_back(n << 4); // push the nibble on to the back << 4
  86. }
  87. for (auto i = begin2; i < end2; ++i, ++d)
  88. {
  89. byte n = nibble(_d2, i);
  90. if (d & 1) // odd
  91. ret.back() |= n; // or the nibble onto the back
  92. else
  93. ret.push_back(n << 4); // push the nibble on to the back << 4
  94. }
  95. return ret;
  96. }
  97. byte uniqueInUse(RLP const& _orig, byte except)
  98. {
  99. byte used = 255;
  100. for (unsigned i = 0; i < 17; ++i)
  101. if (i != except && !_orig[i].isEmpty())
  102. {
  103. if (used == 255)
  104. used = (byte)i;
  105. else
  106. return 255;
  107. }
  108. return used;
  109. }
  110. }