summaryrefslogtreecommitdiff
path: root/graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp')
-rw-r--r--graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp382
1 files changed, 204 insertions, 178 deletions
diff --git a/graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp b/graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp
index 695c35fe1d..731a5541d6 100644
--- a/graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp
+++ b/graphics/asymptote/LspCpp/src/jsonrpc/StreamMessageProducer.cpp
@@ -5,193 +5,207 @@
#include "LibLsp/JsonRpc/stream.h"
#include "LibLsp/lsp/Markup/string_ref.h"
-
bool StartsWith(std::string value, std::string start);
-bool StartsWith(std::string value, std::string start) {
- if (start.size() > value.size())
- return false;
- return std::equal(start.begin(), start.end(), value.begin());
+bool StartsWith(std::string value, std::string start)
+{
+ if (start.size() > value.size())
+ {
+ return false;
+ }
+ return std::equal(start.begin(), start.end(), value.begin());
}
-using namespace std;
+using namespace std;
namespace
{
- string JSONRPC_VERSION = "2.0";
- string CONTENT_LENGTH_HEADER = "Content-Length";
- string CONTENT_TYPE_HEADER = "Content-Type";
- string JSON_MIME_TYPE = "application/json";
- string CRLF = "\r\n";
-
-}
+string JSONRPC_VERSION = "2.0";
+string CONTENT_LENGTH_HEADER = "Content-Length";
+string CONTENT_TYPE_HEADER = "Content-Type";
+string JSON_MIME_TYPE = "application/json";
+string CRLF = "\r\n";
- void LSPStreamMessageProducer::parseHeader(std::string& line, LSPStreamMessageProducer::Headers& headers)
- {
- int sepIndex = line.find(':');
- if (sepIndex >= 0) {
- auto key = line.substr(0, sepIndex);
- if(key == CONTENT_LENGTH_HEADER)
- {
- headers.contentLength = atoi(line.substr(sepIndex + 1).data());
- }
- else if(key == CONTENT_TYPE_HEADER)
- {
- int charsetIndex = line.find("charset=");
- if (charsetIndex >= 0)
- headers.charset = line.substr(charsetIndex + 8);
- }
- }
- }
+} // namespace
+void LSPStreamMessageProducer::parseHeader(std::string& line, LSPStreamMessageProducer::Headers& headers)
+{
+ int sepIndex = line.find(':');
+ if (sepIndex >= 0)
+ {
+ auto key = line.substr(0, sepIndex);
+ if (key == CONTENT_LENGTH_HEADER)
+ {
+ headers.contentLength = atoi(line.substr(sepIndex + 1).data());
+ }
+ else if (key == CONTENT_TYPE_HEADER)
+ {
+ int charsetIndex = line.find("charset=");
+ if (charsetIndex >= 0)
+ {
+ headers.charset = line.substr(charsetIndex + 8);
+ }
+ }
+ }
+}
void LSPStreamMessageProducer::listen(MessageConsumer callBack)
{
- if(!input)
- return;
+ if (!input)
+ {
+ return;
+ }
- keepRunning = true;
- bool newLine = false;
- Headers headers;
- string headerBuilder ;
- string debugBuilder ;
- // Read the content length. It is terminated by the "\r\n" sequence.
- while (keepRunning)
+ keepRunning = true;
+ bool newLine = false;
+ Headers headers;
+ string headerBuilder;
+ string debugBuilder;
+ // Read the content length. It is terminated by the "\r\n" sequence.
+ while (keepRunning)
+ {
+ if (input->bad())
{
- if(input->bad())
- {
- std::string info = "Input stream is bad.";
- auto what = input->what();
- if (what.size())
- {
- info += "Reason:";
- info += input->what();
- }
- MessageIssue issue(info, lsp::Log::Level::SEVERE);
- issueHandler.handle(std::move(issue));
- return;
- }
- if(input->fail())
+ std::string info = "Input stream is bad.";
+ auto what = input->what();
+ if (what.size())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::SEVERE);
+ issueHandler.handle(std::move(issue));
+ return;
+ }
+ if (input->fail())
+ {
+ std::string info = "Input fail.";
+ auto what = input->what();
+ if (what.size())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::WARNING);
+ issueHandler.handle(std::move(issue));
+ if (input->need_to_clear_the_state())
+ {
+ input->clear();
+ }
+ else
+ {
+ return;
+ }
+ }
+ int c = input->get();
+ if (c == EOF)
+ {
+ // End of input stream has been reached
+ keepRunning = false;
+ }
+ else
+ {
+
+ debugBuilder.push_back((char)c);
+ if (c == '\n')
+ {
+ if (newLine)
{
- std::string info = "Input fail.";
- auto what = input->what();
- if(what.size())
- {
- info += "Reason:";
- info += input->what();
- }
+ // Two consecutive newlines have been read, which signals the start of the message content
+ if (headers.contentLength <= 0)
+ {
+ string info = "Unexpected token:" + debugBuilder;
+ info = +" (expected Content-Length: sequence);";
MessageIssue issue(info, lsp::Log::Level::WARNING);
issueHandler.handle(std::move(issue));
- if(input->need_to_clear_the_state())
- input->clear();
- else
- {
- return;
- }
- }
- int c = input->get();
- if (c == EOF) {
- // End of input stream has been reached
- keepRunning = false;
- }
- else
- {
-
- debugBuilder.push_back((char)c);
- if (c == '\n')
+ }
+ else
{
- if (newLine) {
- // Two consecutive newlines have been read, which signals the start of the message content
- if (headers.contentLength <= 0)
- {
- string info = "Unexpected token:" + debugBuilder;
- info = +" (expected Content-Length: sequence);";
- MessageIssue issue(info, lsp::Log::Level::WARNING);
- issueHandler.handle(std::move(issue));
- }
- else {
- bool result = handleMessage(headers,callBack);
- if (!result)
- keepRunning = false;
- newLine = false;
- }
- headers.clear();
- debugBuilder.clear();
- }
- else if (!headerBuilder.empty()) {
- // A single newline ends a header line
- parseHeader(headerBuilder, headers);
- headerBuilder.clear();
+ bool result = handleMessage(headers, callBack);
+ if (!result)
+ {
+ keepRunning = false;
}
- newLine = true;
- }
- else if (c != '\r') {
- // Add the input to the current header line
-
- headerBuilder.push_back((char)c);
newLine = false;
}
+ headers.clear();
+ debugBuilder.clear();
}
- }
+ else if (!headerBuilder.empty())
+ {
+ // A single newline ends a header line
+ parseHeader(headerBuilder, headers);
+ headerBuilder.clear();
+ }
+ newLine = true;
+ }
+ else if (c != '\r')
+ {
+ // Add the input to the current header line
+ headerBuilder.push_back((char)c);
+ newLine = false;
+ }
+ }
+ }
}
-void LSPStreamMessageProducer::bind(std::shared_ptr<lsp::istream>_in)
+void LSPStreamMessageProducer::bind(std::shared_ptr<lsp::istream> _in)
{
- input = _in;
+ input = _in;
}
-bool LSPStreamMessageProducer::handleMessage(Headers& headers ,MessageConsumer callBack)
+bool LSPStreamMessageProducer::handleMessage(Headers& headers, MessageConsumer callBack)
{
- // Read content.
- auto content_length = headers.contentLength;
- std::string content(content_length,0);
- auto data = &content[0];
- input->read(data, content_length);
- if (input->bad())
- {
- std::string info = "Input stream is bad.";
- auto what = input->what();
- if (!what.empty())
- {
- info += "Reason:";
- info += input->what();
- }
- MessageIssue issue(info, lsp::Log::Level::SEVERE);
- issueHandler.handle(std::move(issue));
- return false;
- }
+ // Read content.
+ auto content_length = headers.contentLength;
+ std::string content(content_length, 0);
+ auto data = &content[0];
+ input->read(data, content_length);
+ if (input->bad())
+ {
+ std::string info = "Input stream is bad.";
+ auto what = input->what();
+ if (!what.empty())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::SEVERE);
+ issueHandler.handle(std::move(issue));
+ return false;
+ }
- if (input->eof())
- {
- MessageIssue issue("No more input when reading content body", lsp::Log::Level::INFO);
- issueHandler.handle(std::move(issue));
- return false;
- }
- if (input->fail())
- {
- std::string info = "Input fail.";
- auto what = input->what();
- if (!what.empty())
- {
- info += "Reason:";
- info += input->what();
- }
- MessageIssue issue(info, lsp::Log::Level::WARNING);
- issueHandler.handle(std::move(issue));
- if (input->need_to_clear_the_state())
- input->clear();
- else
- {
- return false;
- }
- }
+ if (input->eof())
+ {
+ MessageIssue issue("No more input when reading content body", lsp::Log::Level::INFO);
+ issueHandler.handle(std::move(issue));
+ return false;
+ }
+ if (input->fail())
+ {
+ std::string info = "Input fail.";
+ auto what = input->what();
+ if (!what.empty())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::WARNING);
+ issueHandler.handle(std::move(issue));
+ if (input->need_to_clear_the_state())
+ {
+ input->clear();
+ }
+ else
+ {
+ return false;
+ }
+ }
- callBack(std::move(content));
+ callBack(std::move(content));
- return true;
+ return true;
}
-
-
/// For lit tests we support a simplified syntax:
/// - messages are delimited by '// -----' on a line by itself
/// - lines starting with // are ignored.
@@ -199,15 +213,18 @@ bool LSPStreamMessageProducer::handleMessage(Headers& headers ,MessageConsumer c
void DelimitedStreamMessageProducer::listen(MessageConsumer callBack)
{
- if(!input)
+ if (!input)
+ {
return;
+ }
keepRunning = true;
- auto readLine = [&]( std::string_ref& lineBuilder) -> bool {
+ auto readLine = [&](std::string_ref& lineBuilder) -> bool
+ {
while (keepRunning)
{
- if(input->bad())
+ if (input->bad())
{
std::string info = "Input stream is bad.";
auto what = input->what();
@@ -220,26 +237,29 @@ void DelimitedStreamMessageProducer::listen(MessageConsumer callBack)
issueHandler.handle(std::move(issue));
return false;
}
- if(input->fail())
+ if (input->fail())
{
std::string info = "Input fail.";
auto what = input->what();
- if(what.size())
+ if (what.size())
{
info += "Reason:";
info += input->what();
}
MessageIssue issue(info, lsp::Log::Level::WARNING);
issueHandler.handle(std::move(issue));
- if(input->need_to_clear_the_state())
+ if (input->need_to_clear_the_state())
+ {
input->clear();
+ }
else
{
return false;
}
}
int c = input->get();
- if (c == EOF) {
+ if (c == EOF)
+ {
// End of input stream has been reached
keepRunning = false;
}
@@ -247,12 +267,14 @@ void DelimitedStreamMessageProducer::listen(MessageConsumer callBack)
{
if (c == '\n')
{
- if(!lineBuilder.empty()){
- lineBuilder.push_back(c);
+ if (!lineBuilder.empty())
+ {
+ lineBuilder.push_back(static_cast<char>(c));
return true;
}
}
- else if (c != '\r') {
+ else if (c != '\r')
+ {
// Add the input to the current header line
lineBuilder.push_back((char)c);
@@ -262,15 +284,18 @@ void DelimitedStreamMessageProducer::listen(MessageConsumer callBack)
return false;
};
- auto getMessage = [&](std::string& json) -> bool {
- std::string_ref lineBuilder ;
- while (readLine(lineBuilder)){
+ auto getMessage = [&](std::string& json) -> bool
+ {
+ std::string_ref lineBuilder;
+ while (readLine(lineBuilder))
+ {
lineBuilder.trim();
- if(lineBuilder.start_with("//")){
+ if (lineBuilder.start_with("//"))
+ {
// Found a delimiter for the message.
if (lineBuilder == "// -----")
{
- return true;
+ return true;
}
}
json += lineBuilder;
@@ -278,20 +303,21 @@ void DelimitedStreamMessageProducer::listen(MessageConsumer callBack)
return false;
};
-
- while (true) {
+ while (true)
+ {
std::string json;
- if (getMessage(json)) {
+ if (getMessage(json))
+ {
callBack(std::move(json));
- }else{
- return ;
+ }
+ else
+ {
+ return;
}
}
}
-void DelimitedStreamMessageProducer::bind(std::shared_ptr<lsp::istream>_in)
+void DelimitedStreamMessageProducer::bind(std::shared_ptr<lsp::istream> _in)
{
input = _in;
}
-
-