|
17 | 17 | #include <cstdint>
|
18 | 18 | #include <cstring>
|
19 | 19 | #include <limits>
|
| 20 | +#include <span> |
20 | 21 | #include <stdexcept>
|
21 | 22 | #include <string>
|
22 | 23 | #include <type_traits>
|
@@ -412,6 +413,32 @@ bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator en
|
412 | 413 | /** Serialized script, used inside transaction inputs and outputs */
|
413 | 414 | class CScript : public CScriptBase
|
414 | 415 | {
|
| 416 | +private: |
| 417 | + inline void AppendDataSize(const uint32_t size) |
| 418 | + { |
| 419 | + if (size < OP_PUSHDATA1) { |
| 420 | + insert(end(), static_cast<value_type>(size)); |
| 421 | + } else if (size <= 0xff) { |
| 422 | + insert(end(), OP_PUSHDATA1); |
| 423 | + insert(end(), static_cast<value_type>(size)); |
| 424 | + } else if (size <= 0xffff) { |
| 425 | + insert(end(), OP_PUSHDATA2); |
| 426 | + value_type data[2]; |
| 427 | + WriteLE16(data, size); |
| 428 | + insert(end(), std::cbegin(data), std::cend(data)); |
| 429 | + } else { |
| 430 | + insert(end(), OP_PUSHDATA4); |
| 431 | + value_type data[4]; |
| 432 | + WriteLE32(data, size); |
| 433 | + insert(end(), std::cbegin(data), std::cend(data)); |
| 434 | + } |
| 435 | + } |
| 436 | + |
| 437 | + void AppendData(std::span<const value_type> data) |
| 438 | + { |
| 439 | + insert(end(), data.begin(), data.end()); |
| 440 | + } |
| 441 | + |
415 | 442 | protected:
|
416 | 443 | CScript& push_int64(int64_t n)
|
417 | 444 | {
|
@@ -463,35 +490,19 @@ class CScript : public CScriptBase
|
463 | 490 | return *this;
|
464 | 491 | }
|
465 | 492 |
|
466 |
| - CScript& operator<<(const std::vector<unsigned char>& b) LIFETIMEBOUND |
| 493 | + CScript& operator<<(std::span<const std::byte> b) LIFETIMEBOUND |
467 | 494 | {
|
468 |
| - if (b.size() < OP_PUSHDATA1) |
469 |
| - { |
470 |
| - insert(end(), (unsigned char)b.size()); |
471 |
| - } |
472 |
| - else if (b.size() <= 0xff) |
473 |
| - { |
474 |
| - insert(end(), OP_PUSHDATA1); |
475 |
| - insert(end(), (unsigned char)b.size()); |
476 |
| - } |
477 |
| - else if (b.size() <= 0xffff) |
478 |
| - { |
479 |
| - insert(end(), OP_PUSHDATA2); |
480 |
| - uint8_t _data[2]; |
481 |
| - WriteLE16(_data, b.size()); |
482 |
| - insert(end(), _data, _data + sizeof(_data)); |
483 |
| - } |
484 |
| - else |
485 |
| - { |
486 |
| - insert(end(), OP_PUSHDATA4); |
487 |
| - uint8_t _data[4]; |
488 |
| - WriteLE32(_data, b.size()); |
489 |
| - insert(end(), _data, _data + sizeof(_data)); |
490 |
| - } |
491 |
| - insert(end(), b.begin(), b.end()); |
| 495 | + AppendDataSize(b.size()); |
| 496 | + AppendData({reinterpret_cast<const value_type*>(b.data()), b.size()}); |
492 | 497 | return *this;
|
493 | 498 | }
|
494 | 499 |
|
| 500 | + // For compatibility reasons. In new code, prefer using std::byte instead of uint8_t. |
| 501 | + CScript& operator<<(std::span<const value_type> b) LIFETIMEBOUND |
| 502 | + { |
| 503 | + return *this << std::as_bytes(b); |
| 504 | + } |
| 505 | + |
495 | 506 | bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) const
|
496 | 507 | {
|
497 | 508 | return GetScriptOp(pc, end(), opcodeRet, &vchRet);
|
|
0 commit comments