diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index eee4c0ac..ed9a1920 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -62,6 +62,39 @@ static DrivenEngine *make_engine(std::string_view kind) { return nullptr; } +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// +// The stdostream +// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +class StreamBufferWriter : public std::streambuf, public eng::opnew { +private: + StreamBuffer *target_; +public: + StreamBufferWriter(StreamBuffer *t) : target_(t) {} + + virtual int_type overflow(int_type c) { + if (c != EOF) { + target_->write_uint8(c); + } + return c; + } +}; + +class StreamBufferOStream : public std::ostream, public eng::opnew { +private: + StreamBufferWriter writer_; +public: + StreamBufferOStream(StreamBuffer *t) : std::ostream(nullptr), writer_(t) { + rdbuf(&writer_); + } + virtual ~StreamBufferOStream() { + } +}; + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // @@ -156,6 +189,7 @@ void DrivenEngine::stop_driver() { DrivenEngine::DrivenEngine() { next_unused_chid_ = 1; stdio_channel_ = eng::make_shared(this, 0, 0, "", false); + stdostream_.reset(new StreamBufferOStream(stdio_channel_->out())); channels_[0] = stdio_channel_; rescan_lua_source_ = false; clock_ = 0.0; diff --git a/luprex/cpp/core/drivenengine.hpp b/luprex/cpp/core/drivenengine.hpp index b8c8c265..0a29ef40 100644 --- a/luprex/cpp/core/drivenengine.hpp +++ b/luprex/cpp/core/drivenengine.hpp @@ -204,7 +204,7 @@ public: // Obtain the output buffer of the stdio channel as an ostream. // - std::ostream &stdostream() { return get_stdio_channel()->out()->ostream(); } + std::ostream &stdostream() { return *stdostream_; } // Set the prompt for the console. // @@ -305,6 +305,7 @@ private: SharedChannel channels_[DRV_MAX_CHAN]; int next_unused_chid_; SharedChannel stdio_channel_; + std::unique_ptr stdostream_; eng::vector accepted_channels_; eng::vector new_outgoing_; util::LuaSourcePtr lua_source_; diff --git a/luprex/cpp/core/http.cpp b/luprex/cpp/core/http.cpp index 1d420fba..962a099d 100644 --- a/luprex/cpp/core/http.cpp +++ b/luprex/cpp/core/http.cpp @@ -248,8 +248,7 @@ static void send_encoded_path(std::string_view path, const UrlParameters ¶ms static void send_host_and_port(std::string_view host, int port, StreamBuffer *sb) { sb->write_bytes(host); if (port != 0) { - sb->write_char(':'); - sb->ostream() << port; + sb->write_bytes(util::ss(":", port)); } } @@ -263,9 +262,7 @@ static void send_protocol(bool http11, StreamBuffer *sb) { static void send_content_length_header(bool http11, int size, StreamBuffer *sb) { if (http11) { - sb->write_bytes("Content-length: "); - sb->ostream() << size; - sb->write_bytes("\r\n"); + sb->write_bytes(util::ss("Content-length: ", size, "\r\n")); } } @@ -285,7 +282,7 @@ static void send_cache_control_header(bool http11, int max_age, StreamBuffer *sb if (max_age == 0) { sb->write_bytes("Cache-control: no-cache\r\n"); } else { - sb->ostream() << "Cache-control: max-age=" << max_age << "\r\n"; + sb->write_bytes(util::ss("Cache-control: max-age=", max_age, "\r\n")); } } else { sb->write_bytes("Pragma: no-cache\r\n"); @@ -305,7 +302,7 @@ static void send_connection_header(bool http11, bool keep_alive, StreamBuffer *s static void send_error_response(bool http11, int code, eng::string extrainfo, StreamBuffer *sb) { send_protocol(http11, sb); eng::string errstr = status_code_to_string(code); - sb->ostream() << " " << code << " " << errstr; + sb->write_bytes(util::ss(" ", code, " ", errstr)); if ((!extrainfo.empty()) && (!contains_newline(extrainfo))) { sb->write_bytes(": "); sb->write_bytes(extrainfo); @@ -480,7 +477,7 @@ void HttpClientRequest::send_internal(StreamBuffer *sb, bool debug_string) const // Add the requester IDs (debug string only) if (debug_string && ((request_id_ != 0) || (place_id_ != 0) || (thread_id_ != 0))) { sb->write_bytes("X-requester-ids: "); - sb->ostream() << "rid=" << request_id_ << "; pid=" << place_id_ << "; tid=" << thread_id_; + sb->write_bytes(util::ss("rid=", request_id_, "; pid=", place_id_, "; tid=", thread_id_)); sb->write_bytes("\r\n"); } @@ -899,7 +896,7 @@ void HttpServerResponse::send_internal(StreamBuffer *sb, bool debug_string) cons // Send the status line. send_protocol(http11_, sb); - sb->ostream() << " " << status_ << " " << statusmsg << "\r\n"; + sb->write_bytes(util::ss(" ", status_, " ", statusmsg, "\r\n")); // Send the connection header. if (!errstatus()) { diff --git a/luprex/cpp/core/streambuffer.cpp b/luprex/cpp/core/streambuffer.cpp index decbea93..395fbd5a 100644 --- a/luprex/cpp/core/streambuffer.cpp +++ b/luprex/cpp/core/streambuffer.cpp @@ -335,38 +335,6 @@ util::HashValue StreamBuffer::hash() const { return std::make_pair(hash1, hash2); } -class StreamBufferWriter : public std::streambuf, public eng::opnew { -private: - StreamBuffer *target_; -public: - StreamBufferWriter(StreamBuffer *t) : target_(t) {} - - virtual int_type overflow(int_type c) { - if (c != EOF) { - target_->write_uint8(c); - } - return c; - } -}; - -class StreamBufferOStream : public std::ostream, public eng::opnew { -private: - StreamBufferWriter writer_; -public: - StreamBufferOStream(StreamBuffer *t) : std::ostream(nullptr), writer_(t) { - rdbuf(&writer_); - } - virtual ~StreamBufferOStream() { - } -}; - -std::ostream &StreamBuffer::ostream() { - if (ostream_ == nullptr) { - ostream_.reset(new StreamBufferOStream(this)); - } - return *ostream_; -} - int lua_writer_into_streambuffer(lua_State *L, const void* bytes, size_t sz, void* sbv) { StreamBuffer *sb = (StreamBuffer *)sbv; memcpy(sb->make_space(sz), bytes, sz); @@ -508,11 +476,5 @@ LuaDefine(unittests_streambuffer, "", "some unit tests") { eqsb1.write_int32(34); LuaAssert(L, !eqsb1.contents_equal(&eqsb2)); - // Check the OStream functionality. - StreamBuffer ossb; - ossb.ostream() << "Testing."; - ossb.ostream() << "Foo."; - LuaAssertStrEq(L, ossb.read_entire_contents(), "Testing.Foo."); - return 0; } diff --git a/luprex/cpp/core/streambuffer.hpp b/luprex/cpp/core/streambuffer.hpp index 124b3958..b9fbd376 100644 --- a/luprex/cpp/core/streambuffer.hpp +++ b/luprex/cpp/core/streambuffer.hpp @@ -385,13 +385,13 @@ public: // Calculate a noncryptographic but good hash of what's in the buffer. util::HashValue hash() const; - // Get an ostream that writes into the StreamBuffer. - std::ostream &ostream(); - // Throw a StreamCorruption exception. void raise_truncated() { throw StreamCorruption(); } void raise_string_too_long() { throw StreamCorruption(); } + // This is for unit testing. + bool layout_is(int64_t a, int64_t b, int64_t c); + private: // Start and end of the allocated block. char *buf_lo_; @@ -410,21 +410,14 @@ private: // True if we're not allowed to expand this buffer. bool fixed_size_; - // The ostream. Only allocated on demand. - std::unique_ptr ostream_; - // Initialize with a new buffer. void init(bool fixed, bool owned, char *buf, int64_t size); + // Function that resizes the buffer during make_space operations. void make_space_slow(int64_t bytes); // Implementation for the overwrite_int functions. char *get_overwrite(int64_t size, int64_t write_count_after); - - // This is for unit testing. - bool layout_is(int64_t a, int64_t b, int64_t c); - - friend int lfn_unittests_streambuffer(lua_State *L); }; // Use a streambuffer as a lua_writer.