Skip to content

Commit 7529f21

Browse files
committed
dont copy strings into textnodes
1 parent 59b446b commit 7529f21

File tree

4 files changed

+15
-9
lines changed

4 files changed

+15
-9
lines changed

include/inja/node.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ class BlockNode : public AstNode {
7474

7575
class TextNode : public AstNode {
7676
public:
77-
std::string content;
77+
size_t length;
7878

79-
explicit TextNode(nonstd::string_view content, size_t pos): AstNode(pos), content(content) { }
79+
explicit TextNode(size_t pos, size_t length): AstNode(pos), length(length) { }
8080

8181
void accept(NodeVisitor& v) const {
8282
v.visit(*this);
@@ -108,14 +108,19 @@ class JsonNode : public ExpressionNode {
108108
std::string name;
109109
std::string ptr {""};
110110

111-
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
112-
// Convert dot notation to json pointer notation
111+
static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
112+
std::string result;
113113
do {
114114
nonstd::string_view part;
115115
std::tie(part, ptr_name) = string_view::split(ptr_name, '.');
116-
ptr.push_back('/');
117-
ptr.append(part.begin(), part.end());
116+
result.push_back('/');
117+
result.append(part.begin(), part.end());
118118
} while (!ptr_name.empty());
119+
return result;
120+
}
121+
122+
explicit JsonNode(nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
123+
ptr = convert_dot_to_json_ptr(ptr_name);
119124
}
120125

121126
void accept(NodeVisitor& v) const {

include/inja/parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class Parser {
471471
}
472472
} return;
473473
case Token::Kind::Text: {
474-
current_block->nodes.emplace_back(std::make_shared<TextNode>(tok.text, tok.text.data() - tmpl.content.c_str()));
474+
current_block->nodes.emplace_back(std::make_shared<TextNode>(tok.text.data() - tmpl.content.c_str(), tok.text.size()));
475475
} break;
476476
case Token::Kind::StatementOpen: {
477477
get_next_token();

include/inja/renderer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class Renderer : public NodeVisitor {
147147
}
148148

149149
void visit(const TextNode& node) {
150-
*output_stream << node.content;
150+
output_stream->write(current_template->content.c_str() + node.pos, node.length);
151151
}
152152

153153
void visit(const ExpressionNode&) { }
@@ -344,7 +344,7 @@ class Renderer : public NodeVisitor {
344344
} break;
345345
case Op::Exists: {
346346
auto &&name = get_arguments<1>(node)[0]->get_ref<const std::string &>();
347-
result_ptr = std::make_shared<json>(json_input->contains(json::json_pointer(JsonNode(name, 0).ptr)));
347+
result_ptr = std::make_shared<json>(json_input->contains(json::json_pointer(JsonNode::convert_dot_to_json_ptr(name))));
348348
json_tmp_stack.push_back(result_ptr);
349349
json_eval_stack.push(result_ptr.get());
350350
} break;

test/test-functions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ TEST_CASE("functions") {
7474
SUBCASE("at") {
7575
CHECK(env.render("{{ at(names, 0) }}", data) == "Jeff");
7676
CHECK(env.render("{{ at(names, i) }}", data) == "Seb");
77+
// CHECK(env.render("{{ at(names, 45) }}", data) == "Jeff");
7778
}
7879

7980
SUBCASE("first") {

0 commit comments

Comments
 (0)