| 273 | */ |
| 274 | template<typename Stream> |
| 275 | uint64_t ReadCompactSize(Stream& is, bool range_check = true) |
| 276 | { |
| 277 | uint8_t chSize = ser_readdata8(is); |
| 278 | uint64_t nSizeRet = 0; |
| 279 | if (chSize < 253) |
| 280 | { |
| 281 | nSizeRet = chSize; |
| 282 | } |
| 283 | else if (chSize == 253) |
| 284 | { |
| 285 | nSizeRet = ser_readdata16(is); |
| 286 | if (nSizeRet < 253) |
| 287 | throw std::ios_base::failure("non-canonical ReadCompactSize()"); |
| 288 | } |
| 289 | else if (chSize == 254) |
| 290 | { |
| 291 | nSizeRet = ser_readdata32(is); |
| 292 | if (nSizeRet < 0x10000u) |
| 293 | throw std::ios_base::failure("non-canonical ReadCompactSize()"); |
| 294 | } |
| 295 | else |
| 296 | { |
| 297 | nSizeRet = ser_readdata64(is); |
| 298 | if (nSizeRet < 0x100000000ULL) |
| 299 | throw std::ios_base::failure("non-canonical ReadCompactSize()"); |
| 300 | } |
| 301 | if (range_check && nSizeRet > MAX_SIZE) { |
| 302 | throw std::ios_base::failure("ReadCompactSize(): size too large"); |
| 303 | } |
| 304 | return nSizeRet; |
| 305 | } |
| 306 | |
| 307 | /** |
| 308 | * Variable-length integers: bytes are a MSB base-128 encoding of the number. |