Skip to content

Commit

Permalink
Change FrameWriter::addFrame() to move its argument.
Browse files Browse the repository at this point in the history
This can prevent copy frame data since c++23
  • Loading branch information
Fanda Vacek committed Nov 15, 2024
1 parent cd5a61a commit b6e3fc1
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 26 deletions.
2 changes: 1 addition & 1 deletion libshvchainpack/include/shv/chainpack/rpcdriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SHVCHAINPACK_DECL_EXPORT RpcDriver
protected:
virtual bool isOpen() = 0;

virtual void writeFrameData(const std::string &frame_data) = 0;
virtual void writeFrame(RpcFrame &&frame) = 0;

void processRpcFrame(RpcFrame &&frame);
virtual void onRpcFrameReceived(RpcFrame &&frame);
Expand Down
1 change: 1 addition & 0 deletions libshvchainpack/include/shv/chainpack/rpcmessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct SHVCHAINPACK_DECL_EXPORT RpcFrame
RpcFrame(Rpc::ProtocolType protocol, RpcValue::MetaData &&meta, std::string &&data) : protocol(protocol), meta(std::move(meta)), data(std::move(data)) {}
bool isValid() const { return !meta.isEmpty() && !data.empty(); }
RpcMessage toRpcMessage(std::string *errmsg = nullptr) const;
std::string toFrameHead() const;
std::string toFrameData() const;
static RpcFrame fromFrameData(const std::string &frame_data);
};
Expand Down
2 changes: 1 addition & 1 deletion libshvchainpack/include/shv/chainpack/socketrpcdriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class SHVCHAINPACK_DECL_EXPORT SocketRpcDriver : public RpcDriver
void sendNotify(std::string &&method, const RpcValue &result);
protected:
bool isOpen() override;
void writeFrameData(const std::string &frame_data) override;
void writeFrame(RpcFrame &&frame) override;

virtual void onFrameDataRead(const std::string &frame_data);
virtual void idleTaskOnSelectTimeout();
Expand Down
10 changes: 6 additions & 4 deletions libshvchainpack/src/rpcdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ void RpcDriver::sendRpcFrame(RpcFrame &&frame)
if (!errmsg.empty()) {
throw std::runtime_error("Cannot convert RPC frame to message: " + errmsg);
}
frame = msg.toRpcFrame(m_clientProtocolType);
auto frame2 = msg.toRpcFrame(m_clientProtocolType);
writeFrame(std::move(frame2));
}
else {
//logRpcData().nospace() << "FRAME DATA WRITE " << frame_data.size() << " bytes of data:\n" << shv::chainpack::utils::hexDump(frame_data);
writeFrame(std::move(frame));
}
auto frame_data = frame.toFrameData();
//logRpcData().nospace() << "FRAME DATA WRITE " << frame_data.size() << " bytes of data:\n" << shv::chainpack::utils::hexDump(frame_data);
writeFrameData(frame_data);
}
catch (const std::exception &e) {
nError() << "ERROR send frame:" << e.what();
Expand Down
10 changes: 8 additions & 2 deletions libshvchainpack/src/rpcmessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ RpcMessage RpcFrame::toRpcMessage(std::string *errmsg) const
return {};
}

std::string RpcFrame::toFrameData() const
std::string RpcFrame::toFrameHead() const
{
switch (protocol) {
case Rpc::ProtocolType::ChainPack: {
Expand All @@ -118,7 +118,6 @@ std::string RpcFrame::toFrameData() const
}
auto ret = out.str();
ret = static_cast<char>(protocol) + ret;
ret += data;
return ret;
}
default: {
Expand All @@ -127,6 +126,13 @@ std::string RpcFrame::toFrameData() const
}
}

std::string RpcFrame::toFrameData() const
{
auto ret = toFrameHead();
ret += data;
return ret;
}

