forked from quickshell/quickshell
refactor: move socket and datastream types to Io module
This commit is contained in:
parent
f45d298b66
commit
14e1d2d162
12 changed files with 26 additions and 13 deletions
108
src/io/datastream.cpp
Normal file
108
src/io/datastream.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include "datastream.hpp"
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include <qlocalsocket.h>
|
||||
#include <qobject.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
DataStreamParser* DataStream::reader() const { return this->mReader; }
|
||||
|
||||
void DataStream::setReader(DataStreamParser* reader) {
|
||||
if (reader == this->mReader) return;
|
||||
|
||||
if (this->mReader != nullptr) {
|
||||
QObject::disconnect(this->mReader, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
this->mReader = reader;
|
||||
|
||||
if (reader != nullptr) {
|
||||
QObject::connect(reader, &QObject::destroyed, this, &DataStream::onReaderDestroyed);
|
||||
}
|
||||
|
||||
emit this->readerChanged();
|
||||
|
||||
if (reader != nullptr && !this->buffer.isEmpty()) {
|
||||
reader->parseBytes(this->buffer, this->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void DataStream::onReaderDestroyed() {
|
||||
this->mReader = nullptr;
|
||||
emit this->readerChanged();
|
||||
}
|
||||
|
||||
void DataStream::onBytesAvailable() {
|
||||
auto buf = this->ioDevice()->readAll();
|
||||
this->mReader->parseBytes(buf, this->buffer);
|
||||
}
|
||||
|
||||
void SplitParser::parseBytes(QByteArray& incoming, QByteArray& buffer) {
|
||||
if (this->mSplitMarker.isEmpty()) {
|
||||
if (!buffer.isEmpty()) {
|
||||
emit this->read(QString(buffer));
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
emit this->read(QString(incoming));
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we dont miss any delimiters in the buffer if the delimiter changes
|
||||
if (this->mSplitMarkerChanged) {
|
||||
this->mSplitMarkerChanged = false;
|
||||
this->parseBytes(buffer, buffer);
|
||||
}
|
||||
|
||||
auto marker = this->mSplitMarker.toUtf8();
|
||||
auto mlen = marker.length();
|
||||
|
||||
auto blen = buffer.size();
|
||||
auto ilen = incoming.size();
|
||||
|
||||
qsizetype start = &incoming == &buffer ? 0 : -blen;
|
||||
for (auto readi = -std::min(blen, mlen - 1); readi <= ilen - mlen; readi++) {
|
||||
for (auto marki = 0; marki < mlen; marki++) {
|
||||
qint8 byte; // NOLINT
|
||||
if (readi + marki < 0) byte = buffer[blen + readi + marki];
|
||||
else byte = incoming[readi + marki];
|
||||
|
||||
if (byte != marker[marki]) goto fail;
|
||||
}
|
||||
|
||||
{
|
||||
QByteArray slice;
|
||||
if (start < 0) slice = buffer.sliced(0, std::min(blen, blen + readi));
|
||||
if (readi > 0) {
|
||||
auto sstart = std::max(static_cast<qsizetype>(0), start);
|
||||
slice.append(incoming.sliced(sstart, readi - sstart));
|
||||
}
|
||||
readi += mlen;
|
||||
start = readi;
|
||||
emit this->read(QString(slice));
|
||||
}
|
||||
|
||||
fail:;
|
||||
}
|
||||
|
||||
if (start < 0) {
|
||||
buffer.append(incoming);
|
||||
} else {
|
||||
// Will break the init case if inlined. Must be before clear.
|
||||
auto slice = incoming.sliced(start);
|
||||
buffer.clear();
|
||||
buffer.insert(0, slice);
|
||||
}
|
||||
}
|
||||
|
||||
QString SplitParser::splitMarker() const { return this->mSplitMarker; }
|
||||
|
||||
void SplitParser::setSplitMarker(QString marker) {
|
||||
if (marker == this->mSplitMarker) return;
|
||||
|
||||
this->mSplitMarker = std::move(marker);
|
||||
this->mSplitMarkerChanged = true;
|
||||
emit this->splitMarkerChanged();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue