dont copy strings into textnodes

This commit is contained in:
pantor
2020-07-26 13:13:05 +02:00
parent 59b446b215
commit 7529f21e63
4 changed files with 15 additions and 9 deletions

View File

@@ -74,9 +74,9 @@ public:
class TextNode : public AstNode {
public:
std::string content;
size_t length;
explicit TextNode(nonstd::string_view content, size_t pos): AstNode(pos), content(content) { }
explicit TextNode(size_t pos, size_t length): AstNode(pos), length(length) { }
void accept(NodeVisitor& v) const {
v.visit(*this);
@@ -108,14 +108,19 @@ public:
std::string name;
std::string ptr {""};
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
// Convert dot notation to json pointer notation
static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
std::string result;
do {
nonstd::string_view part;
std::tie(part, ptr_name) = string_view::split(ptr_name, '.');
ptr.push_back('/');
ptr.append(part.begin(), part.end());
result.push_back('/');
result.append(part.begin(), part.end());
} while (!ptr_name.empty());
return result;
}
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
ptr = convert_dot_to_json_ptr(ptr_name);
}
void accept(NodeVisitor& v) const {

View File

@@ -471,7 +471,7 @@ class Parser {
}
} return;
case Token::Kind::Text: {
current_block->nodes.emplace_back(std::make_shared<TextNode>(tok.text, tok.text.data() - tmpl.content.c_str()));
current_block->nodes.emplace_back(std::make_shared<TextNode>(tok.text.data() - tmpl.content.c_str(), tok.text.size()));
} break;
case Token::Kind::StatementOpen: {
get_next_token();

View File

@@ -147,7 +147,7 @@ class Renderer : public NodeVisitor {
}
void visit(const TextNode& node) {
*output_stream << node.content;
output_stream->write(current_template->content.c_str() + node.pos, node.length);
}
void visit(const ExpressionNode&) { }
@@ -344,7 +344,7 @@ class Renderer : public NodeVisitor {
} break;
case Op::Exists: {
auto &&name = get_arguments<1>(node)[0]->get_ref<const std::string &>();
result_ptr = std::make_shared<json>(json_input->contains(json::json_pointer(JsonNode(name, 0).ptr)));
result_ptr = std::make_shared<json>(json_input->contains(json::json_pointer(JsonNode::convert_dot_to_json_ptr(name))));
json_tmp_stack.push_back(result_ptr);
json_eval_stack.push(result_ptr.get());
} break;

View File

@@ -74,6 +74,7 @@ TEST_CASE("functions") {
SUBCASE("at") {
CHECK(env.render("{{ at(names, 0) }}", data) == "Jeff");
CHECK(env.render("{{ at(names, i) }}", data) == "Seb");
// CHECK(env.render("{{ at(names, 45) }}", data) == "Jeff");
}
SUBCASE("first") {