From cfeeb2eaf32d744601784dd2a89f028e681ec3d5 Mon Sep 17 00:00:00 2001 From: jyelon Date: Fri, 4 Mar 2022 16:45:47 -0500 Subject: [PATCH] Small overhaul using string_view --- luprex/core/cpp/drivenengine.cpp | 26 +++++++++++++------------- luprex/core/cpp/drivenengine.hpp | 8 ++++---- luprex/core/cpp/driver-common.cpp | 28 +++++++++++++--------------- luprex/core/cpp/driver-util.hpp | 14 ++++++++++++++ luprex/core/cpp/streambuffer.cpp | 16 +++++++++++----- luprex/core/cpp/streambuffer.hpp | 7 +++++-- 6 files changed, 60 insertions(+), 39 deletions(-) diff --git a/luprex/core/cpp/drivenengine.cpp b/luprex/core/cpp/drivenengine.cpp index f78389fb..1fdde0e4 100644 --- a/luprex/core/cpp/drivenengine.cpp +++ b/luprex/core/cpp/drivenengine.cpp @@ -86,7 +86,9 @@ void Channel::set_prompt(const eng::string &p) { desired_prompt_ = p; } -void Channel::feed_readline(int nbytes, const char *bytes) { +void Channel::feed_readline(std::string_view data) { + int nbytes = data.size(); + const char *bytes = data.data(); for (int i = 0; i < nbytes; i++) { char c = bytes[i]; if ((c == '\n') && (readline_lastc_ == '\r')) { @@ -115,9 +117,8 @@ void Channel::feed_readline(int nbytes, const char *bytes) { } } -void Channel::peek_outgoing(int *nbytes, const char **bytes) const { - *nbytes = sb_drvout_->fill(); - *bytes = sb_drvout_->data(); +std::string_view Channel::peek_outgoing() const { + return sb_drvout_->view(); } void Channel::pump_readline() { @@ -215,30 +216,29 @@ const eng::string &DrivenEngine::drv_get_target(int chid) const { } bool DrivenEngine::drv_outgoing_empty(int chid) const { - int nbytes; const char *bytes; - drv_peek_outgoing(chid, &nbytes, &bytes); - return (nbytes == 0); + std::string_view view = drv_peek_outgoing(chid); + return (view.size() == 0); } bool DrivenEngine::drv_get_channel_released(int chid) const { return channels_[chid].use_count() == 1; } -void DrivenEngine::drv_peek_outgoing(int chid, int *nbytes, const char **bytes) const { - return get_chid(chid)->peek_outgoing(nbytes, bytes); +std::string_view DrivenEngine::drv_peek_outgoing(int chid) const { + return get_chid(chid)->peek_outgoing(); } void DrivenEngine::drv_sent_outgoing(int chid, int nbytes) { return get_chid(chid)->sent_outgoing(nbytes); } -void DrivenEngine::drv_recv_incoming(int chid, int nbytes, const char *bytes) { - if (nbytes > 0) { +void DrivenEngine::drv_recv_incoming(int chid, std::string_view data) { + if (data.size() > 0) { Channel *ch = get_chid(chid); if (ch->sb_drvout_ != ch->sb_out_) { - ch->feed_readline(nbytes, bytes); + ch->feed_readline(data); } else { - ch->sb_in_->write_bytes(bytes, nbytes); + ch->sb_in_->write_bytes(data); } } } diff --git a/luprex/core/cpp/drivenengine.hpp b/luprex/core/cpp/drivenengine.hpp index 4cb4d014..9fd72361 100644 --- a/luprex/core/cpp/drivenengine.hpp +++ b/luprex/core/cpp/drivenengine.hpp @@ -152,8 +152,8 @@ private: // DrivenEngine::new_outgoing_channel to create outgoing socket channels. // - void feed_readline(int nbytes, const char *bytes); - void peek_outgoing(int *nbytes, const char **bytes) const; + void feed_readline(std::string_view data); + std::string_view peek_outgoing() const; void sent_outgoing(int nbytes); void erase_command(); void echo_command(); @@ -334,7 +334,7 @@ public: // here is naturally only valid until the buffer is changed. This function // is used for all channels, including sockets and stdio. // - void drv_peek_outgoing(int chid, int *nbytes, const char **bytes) const; + std::string_view drv_peek_outgoing(int chid) const; // Notifies the channel that some bytes were transmitted. This causes those // bytes to be removed from the outgoing buffer. This function is used for @@ -346,7 +346,7 @@ public: // bytes to be appended to the incoming buffer. This function is used for // all channels, including sockets and stdio. // - void drv_recv_incoming(int chid, int nbytes, const char *bytes); + void drv_recv_incoming(int chid, std::string_view data); // Notify the channel that the connection was closed. This includes all // sorts of closes, including friendly termination, all the way to network diff --git a/luprex/core/cpp/driver-common.cpp b/luprex/core/cpp/driver-common.cpp index e63b7929..c1160926 100644 --- a/luprex/core/cpp/driver-common.cpp +++ b/luprex/core/cpp/driver-common.cpp @@ -199,10 +199,9 @@ public: void handle_console_output() { while (true) { - int nbytes; const char *bytes; - driven_->drv_peek_outgoing(0, &nbytes, &bytes); - if (nbytes == 0) break; - int nwrote = console_write(bytes, nbytes); + std::string_view s = driven_->drv_peek_outgoing(0); + if (s.size() == 0) break; + int nwrote = console_write(s.data(), s.size()); if (nwrote <= 0) break; driven_->drv_sent_outgoing(0, nwrote); } @@ -215,7 +214,7 @@ public: int nread = console_read(buffer, 256); if (nread <= 0) break; read_console_recently_ = true; - driven_->drv_recv_incoming(0, nread, buffer); + driven_->drv_recv_incoming(0, std::string_view(buffer, nread)); } } @@ -279,13 +278,11 @@ public: } // Try to write plaintext to the channel. - int nbytes; const char *bytes; - driven_->drv_peek_outgoing(chan.chid, &nbytes, &bytes); - if (nbytes > 0) { - int sbytes = nbytes; + std::string_view s = driven_->drv_peek_outgoing(chan.chid); + if (s.size() > 0) { + int sbytes = s.size(); if (sbytes > 65536) sbytes = 65536; - int wbytes = socket_send(chan.socket, bytes, sbytes, err); - // std::cerr << "send.bytes="<< wbytes << ".errno=" << errno << " "; + int wbytes = socket_send(chan.socket, s.data(), sbytes, err); if (wbytes < 0) { close_channel(chan, err); } else { @@ -296,11 +293,10 @@ public: // Try to read plaintext from the channel. // Someday, find a way to avoid this copy. int nrecv = socket_recv(chan.socket, chbuf.get(), 65536, err); - // std::cerr << "recv.bytes="<< nrecv << ".errno=" << errno << " "; if (nrecv < 0) { close_channel(chan, err); } else { - driven_->drv_recv_incoming(chan.chid, nrecv, chbuf.get()); + driven_->drv_recv_incoming(chan.chid, std::string_view(chbuf.get(), nrecv)); } // Update the ready-flags for next time. @@ -350,7 +346,7 @@ public: // Try to read data. int read_result = SSL_read(chan.ssl, chbuf.get(), 65536); if (read_result > 0) { - driven_->drv_recv_incoming(chan.chid, read_result, chbuf.get()); + driven_->drv_recv_incoming(chan.chid, std::string_view(chbuf.get(), read_result)); chan.ready_now = true; } else { process_ssl_error(chan, read_result); @@ -411,7 +407,9 @@ public: // Peek output buffers and determine channel release flags. for (ChanInfo &chan : chans_) { - driven_->drv_peek_outgoing(chan.chid, &chan.nbytes, &chan.bytes); + std::string_view s = driven_->drv_peek_outgoing(chan.chid); + chan.nbytes = s.size(); + chan.bytes = s.data(); chan.just_released = false; if ((chan.nbytes == 0)&&(!chan.released)) { chan.released = driven_->drv_get_channel_released(chan.chid); diff --git a/luprex/core/cpp/driver-util.hpp b/luprex/core/cpp/driver-util.hpp index 9ff7ec81..458d8276 100644 --- a/luprex/core/cpp/driver-util.hpp +++ b/luprex/core/cpp/driver-util.hpp @@ -5,6 +5,8 @@ #include "wrap-string.hpp" #include "wrap-vector.hpp" +#include +#include #include namespace drv { @@ -13,6 +15,18 @@ void split_host_port(std::string_view target, std::string &host, std::string &po std::vector parse_control_lst(std::string_view ctrl); + + +// Write encoded data to a replay log. +void wlog_byte(std::ostream &s, uint8_t byte); +void wlog_uint16(std::ostream &s, uint16_t v); +void wlog_string(std::ostream &s, std::string_view v); + +// Read encoded data from a file. +uint8_t rlog_byte(std::istream &s); +uint16_t rlog_uint16(std::istream &s); +std::string_view rlog_string(std::istream &s, char *buf, size_t buflen); + } #endif // DRIVER_UTIL_HPP diff --git a/luprex/core/cpp/streambuffer.cpp b/luprex/core/cpp/streambuffer.cpp index 2019c2d5..e7835fd4 100644 --- a/luprex/core/cpp/streambuffer.cpp +++ b/luprex/core/cpp/streambuffer.cpp @@ -59,6 +59,10 @@ const char *StreamBuffer::data() const { return read_cursor_; } +std::string_view StreamBuffer::view() const { + return std::string_view(read_cursor_, write_cursor_ - read_cursor_); +} + bool StreamBuffer::layout_is(int64_t a, int64_t b, int64_t c) { if (read_cursor_ - buf_lo_ != a) return false; if (write_cursor_ - read_cursor_ != b) return false; @@ -182,8 +186,10 @@ void StreamBuffer::write_bytes(const char *s, int64_t len) { write_cursor_ += len; } -void StreamBuffer::write_bytes(const eng::string &s) { - write_bytes(s.c_str(), s.size()); +void StreamBuffer::write_bytes(std::string_view s) { + make_space(s.size()); + memcpy(write_cursor_, s.data(), s.size()); + write_cursor_ += s.size(); } const char *StreamBuffer::read_bytes(int64_t bytes) { @@ -322,14 +328,14 @@ void StreamBuffer::write_hashvalue(const util::HashValue &hv) { write_uint64(hv.second); } -void StreamBuffer::write_string(const eng::string &s) { +void StreamBuffer::write_string(std::string_view s) { if (s.size() >= 255) { write_uint8(0xFF); write_uint64(s.size()); - write_bytes(s.c_str(), s.size()); + write_bytes(s); } else { write_uint8(s.size()); - write_bytes(s.c_str(), s.size()); + write_bytes(s); } } diff --git a/luprex/core/cpp/streambuffer.hpp b/luprex/core/cpp/streambuffer.hpp index 378946ee..bc32a42d 100644 --- a/luprex/core/cpp/streambuffer.hpp +++ b/luprex/core/cpp/streambuffer.hpp @@ -269,6 +269,9 @@ public: // Get a pointer to the data. const char *data() const; + // Get entire contents as a string_view + std::string_view view() const; + // Discard all data. Reset total read and write counts. // Frees up as much space as possible. void clear(); @@ -284,7 +287,7 @@ public: // It just writes the bytes. // void write_bytes(const char *bytes, int64_t len); - void write_bytes(const eng::string &bytes); + void write_bytes(std::string_view bytes); // Read a block of bytes from the buffer. // @@ -333,7 +336,7 @@ public: // void write_bool(bool b) { write_int8(b ? 1 : 0); } void write_hashvalue(const util::HashValue &hv); - void write_string(const eng::string &s); + void write_string(std::string_view s); // Read other types from the buffer. //