RpcFrame RpcFrame::fromFrameData(const std::string &frame_data)
{
std::istringstream in(frame_data);
Expand Down
8 changes: 5 additions & 3 deletions libshvchainpack/src/socketrpcdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ void SocketRpcDriver::idleTaskOnSelectTimeout()
{
}

void SocketRpcDriver::writeFrameData(const std::string &frame_data)
void SocketRpcDriver::writeFrame(RpcFrame &&frame)
{
if(!isOpen()) {
nInfo() << "Write to closed socket";
return;
}
if (m_writeBuffer.size() + frame_data.size() < m_maxWriteBufferLength) {
m_writeBuffer += frame_data;
auto frame_head = frame.toFrameHead();
if (m_writeBuffer.size() + frame_head.size() + frame.data.size() < m_maxWriteBufferLength) {
m_writeBuffer += frame_head;
m_writeBuffer += frame.data;
flush();
}
}
Expand Down
3 changes: 2 additions & 1 deletion libshviotqt/include/shv/iotqt/rpc/serialportsocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ class SHVIOTQT_DECL_EXPORT SerialFrameWriter : public FrameWriter
SerialFrameWriter(CrcCheck crc);
~SerialFrameWriter() override = default;

void addFrame(const std::string &frame_data) override;
void resetCommunication() override;
protected:
void addFrameData(std::string &&frame_data) override;
private:
bool m_withCrcCheck = true;
};
Expand Down
10 changes: 6 additions & 4 deletions libshviotqt/include/shv/iotqt/rpc/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ class SHVIOTQT_DECL_EXPORT FrameWriter
{
public:
virtual ~FrameWriter() = default;
virtual void addFrame(const std::string &frame_data) = 0;
void addFrame(shv::chainpack::RpcFrame &&frame);
virtual void resetCommunication() {}
void flushToDevice(QIODevice *device);
void clear();
#ifdef WITH_SHV_WEBSOCKETS
void flushToWebSocket(QWebSocket *socket);
#endif
protected:
virtual void addFrameData(std::string &&frame_data) = 0;
protected:
QList<QByteArray> m_messageDataToWrite;
};
Expand All @@ -70,8 +72,8 @@ class SHVIOTQT_DECL_EXPORT StreamFrameWriter : public FrameWriter
{
public:
~StreamFrameWriter() override = default;

void addFrame(const std::string &frame_data) override;
protected:
void addFrameData(std::string &&frame_data) override;
};

/// wrapper class for QTcpSocket and QWebSocket
Expand Down Expand Up @@ -103,7 +105,7 @@ class SHVIOTQT_DECL_EXPORT Socket : public QObject
virtual quint16 peerPort() const = 0;

std::vector<chainpack::RpcFrame> takeFrames();
void writeFrameData(const std::string &frame_data);
void writeFrame(chainpack::RpcFrame &&frame);

virtual void ignoreSslErrors() = 0;

Expand Down
2 changes: 1 addition & 1 deletion libshviotqt/include/shv/iotqt/rpc/socketrpcconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class SHVIOTQT_DECL_EXPORT SocketRpcConnection : public QObject, public shv::cha
protected:
// RpcDriver interface
bool isOpen() Q_DECL_OVERRIDE;
void writeFrameData(const std::string &frame_data) override;
void writeFrame(shv::chainpack::RpcFrame &&frame) override;

Socket* socket();
void onReadyRead();
Expand Down
4 changes: 2 additions & 2 deletions libshviotqt/src/rpc/serialportsocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ SerialFrameWriter::SerialFrameWriter(CrcCheck crc)
{
}

void SerialFrameWriter::addFrame(const std::string &frame_data)
void SerialFrameWriter::addFrameData(string &&frame_data)
{
QByteArray data_to_write;
auto write_escaped = [&data_to_write](uint8_t b) {
Expand Down Expand Up @@ -213,7 +213,7 @@ void SerialFrameWriter::resetCommunication()

QByteArray data_to_write;
data_to_write.append(static_cast<char>(00));
addFrame(data_to_write.toStdString());
addFrameData(data_to_write.toStdString());
}

//======================================================
Expand Down
17 changes: 14 additions & 3 deletions libshviotqt/src/rpc/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ namespace shv::iotqt::rpc {
//======================================================
// FrameWriter
//======================================================
void FrameWriter::addFrame(chainpack::RpcFrame &&frame)
{
try {
auto frame_data = frame.toFrameHead();
frame_data += frame.data;
addFrameData(std::move(frame_data));
} catch (const std::runtime_error &e) {
shvWarning() << "Error converting frame to data:" << e.what();
}
}

void FrameWriter::flushToDevice(QIODevice *device)
{
while (!m_messageDataToWrite.isEmpty()) {
Expand Down Expand Up @@ -160,7 +171,7 @@ QList<int> StreamFrameReader::addData(std::string_view data)
//======================================================
// StreamFrameWriter
//======================================================
void StreamFrameWriter::addFrame(const std::string &frame_data)
void StreamFrameWriter::addFrameData(std::string &&frame_data)
{
using namespace shv::chainpack;
std::ostringstream out;
Expand Down Expand Up @@ -245,10 +256,10 @@ std::vector<chainpack::RpcFrame> Socket::takeFrames()
return m_frameReader->takeFrames();
}

void Socket::writeFrameData(const std::string &frame_data)
void Socket::writeFrame(shv::chainpack::RpcFrame &&frame)
{
Q_ASSERT(m_frameWriter);
m_frameWriter->addFrame(frame_data);
m_frameWriter->addFrame(std::move(frame));
flushWriteBuffer();
}

Expand Down
4 changes: 2 additions & 2 deletions libshviotqt/src/rpc/socketrpcconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ bool SocketRpcConnection::isOpen()
return isSocketConnected();
}

void SocketRpcConnection::writeFrameData(const std::string &frame_data)
void SocketRpcConnection::writeFrame(chainpack::RpcFrame &&frame)
{
socket()->writeFrameData(frame_data);
socket()->writeFrame(std::move(frame));
}

void SocketRpcConnection::sendRpcMessage(const shv::chainpack::RpcMessage &rpc_msg)
Expand Down
4 changes: 2 additions & 2 deletions libshviotqt/tests/test_frame_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ vector<string> msg_to_raw_data(const vector<string> &cpons)
auto rv = RpcValue::fromCpon(cpon);
auto msg = RpcMessage(rv);
StreamFrameWriter wr;
wr.addFrame(msg.toRpcFrame().toFrameData());
wr.addFrame(msg.toRpcFrame());
QByteArray ba;
{
QBuffer buffer(&ba);
Expand All @@ -54,7 +54,7 @@ vector<string> msg_to_raw_data_serial(const vector<string> &cpons, SerialFrameWr
auto rv = RpcValue::fromCpon(cpon);
auto msg = RpcMessage(rv);
SerialFrameWriter wr(crc_check);
wr.addFrame(msg.toRpcFrame().toFrameData());
wr.addFrame(msg.toRpcFrame());
QByteArray ba;
{
QBuffer buffer(&ba);
Expand Down

0 comments on commit b6e3fc1

Please sign in to comment.