Skip to content

Commit f33c2ea

Browse files
committed
Fix initialization order issue in streamers.
1 parent fd126e4 commit f33c2ea

21 files changed

Lines changed: 236 additions & 77 deletions

include/bitcoin/system/impl/stream/streamers/bit_reader.ipp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,19 @@ namespace system {
3434
// constructors
3535
// ----------------------------------------------------------------------------
3636

37+
// protected
38+
template <typename IStream>
39+
bit_reader<IStream>::bit_reader() NOEXCEPT
40+
: base(),
41+
byte_(base::pad()),
42+
offset_(byte_bits)
43+
{
44+
}
45+
3746
template <typename IStream>
3847
bit_reader<IStream>::bit_reader(IStream& source) NOEXCEPT
39-
: byte_reader<IStream>(source),
40-
byte_(byte_reader<IStream>::pad()),
48+
: base(source),
49+
byte_(base::pad()),
4150
offset_(byte_bits)
4251
{
4352
}
@@ -144,10 +153,10 @@ void bit_reader<IStream>::do_rewind_bytes(size_t size) NOEXCEPT
144153
template <typename IStream>
145154
bool bit_reader<IStream>::get_exhausted() const NOEXCEPT
146155
{
147-
if (byte_reader<IStream>::operator!())
156+
if (base::operator!())
148157
return true;
149158

150-
return is_zero(shift()) && byte_reader<IStream>::get_exhausted();
159+
return is_zero(shift()) && base::get_exhausted();
151160
}
152161

153162
// private
@@ -158,24 +167,24 @@ void bit_reader<IStream>::load() NOEXCEPT
158167
{
159168
// The next bit read will be from this byte.
160169
offset_ = 0;
161-
byte_ = byte_reader<IStream>::pad();
162-
byte_reader<IStream>::do_read_bytes(&byte_, one);
170+
byte_ = base::pad();
171+
base::do_read_bytes(&byte_, one);
163172
}
164173

165174
template <typename IStream>
166175
void bit_reader<IStream>::reload() NOEXCEPT
167176
{
168177
offset_ = byte_bits;
169-
byte_ = byte_reader<IStream>::pad();
170-
byte_reader<IStream>::do_rewind_bytes(two);
171-
byte_reader<IStream>::do_read_bytes(&byte_, one);
178+
byte_ = base::pad();
179+
base::do_rewind_bytes(two);
180+
base::do_read_bytes(&byte_, one);
172181
}
173182

174183
// This is the only byte peek.
175184
template <typename IStream>
176185
uint8_t bit_reader<IStream>::peek() NOEXCEPT
177186
{
178-
return byte_reader<IStream>::do_peek_byte();
187+
return base::do_peek_byte();
179188
}
180189

181190
template <typename OStream>

include/bitcoin/system/impl/stream/streamers/bit_writer.ipp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,20 @@ namespace system {
3333

3434
// constructors
3535
// ----------------------------------------------------------------------------
36+
37+
// protected
38+
template <typename OStream>
39+
bit_writer<OStream>::bit_writer() NOEXCEPT
40+
: base(),
41+
byte_(base::pad()),
42+
offset_(0)
43+
{
44+
}
3645

3746
template <typename OStream>
3847
bit_writer<OStream>::bit_writer(OStream& sink) NOEXCEPT
39-
: byte_writer<OStream>(sink),
40-
byte_(byte_writer<OStream>::pad()),
48+
: base(sink),
49+
byte_(base::pad()),
4150
offset_(0)
4251
{
4352
}
@@ -91,7 +100,7 @@ template <typename OStream>
91100
void bit_writer<OStream>::do_flush() NOEXCEPT
92101
{
93102
flusher();
94-
byte_writer<OStream>::do_flush();
103+
base::do_flush();
95104
}
96105

97106
// private
@@ -101,8 +110,8 @@ void bit_writer<OStream>::do_flush() NOEXCEPT
101110
template <typename OStream>
102111
void bit_writer<OStream>::unload() NOEXCEPT
103112
{
104-
byte_writer<OStream>::do_write_bytes(&byte_, one);
105-
byte_ = byte_writer<OStream>::pad();
113+
base::do_write_bytes(&byte_, one);
114+
byte_ = base::pad();
106115
offset_ = 0;
107116
}
108117

include/bitcoin/system/impl/stream/streamers/byte_reader.ipp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,42 @@ byte_reader<IStream>::default_arena() NOEXCEPT
4444
return bc::default_arena::get();
4545
}
4646

47+
// protected/friend accessor
48+
template <typename IStream>
49+
void byte_reader<IStream>::set_stream(IStream* stream) NOEXCEPT
50+
{
51+
stream_ = stream;
52+
}
53+
4754
// All public methods must rely on protected for stream state except validity.
4855

4956
// constructors
5057
// ----------------------------------------------------------------------------
5158

59+
// protected
60+
template <typename IStream>
61+
byte_reader<IStream>::byte_reader() NOEXCEPT
62+
: stream_(nullptr),
63+
remaining_(system::maximum<size_t>),
64+
allocator_(default_arena())
65+
{
66+
// stream_ set by friend make_streamer<>.
67+
}
68+
69+
template <typename IStream>
70+
byte_reader<IStream>::byte_reader(IStream& source) NOEXCEPT
71+
: byte_reader(source, default_arena())
72+
{
73+
}
74+
5275
template <typename IStream>
5376
byte_reader<IStream>::byte_reader(IStream& source,
5477
const memory_arena& arena) NOEXCEPT
55-
: stream_(source),
78+
: stream_(&source),
5679
remaining_(system::maximum<size_t>),
5780
allocator_(arena)
5881
{
59-
////BC_ASSERT_MSG(stream_.exceptions() == IStream::goodbit,
82+
////BC_ASSERT_MSG(stream_->exceptions() == IStream::goodbit,
6083
//// "Input stream must not be configured to throw exceptions.");
6184
}
6285

@@ -666,7 +689,7 @@ uint8_t byte_reader<IStream>::do_peek_byte() NOEXCEPT
666689
// the call the achieve consistent behavior. The reader will be invalid if
667690
// the stream is peeked past end, including when empty.
668691
const auto value =
669-
possible_narrow_and_sign_cast<uint8_t>(stream_.peek());
692+
possible_narrow_and_sign_cast<uint8_t>(stream_->peek());
670693

671694
validate();
672695
return valid() ? value : pad();
@@ -679,15 +702,15 @@ void byte_reader<IStream>::do_read_bytes(uint8_t* buffer, size_t size) NOEXCEPT
679702
if (limiter(size))
680703
return;
681704

682-
// It is not generally more efficient to call stream_.get() for one byte.
705+
// It is not generally more efficient to call stream_->get() for one byte.
683706
// Partially-failed reads here will be populated by the stream, not padded.
684707
// However, both copy_source and stringstream will zero-fill partial reads.
685708
// Read on empty is inconsistent, so validate the result. The reader will be
686709
// invalid if the stream is get past end, including when empty.
687710

688711
// Read past stream end invalidates stream unless size exceeds maximum.
689712
BC_ASSERT(size <= maximum);
690-
stream_.read(pointer_cast<char>(buffer),
713+
stream_->read(pointer_cast<char>(buffer),
691714
possible_narrow_and_sign_cast<typename IStream::pos_type>(size));
692715

693716
validate();
@@ -739,9 +762,9 @@ bool byte_reader<IStream>::get_exhausted() const NOEXCEPT
739762
return true;
740763

741764
// Peek to force error on eof, save condition, restore valid stream state.
742-
stream_.peek();
765+
stream_->peek();
743766
const auto eof = !valid();
744-
stream_.clear();
767+
stream_->clear();
745768

746769
return eof;
747770
}
@@ -754,15 +777,15 @@ template <typename IStream>
754777
bool byte_reader<IStream>::valid() const NOEXCEPT
755778
{
756779
// zero is the istream documented flag for no error.
757-
return stream_.rdstate() == IStream::goodbit;
780+
return stream_->rdstate() == IStream::goodbit;
758781
}
759782

760783
template <typename IStream>
761784
void byte_reader<IStream>::invalid() NOEXCEPT
762785
{
763786
// If eofbit is set, failbit is generally set on all operations.
764787
// badbit is unrecoverable, set the others to ensure consistency.
765-
stream_.setstate(IStream::eofbit | IStream::failbit | IStream::badbit);
788+
stream_->setstate(IStream::eofbit | IStream::failbit | IStream::badbit);
766789
}
767790

768791
template <typename IStream>
@@ -780,7 +803,7 @@ template <typename IStream>
780803
void byte_reader<IStream>::clear() NOEXCEPT
781804
{
782805
// Does not reset the current position.
783-
stream_.clear();
806+
stream_->clear();
784807
}
785808

786809
template <typename IStream>
@@ -795,7 +818,7 @@ size_t byte_reader<IStream>::getter() NOEXCEPT
795818
try
796819
{
797820
// This does not honor BOOST_EXCEPTION_DISABLE.
798-
position = stream_.tellg();
821+
position = stream_->tellg();
799822
validate();
800823
}
801824
catch (const typename IStream::failure&)
@@ -844,7 +867,7 @@ void byte_reader<IStream>::seeker(typename IStream::pos_type offset) NOEXCEPT
844867
try
845868
{
846869
// This does not honor BOOST_EXCEPTION_DISABLE.
847-
stream_.seekg(offset, IStream::cur);
870+
stream_->seekg(offset, IStream::cur);
848871
validate();
849872
}
850873
catch (const typename IStream::failure&)

include/bitcoin/system/impl/stream/streamers/byte_writer.ipp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,29 @@ namespace system {
3434

3535
// All public methods must rely on protected for stream state except validity.
3636

37+
// protected/friend accessor
38+
template <typename OStream>
39+
void byte_writer<OStream>::set_stream(OStream* stream) NOEXCEPT
40+
{
41+
stream_ = stream;
42+
}
43+
3744
// constructors
3845
// ----------------------------------------------------------------------------
3946

47+
// protected
48+
template <typename OStream>
49+
byte_writer<OStream>::byte_writer() NOEXCEPT
50+
: stream_(nullptr)
51+
{
52+
// stream_ set by friend make_streamer<>.
53+
}
54+
4055
template <typename OStream>
4156
byte_writer<OStream>::byte_writer(OStream& sink) NOEXCEPT
42-
: stream_(sink)
57+
: stream_(&sink)
4358
{
44-
////BC_ASSERT_MSG(stream_.exceptions() == OStream::goodbit,
59+
////BC_ASSERT_MSG(stream_->exceptions() == OStream::goodbit,
4560
//// "Output stream must not be configured to throw exceptions.");
4661
}
4762

@@ -304,11 +319,11 @@ template <typename OStream>
304319
void byte_writer<OStream>::do_write_bytes(const uint8_t* data,
305320
size_t size) NOEXCEPT
306321
{
307-
// It is not generally more efficient to call stream_.put() for one byte.
322+
// It is not generally more efficient to call stream_->put() for one byte.
308323

309324
// Write past stream start invalidates stream unless size exceeds maximum.
310325
BC_ASSERT(size <= maximum);
311-
stream_.write(pointer_cast<const char>(data),
326+
stream_->write(pointer_cast<const char>(data),
312327
possible_narrow_and_sign_cast<typename OStream::pos_type>(size));
313328

314329
validate();
@@ -328,15 +343,15 @@ template <typename OStream>
328343
bool byte_writer<OStream>::valid() const NOEXCEPT
329344
{
330345
// zero is the istream documented flag for no error.
331-
return stream_.rdstate() == OStream::goodbit;
346+
return stream_->rdstate() == OStream::goodbit;
332347
}
333348

334349
template <typename OStream>
335350
void byte_writer<OStream>::invalid() NOEXCEPT
336351
{
337352
// If eofbit is set, failbit is generally set on all operations.
338353
// badbit is unrecoverable, set the others to ensure consistency.
339-
stream_.setstate(OStream::eofbit | OStream::failbit | OStream::badbit);
354+
stream_->setstate(OStream::eofbit | OStream::failbit | OStream::badbit);
340355
}
341356

342357
template <typename OStream>
@@ -352,7 +367,7 @@ void byte_writer<OStream>::validate() NOEXCEPT
352367
template <typename OStream>
353368
void byte_writer<OStream>::flusher() NOEXCEPT
354369
{
355-
stream_.flush();
370+
stream_->flush();
356371
validate();
357372
}
358373

@@ -368,7 +383,7 @@ size_t byte_writer<OStream>::getter() NOEXCEPT
368383
try
369384
{
370385
// This does not honor BOOST_EXCEPTION_DISABLE.
371-
position = stream_.tellp();
386+
position = stream_->tellp();
372387
validate();
373388
}
374389
catch (const typename OStream::failure&)

include/bitcoin/system/impl/stream/streamers/hex_reader.ipp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ namespace system {
2929
// constructors
3030
// ----------------------------------------------------------------------------
3131

32+
// protected
33+
template <typename IStream>
34+
hex_reader<IStream>::hex_reader() NOEXCEPT
35+
: base()
36+
{
37+
}
38+
3239
template <typename IStream>
3340
hex_reader<IStream>::hex_reader(IStream& source) NOEXCEPT
3441
: base(source)

include/bitcoin/system/impl/stream/streamers/hex_writer.ipp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ namespace system {
3030
// constructors
3131
// ----------------------------------------------------------------------------
3232

33+
// protected
34+
template <typename OStream>
35+
hex_writer<OStream>::hex_writer() NOEXCEPT
36+
: base()
37+
{
38+
}
39+
40+
3341
template <typename OStream>
3442
hex_writer<OStream>::hex_writer(OStream& sink) NOEXCEPT
3543
: base(sink)

include/bitcoin/system/impl/stream/streamers/sha256_writer.ipp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,15 @@ namespace system {
2929
// constructors
3030
// ----------------------------------------------------------------------------
3131

32+
template <typename OStream>
33+
sha256_writer<OStream>::sha256_writer() NOEXCEPT
34+
: base()
35+
{
36+
}
37+
3238
template <typename OStream>
3339
sha256_writer<OStream>::sha256_writer(OStream& sink) NOEXCEPT
34-
: byte_writer<OStream>(sink)
40+
: base(sink)
3541
{
3642
}
3743

@@ -58,7 +64,7 @@ template <typename OStream>
5864
void sha256_writer<OStream>::do_flush() NOEXCEPT
5965
{
6066
flusher();
61-
byte_writer<OStream>::do_flush();
67+
base::do_flush();
6268
}
6369

6470
// private
@@ -74,7 +80,7 @@ void sha256_writer<OStream>::flusher() NOEXCEPT
7480
context_.reset();
7581

7682
// Write hash to stream.
77-
byte_writer<OStream>::do_write_bytes(hash.data(), hash_size);
83+
base::do_write_bytes(hash.data(), hash_size);
7884
}
7985

8086
} // namespace system

0 commit comments

Comments
 (0)