Small overhaul using string_view

This commit is contained in:
2022-03-04 16:45:47 -05:00
parent b17b34924e
commit cfeeb2eaf3
6 changed files with 60 additions and 39 deletions

View File

@@ -86,7 +86,9 @@ void Channel::set_prompt(const eng::string &p) {
desired_prompt_ = 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++) { for (int i = 0; i < nbytes; i++) {
char c = bytes[i]; char c = bytes[i];
if ((c == '\n') && (readline_lastc_ == '\r')) { 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 { std::string_view Channel::peek_outgoing() const {
*nbytes = sb_drvout_->fill(); return sb_drvout_->view();
*bytes = sb_drvout_->data();
} }
void Channel::pump_readline() { 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 { bool DrivenEngine::drv_outgoing_empty(int chid) const {
int nbytes; const char *bytes; std::string_view view = drv_peek_outgoing(chid);
drv_peek_outgoing(chid, &nbytes, &bytes); return (view.size() == 0);
return (nbytes == 0);
} }
bool DrivenEngine::drv_get_channel_released(int chid) const { bool DrivenEngine::drv_get_channel_released(int chid) const {
return channels_[chid].use_count() == 1; return channels_[chid].use_count() == 1;
} }
void DrivenEngine::drv_peek_outgoing(int chid, int *nbytes, const char **bytes) const { std::string_view DrivenEngine::drv_peek_outgoing(int chid) const {
return get_chid(chid)->peek_outgoing(nbytes, bytes); return get_chid(chid)->peek_outgoing();
} }
void DrivenEngine::drv_sent_outgoing(int chid, int nbytes) { void DrivenEngine::drv_sent_outgoing(int chid, int nbytes) {
return get_chid(chid)->sent_outgoing(nbytes); return get_chid(chid)->sent_outgoing(nbytes);
} }
void DrivenEngine::drv_recv_incoming(int chid, int nbytes, const char *bytes) { void DrivenEngine::drv_recv_incoming(int chid, std::string_view data) {
if (nbytes > 0) { if (data.size() > 0) {
Channel *ch = get_chid(chid); Channel *ch = get_chid(chid);
if (ch->sb_drvout_ != ch->sb_out_) { if (ch->sb_drvout_ != ch->sb_out_) {
ch->feed_readline(nbytes, bytes); ch->feed_readline(data);
} else { } else {
ch->sb_in_->write_bytes(bytes, nbytes); ch->sb_in_->write_bytes(data);
} }
} }
} }

View File

@@ -152,8 +152,8 @@ private:
// DrivenEngine::new_outgoing_channel to create outgoing socket channels. // DrivenEngine::new_outgoing_channel to create outgoing socket channels.
// //
void feed_readline(int nbytes, const char *bytes); void feed_readline(std::string_view data);
void peek_outgoing(int *nbytes, const char **bytes) const; std::string_view peek_outgoing() const;
void sent_outgoing(int nbytes); void sent_outgoing(int nbytes);
void erase_command(); void erase_command();
void echo_command(); void echo_command();
@@ -334,7 +334,7 @@ public:
// here is naturally only valid until the buffer is changed. This function // here is naturally only valid until the buffer is changed. This function
// is used for all channels, including sockets and stdio. // 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 // Notifies the channel that some bytes were transmitted. This causes those
// bytes to be removed from the outgoing buffer. This function is used for // 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 // bytes to be appended to the incoming buffer. This function is used for
// all channels, including sockets and stdio. // 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 // Notify the channel that the connection was closed. This includes all
// sorts of closes, including friendly termination, all the way to network // sorts of closes, including friendly termination, all the way to network

View File

@@ -199,10 +199,9 @@ public:
void handle_console_output() { void handle_console_output() {
while (true) { while (true) {
int nbytes; const char *bytes; std::string_view s = driven_->drv_peek_outgoing(0);
driven_->drv_peek_outgoing(0, &nbytes, &bytes); if (s.size() == 0) break;
if (nbytes == 0) break; int nwrote = console_write(s.data(), s.size());
int nwrote = console_write(bytes, nbytes);
if (nwrote <= 0) break; if (nwrote <= 0) break;
driven_->drv_sent_outgoing(0, nwrote); driven_->drv_sent_outgoing(0, nwrote);
} }
@@ -215,7 +214,7 @@ public:
int nread = console_read(buffer, 256); int nread = console_read(buffer, 256);
if (nread <= 0) break; if (nread <= 0) break;
read_console_recently_ = true; 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. // Try to write plaintext to the channel.
int nbytes; const char *bytes; std::string_view s = driven_->drv_peek_outgoing(chan.chid);
driven_->drv_peek_outgoing(chan.chid, &nbytes, &bytes); if (s.size() > 0) {
if (nbytes > 0) { int sbytes = s.size();
int sbytes = nbytes;
if (sbytes > 65536) sbytes = 65536; if (sbytes > 65536) sbytes = 65536;
int wbytes = socket_send(chan.socket, bytes, sbytes, err); int wbytes = socket_send(chan.socket, s.data(), sbytes, err);
// std::cerr << "send.bytes="<< wbytes << ".errno=" << errno << " ";
if (wbytes < 0) { if (wbytes < 0) {
close_channel(chan, err); close_channel(chan, err);
} else { } else {
@@ -296,11 +293,10 @@ public:
// Try to read plaintext from the channel. // Try to read plaintext from the channel.
// Someday, find a way to avoid this copy. // Someday, find a way to avoid this copy.
int nrecv = socket_recv(chan.socket, chbuf.get(), 65536, err); int nrecv = socket_recv(chan.socket, chbuf.get(), 65536, err);
// std::cerr << "recv.bytes="<< nrecv << ".errno=" << errno << " ";
if (nrecv < 0) { if (nrecv < 0) {
close_channel(chan, err); close_channel(chan, err);
} else { } 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. // Update the ready-flags for next time.
@@ -350,7 +346,7 @@ public:
// Try to read data. // Try to read data.
int read_result = SSL_read(chan.ssl, chbuf.get(), 65536); int read_result = SSL_read(chan.ssl, chbuf.get(), 65536);
if (read_result > 0) { 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; chan.ready_now = true;
} else { } else {
process_ssl_error(chan, read_result); process_ssl_error(chan, read_result);
@@ -411,7 +407,9 @@ public:
// Peek output buffers and determine channel release flags. // Peek output buffers and determine channel release flags.
for (ChanInfo &chan : chans_) { 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; chan.just_released = false;
if ((chan.nbytes == 0)&&(!chan.released)) { if ((chan.nbytes == 0)&&(!chan.released)) {
chan.released = driven_->drv_get_channel_released(chan.chid); chan.released = driven_->drv_get_channel_released(chan.chid);

View File

@@ -5,6 +5,8 @@
#include "wrap-string.hpp" #include "wrap-string.hpp"
#include "wrap-vector.hpp" #include "wrap-vector.hpp"
#include <istream>
#include <ostream>
#include <string_view> #include <string_view>
namespace drv { namespace drv {
@@ -13,6 +15,18 @@ void split_host_port(std::string_view target, std::string &host, std::string &po
std::vector<std::string> parse_control_lst(std::string_view ctrl); std::vector<std::string> 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 #endif // DRIVER_UTIL_HPP

View File

@@ -59,6 +59,10 @@ const char *StreamBuffer::data() const {
return read_cursor_; 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) { bool StreamBuffer::layout_is(int64_t a, int64_t b, int64_t c) {
if (read_cursor_ - buf_lo_ != a) return false; if (read_cursor_ - buf_lo_ != a) return false;
if (write_cursor_ - read_cursor_ != b) 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; write_cursor_ += len;
} }
void StreamBuffer::write_bytes(const eng::string &s) { void StreamBuffer::write_bytes(std::string_view s) {
write_bytes(s.c_str(), s.size()); make_space(s.size());
memcpy(write_cursor_, s.data(), s.size());
write_cursor_ += s.size();
} }
const char *StreamBuffer::read_bytes(int64_t bytes) { const char *StreamBuffer::read_bytes(int64_t bytes) {
@@ -322,14 +328,14 @@ void StreamBuffer::write_hashvalue(const util::HashValue &hv) {
write_uint64(hv.second); write_uint64(hv.second);
} }
void StreamBuffer::write_string(const eng::string &s) { void StreamBuffer::write_string(std::string_view s) {
if (s.size() >= 255) { if (s.size() >= 255) {
write_uint8(0xFF); write_uint8(0xFF);
write_uint64(s.size()); write_uint64(s.size());
write_bytes(s.c_str(), s.size()); write_bytes(s);
} else { } else {
write_uint8(s.size()); write_uint8(s.size());
write_bytes(s.c_str(), s.size()); write_bytes(s);
} }
} }

View File

@@ -269,6 +269,9 @@ public:
// Get a pointer to the data. // Get a pointer to the data.
const char *data() const; 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. // Discard all data. Reset total read and write counts.
// Frees up as much space as possible. // Frees up as much space as possible.
void clear(); void clear();
@@ -284,7 +287,7 @@ public:
// It just writes the bytes. // It just writes the bytes.
// //
void write_bytes(const char *bytes, int64_t len); 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. // 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_bool(bool b) { write_int8(b ? 1 : 0); }
void write_hashvalue(const util::HashValue &hv); 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. // Read other types from the buffer.
// //