Initial implementation for #254

This commit is contained in:
Roy Qu 2024-03-09 20:19:38 +08:00
parent 8d1cda13b3
commit 9a66022b8a
2 changed files with 137 additions and 28 deletions

View File

@ -2,46 +2,136 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
QString createDAPRequestMessage(qint64 seq, const QString &command, const QVariantMap &arguments)
DAPMessageError::DAPMessageError(const QString &reason) : BaseError{reason}
{ {
}
static QJsonObject createDAPMessageObj(qint64 seq, const QString& type) {
QJsonObject obj; QJsonObject obj;
obj["seq"]=seq; obj["seq"]=seq;
obj["type"]="request"; obj["type"]=type;
obj["command"]=command; return obj;
if (!arguments.isEmpty()) { }
obj["arguments"]= QJsonObject::fromVariantMap(arguments);
} static QString jsonToDAPMessageString(const QJsonObject &jsonObj)
{
QJsonDocument doc; QJsonDocument doc;
doc.setObject(obj); doc.setObject(jsonObj);
QString contentPart = doc.toJson(QJsonDocument::JsonFormat::Indented); QString contentPart = doc.toJson(QJsonDocument::JsonFormat::Indented);
QString message = QString("Content-Length: %1\r\n").arg(contentPart.length())+contentPart; QString message = QString("Content-Length: %1\r\n").arg(contentPart.length())+contentPart;
return message; return message;
} }
DAPRequest parseDAPRequestMessage(const QByteArray &contentPart) static QJsonObject contentPartToDAPMessageObj(const QByteArray &contentPart) {
{
QJsonParseError error; QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(contentPart, &error); QJsonDocument doc = QJsonDocument::fromJson(contentPart, &error);
if (error.error != QJsonParseError::NoError) { if (error.error != QJsonParseError::NoError) {
throw DAPMessageError(QObject::tr("Failed to parse json content: %1").arg(QString::fromUtf8(contentPart))); throw DAPMessageError(QObject::tr("Failed to parse json content: %1").arg(QString::fromUtf8(contentPart)));
} }
QJsonObject obj = doc.object(); QJsonObject obj = doc.object();
DAPRequest req; return obj;
if (!obj.contains("seq")) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg("seq"));
}
req.seq = obj["seq"].toDouble();
req.type = "request";
if (!obj.contains("command")) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg("command"));
}
req.command = obj["command"].toString();
if (obj.contains("arguments"))
req.arguments = obj["arguments"].toObject().toVariantMap();
return req;
} }
DAPMessageError::DAPMessageError(const QString &reason) : BaseError{reason} static bool parseJsonObjBoolProperty(const QJsonObject& obj, const QString propName) {
if (!obj.contains(propName)) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg(propName));
}
return obj[propName].toBool();
}
static int parseJsonObjIntProperty(const QJsonObject& obj, const QString propName) {
if (!obj.contains(propName)) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg(propName));
}
return obj[propName].toInt();
}
static double parseJsonObjNumberProperty(const QJsonObject& obj, const QString propName) {
if (!obj.contains(propName)) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg(propName));
}
return obj[propName].toDouble();
}
static QString parseJsonObjStringProperty(const QJsonObject& obj, const QString propName) {
if (!obj.contains(propName)) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg(propName));
}
return obj[propName].toString();
}
static QJsonObject parseJsonObjObjectProperty(const QJsonObject& obj, const QString propName) {
if (!obj.contains(propName)) {
throw DAPMessageError(QObject::tr("The request message don't have '%1' field!").arg(propName));
}
return obj[propName].toObject();
}
QString createDAPRequestMessage(qint64 seq, const QString &command, const QJsonObject &arguments)
{ {
QJsonObject obj = createDAPMessageObj(seq, "request");
obj["command"]=command;
if (!arguments.isEmpty()) {
obj["arguments"] = arguments;
}
return jsonToDAPMessageString(obj);
}
QString createDAPResponseMessage(qint64 seq, qint64 request_seq, bool success, const QString &command, const QString &message, const QJsonObject &body)
{
QJsonObject obj = createDAPMessageObj(seq, "response");
obj["request_seq"]=request_seq;
obj["success"]=success;
obj["command"]=command;
if (!message.isEmpty())
obj["message"]=message;
if (!body.isEmpty())
obj["body"]=body;
return jsonToDAPMessageString(obj);
}
QString createDAPEventMessage(qint64 seq, const QString &event, const QJsonObject &body)
{
QJsonObject obj = createDAPMessageObj(seq, "event");
obj["event"] = event;
if (!body.isEmpty())
obj["body"] = body;
return jsonToDAPMessageString(obj);
}
std::shared_ptr<DAPProtocolMessage> parseDAPMessage(const QByteArray &contentPart)
{
QJsonObject obj = contentPartToDAPMessageObj(contentPart);
DAPRequest req;
qint64 seq = parseJsonObjNumberProperty(obj, "seq");
QString type = parseJsonObjStringProperty(obj, "type");
if (type == "request") {
std::shared_ptr<DAPRequest> req = std::make_shared<DAPRequest>();
req->seq = seq;
req->type = "request";
req->command = parseJsonObjStringProperty(obj, "command");
req->arguments = obj["arguments"].toObject();
return req;
} else if (type == "event") {
std::shared_ptr<DAPEvent> event = std::make_shared<DAPEvent>();
event->seq = seq;
event->type = "event";
event->event = parseJsonObjStringProperty(obj, "event");
event->body = obj["body"].toObject();
return event;
} else if (type == "response") {
std::shared_ptr<DAPResponse> response = std::make_shared<DAPResponse>();
response->seq = seq;
response->type = "response";
response->request_seq = parseJsonObjNumberProperty(obj, "request_seq");
response->success = parseJsonObjBoolProperty(obj, "success");
response->command = parseJsonObjStringProperty(obj, "command");
response->message = obj["message"].toString();
response->body = obj["body"].toObject();
return response;
}
return std::shared_ptr<DAPProtocolMessage>();
} }

View File

@ -19,11 +19,12 @@
#include <QString> #include <QString>
#include <QMap> #include <QMap>
#include <QVariant> #include <QVariant>
#include <QJsonObject>
#include <qt_utils/utils.h> #include <qt_utils/utils.h>
class DAPMessageError : public BaseError { class DAPMessageError : public BaseError {
public: public:
explicit FileError(const QString& reason); explicit DAPMessageError(const QString& reason);
}; };
struct DAPProtocolMessage{ struct DAPProtocolMessage{
@ -33,11 +34,29 @@ struct DAPProtocolMessage{
struct DAPRequest: public DAPProtocolMessage { struct DAPRequest: public DAPProtocolMessage {
QString command; QString command;
QVariantMap arguments; QJsonObject arguments;
};
struct DAPEvent: public DAPProtocolMessage {
QString event;
QJsonObject body;
};
struct DAPResponse: public DAPProtocolMessage {
qint64 request_seq;
bool success;
QString command;
QString message;
QJsonObject body;
}; };
QString createDAPRequestMessage( QString createDAPRequestMessage(
qint64 seq, const QString &command, const QVariantMap& arguments); qint64 seq, const QString &command, const QJsonObject& arguments);
QString createDAPResponseMessage(
qint64 seq, qint64 request_seq, bool success,
const QString& command, const QString& message, const QJsonObject& body);
std::shared_ptr<DAPProtocolMessage> parseDAPMessage(const QByteArray& contentPart);
DAPRequest parseDAPRequestMessage(const QByteArray& contentPart);
#endif #endif