9
9
#define GOOGLE_PROTOBUF_IO_TEST_ZERO_COPY_STREAM_H__
10
10
11
11
#include < deque>
12
+ #include < memory>
12
13
#include < string>
13
14
#include < utility>
14
15
#include < vector>
15
16
16
17
#include " absl/log/absl_check.h"
17
- #include " absl/types/optional.h"
18
18
#include " google/protobuf/io/zero_copy_stream.h"
19
19
20
20
// Must be included last.
@@ -37,18 +37,22 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
37
37
TestZeroCopyInputStream (const TestZeroCopyInputStream& other)
38
38
: ZeroCopyInputStream(),
39
39
buffers_ (other.buffers_),
40
- last_returned_buffer_(other.last_returned_buffer_),
40
+ last_returned_buffer_(
41
+ other.last_returned_buffer_
42
+ ? std::make_unique<std::string>(*other.last_returned_buffer_)
43
+ : nullptr),
41
44
byte_count_(other.byte_count_) {}
42
45
43
46
bool Next (const void ** data, int * size) override {
44
47
ABSL_CHECK (data) << " data must not be null" ;
45
48
ABSL_CHECK (size) << " size must not be null" ;
46
- last_returned_buffer_ = absl::nullopt ;
49
+ last_returned_buffer_ = nullptr ;
47
50
48
51
// We are done
49
52
if (buffers_.empty ()) return false ;
50
53
51
- last_returned_buffer_ = std::move (buffers_.front ());
54
+ last_returned_buffer_ =
55
+ std::make_unique<std::string>(std::move (buffers_.front ()));
52
56
buffers_.pop_front ();
53
57
*data = last_returned_buffer_->data ();
54
58
*size = static_cast <int >(last_returned_buffer_->size ());
@@ -58,19 +62,19 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
58
62
59
63
void BackUp (int count) override {
60
64
ABSL_CHECK_GE (count, 0 ) << " count must not be negative" ;
61
- ABSL_CHECK (last_returned_buffer_. has_value () )
65
+ ABSL_CHECK (last_returned_buffer_ != nullptr )
62
66
<< " The last call was not a successful Next()" ;
63
67
ABSL_CHECK_LE (count, last_returned_buffer_->size ())
64
68
<< " count must be within bounds of last buffer" ;
65
69
buffers_.push_front (
66
70
last_returned_buffer_->substr (last_returned_buffer_->size () - count));
67
- last_returned_buffer_ = absl::nullopt ;
71
+ last_returned_buffer_ = nullptr ;
68
72
byte_count_ -= count;
69
73
}
70
74
71
75
bool Skip (int count) override {
72
76
ABSL_CHECK_GE (count, 0 ) << " count must not be negative" ;
73
- last_returned_buffer_ = absl::nullopt ;
77
+ last_returned_buffer_ = nullptr ;
74
78
while (true ) {
75
79
if (count == 0 ) return true ;
76
80
if (buffers_.empty ()) return false ;
@@ -96,7 +100,9 @@ class TestZeroCopyInputStream final : public ZeroCopyInputStream {
96
100
// move them to `last_returned_buffer_`. It makes it simpler to keep track of
97
101
// the state of the object. The extra cost is not relevant for testing.
98
102
std::deque<std::string> buffers_;
99
- absl::optional<std::string> last_returned_buffer_;
103
+ // absl::optional could work here, but std::unique_ptr makes it more likely
104
+ // for sanitizers to detect if the string is used after it is destroyed.
105
+ std::unique_ptr<std::string> last_returned_buffer_;
100
106
int64_t byte_count_ = 0 ;
101
107
};
102
108
0 commit comments