Skip to content

Commit 25aa3ca

Browse files
committed
Added std::ostream os in DataSink.
1 parent 2d67211 commit 25aa3ca

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

httplib.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ using MultipartFormDataMap = std::multimap<std::string, MultipartFormData>;
215215

216216
class DataSink {
217217
public:
218-
DataSink() = default;
218+
DataSink() : os(&sb_), sb_(*this) {}
219+
219220
DataSink(const DataSink &) = delete;
220221
DataSink &operator=(const DataSink &) = delete;
221222
DataSink(DataSink &&) = delete;
@@ -224,6 +225,24 @@ class DataSink {
224225
std::function<void(const char *data, size_t data_len)> write;
225226
std::function<void()> done;
226227
std::function<bool()> is_writable;
228+
std::ostream os;
229+
230+
private:
231+
class data_sink_streambuf : public std::streambuf {
232+
public:
233+
data_sink_streambuf(DataSink &sink) : sink_(sink) {}
234+
235+
protected:
236+
std::streamsize xsputn(const char *s, std::streamsize n) {
237+
sink_.write(s, static_cast<size_t>(n));
238+
return n;
239+
}
240+
241+
private:
242+
DataSink &sink_;
243+
};
244+
245+
data_sink_streambuf sb_;
227246
};
228247

229248
using ContentProvider =
@@ -2084,22 +2103,20 @@ inline ssize_t write_content(Stream &strm, ContentProvider content_provider,
20842103
size_t begin_offset = offset;
20852104
size_t end_offset = offset + length;
20862105

2087-
ssize_t written_length = 0;
2106+
auto ok = true;
20882107

20892108
DataSink data_sink;
20902109
data_sink.write = [&](const char *d, size_t l) {
20912110
offset += l;
2092-
written_length = strm.write(d, l);
2093-
};
2094-
data_sink.is_writable = [&](void) {
2095-
return strm.is_writable() && written_length >= 0;
2111+
if (strm.write(d, l) < 0) { ok = false; }
20962112
};
2113+
data_sink.is_writable = [&](void) { return strm.is_writable() && ok; };
20972114

20982115
while (offset < end_offset) {
20992116
if (!content_provider(offset, end_offset - offset, data_sink)) {
21002117
return -1;
21012118
}
2102-
if (written_length < 0) { return written_length; }
2119+
if (!ok) { return -1; }
21032120
}
21042121

21052122
return static_cast<ssize_t>(offset - begin_offset);

test/test.cc

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -875,9 +875,9 @@ class ServerTest : public ::testing::Test {
875875
res.set_chunked_content_provider(
876876
[](size_t /*offset*/, DataSink &sink) {
877877
EXPECT_TRUE(sink.is_writable());
878-
sink.write("123", 3);
879-
sink.write("456", 3);
880-
sink.write("789", 3);
878+
sink.os << "123";
879+
sink.os << "456";
880+
sink.os << "789";
881881
sink.done();
882882
return true;
883883
});
@@ -889,9 +889,9 @@ class ServerTest : public ::testing::Test {
889889
[i](size_t /*offset*/, DataSink &sink) {
890890
EXPECT_TRUE(sink.is_writable());
891891
switch (*i) {
892-
case 0: sink.write("123", 3); break;
893-
case 1: sink.write("456", 3); break;
894-
case 2: sink.write("789", 3); break;
892+
case 0: sink.os << "123"; break;
893+
case 1: sink.os << "456"; break;
894+
case 2: sink.os << "789"; break;
895895
case 3: sink.done(); break;
896896
}
897897
(*i)++;
@@ -903,7 +903,7 @@ class ServerTest : public ::testing::Test {
903903
[&](const Request & /*req*/, Response &res) {
904904
res.set_content_provider(
905905
6, [](size_t offset, size_t /*length*/, DataSink &sink) {
906-
sink.write(offset < 3 ? "a" : "b", 1);
906+
sink.os << (offset < 3 ? "a" : "b");
907907
return true;
908908
});
909909
})
@@ -929,8 +929,7 @@ class ServerTest : public ::testing::Test {
929929
size_t(-1),
930930
[](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
931931
EXPECT_TRUE(sink.is_writable());
932-
std::string data = "data_chunk";
933-
sink.write(data.data(), data.size());
932+
sink.os << "data_chunk";
934933
return true;
935934
});
936935
})
@@ -1898,7 +1897,7 @@ TEST_F(ServerTest, PutWithContentProvider) {
18981897
"/put", 3,
18991898
[](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
19001899
EXPECT_TRUE(sink.is_writable());
1901-
sink.write("PUT", 3);
1900+
sink.os << "PUT";
19021901
return true;
19031902
},
19041903
"text/plain");
@@ -1926,7 +1925,7 @@ TEST_F(ServerTest, PutWithContentProviderWithGzip) {
19261925
"/put", 3,
19271926
[](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
19281927
EXPECT_TRUE(sink.is_writable());
1929-
sink.write("PUT", 3);
1928+
sink.os << "PUT";
19301929
return true;
19311930
},
19321931
"text/plain");

0 commit comments

Comments
 (0)