RedPanda-CPP/RedPandaIDE/debugger/dapprotocol.cpp

138 lines
4.8 KiB
C++
Raw Normal View History

#include "dapprotocol.h"
#include <QJsonDocument>
#include <QJsonObject>
2024-03-09 20:19:38 +08:00
DAPMessageError::DAPMessageError(const QString &reason) : BaseError{reason}
{
2024-03-09 20:19:38 +08:00
}
static QJsonObject createDAPMessageObj(qint64 seq, const QString& type) {
QJsonObject obj;
obj["seq"]=seq;
2024-03-09 20:19:38 +08:00
obj["type"]=type;
return obj;
}
static QString jsonToDAPMessageString(const QJsonObject &jsonObj)
{
QJsonDocument doc;
2024-03-09 20:19:38 +08:00
doc.setObject(jsonObj);
QString contentPart = doc.toJson(QJsonDocument::JsonFormat::Indented);
QString message = QString("Content-Length: %1\r\n").arg(contentPart.length())+contentPart;
return message;
}
2024-03-09 20:19:38 +08:00
static QJsonObject contentPartToDAPMessageObj(const QByteArray &contentPart) {
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(contentPart, &error);
if (error.error != QJsonParseError::NoError) {
throw DAPMessageError(QObject::tr("Failed to parse json content: %1").arg(QString::fromUtf8(contentPart)));
}
QJsonObject obj = doc.object();
2024-03-09 20:19:38 +08:00
return obj;
}
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));
}
2024-03-09 20:19:38 +08:00
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));
}
2024-03-09 20:19:38 +08:00
return obj[propName].toDouble();
}
2024-03-09 20:19:38 +08:00
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)
{
2024-03-09 20:19:38 +08:00
QJsonObject obj = createDAPMessageObj(seq, "request");
obj["command"]=command;
if (!arguments.isEmpty()) {
obj["arguments"] = arguments;
}
return jsonToDAPMessageString(obj);
}
2024-03-09 20:19:38 +08:00
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>();
}