Skip to content

Commit 52dae0c

Browse files
committed
review
1 parent e847c7b commit 52dae0c

7 files changed

Lines changed: 86 additions & 60 deletions

File tree

private/rdf4cpp/parser/JsonLdContextParser.cpp

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#include "JsonLdContextParser.hpp"
22

33
namespace rdf4cpp::parser::json_ld {
4-
nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_context(simdjson::ondemand::value local_context, Context const &active_context, std::string_view base_iri, bool override_protected, bool propagate) {
4+
nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_context(simdjson::ondemand::value local_context, params::ParseContextParams p) {
55
// https://www.w3.org/TR/json-ld11-api/#context-processing-algorithm
66
// 1
7-
nonstd::expected<Context, error_type> result{active_context};
7+
nonstd::expected<Context, error_type> result{p.active_context};
88
for (auto &t : result->terms) {
99
t.needs_context_check = false;
1010
}
@@ -170,9 +170,9 @@ namespace rdf4cpp::parser::json_ld {
170170
.active_context = *result,
171171
.term = term,
172172
.previous_terms = previous_terms,
173-
.base_iri = base_iri,
173+
.base_iri = p.base_iri,
174174
.is_protected = prot,
175-
.override_protected = override_protected,
175+
.override_protected = p.override_protected,
176176
});
177177
if (e.has_value()) {
178178
result = nonstd::unexpected{e.value()};
@@ -183,34 +183,36 @@ namespace rdf4cpp::parser::json_ld {
183183
return false;
184184
};
185185

186+
auto handle_null = [&]() -> nonstd::expected<Context, error_type> {
187+
if (!p.override_protected) {
188+
for (auto const &t : p.active_context.terms) {
189+
if (t.is_protected) {
190+
result = nonstd::unexpected{make_error(ParsingError::Type::BadSyntax, "invalid context nullification")};
191+
return result;
192+
}
193+
}
194+
}
195+
return Context{
196+
.base_iri{original_base_iri},
197+
};
198+
};
199+
186200
if (local_context.type() == simdjson::ondemand::json_type::object) {
187201
// 2 & 3
188202
simdjson::ondemand::object const o = local_context.get_object();
189203
auto [c, prop] = try_get_field<bool>(o, keyword_propagate);
190-
bool p = propagate;
191-
if (c == simdjson::SUCCESS) {
192-
p = prop;
193-
}
194-
if (!p && result->previous_context == nullptr) {
195-
result->previous_context = &active_context;
204+
bool const actual_propagate = c == simdjson::SUCCESS ? prop : p.propagate;
205+
if (!actual_propagate && result->previous_context == nullptr) {
206+
result->previous_context = &p.active_context;
196207
}
197208
//error handling later
198209

199210
handle_ctx(o); // 4
200-
} else if (local_context.is_scalar() && local_context.is_null()) {
201-
for (auto const &t : active_context.terms) {
202-
if (t.is_protected) {
203-
result = nonstd::unexpected{make_error(ParsingError::Type::BadSyntax, "invalid context nullification")};
204-
return result;
205-
}
206-
}
207-
result = Context{
208-
.base_iri{base_iri},
209-
};
210-
return result;
211+
} else if (local_context.is_scalar() && local_context.is_null()) { // 5.1
212+
return handle_null();
211213
} else {
212-
if (!propagate && result->previous_context == nullptr) {
213-
result->previous_context = &active_context;
214+
if (!p.propagate && result->previous_context == nullptr) {
215+
result->previous_context = &p.active_context;
214216
}
215217
simdjson::ondemand::array a{};
216218
if (local_context.get(a) != simdjson::SUCCESS) {
@@ -220,19 +222,15 @@ namespace rdf4cpp::parser::json_ld {
220222
for (auto v : a) {
221223
switch (v.type()) {
222224
case simdjson::ondemand::json_type::null: // 5.1
225+
{
223226
v.is_null();
224-
if (!override_protected) {
225-
for (auto const &t : active_context.terms) {
226-
if (t.is_protected) {
227-
result = nonstd::unexpected{make_error(ParsingError::Type::BadSyntax, "invalid context nullification")};
228-
return result;
229-
}
230-
}
227+
auto r = handle_null();
228+
if (!r.has_value()) {
229+
return r;
231230
}
232-
result = Context{
233-
.base_iri{base_iri},
234-
};
231+
result = r;
235232
break;
233+
}
236234
case simdjson::ondemand::json_type::object: // 5.4
237235
if (handle_ctx(v.get_object())) {
238236
return result;
@@ -252,7 +250,11 @@ namespace rdf4cpp::parser::json_ld {
252250
if (result.has_value()) {
253251
for (auto const &t : result->terms) {
254252
if (t.needs_context_check && t.context.has_value()) {
255-
auto lc = parse_local_context(simdjson::padded_string_view{*t.context}, *result, base_iri, true);
253+
auto lc = parse_local_context(simdjson::padded_string_view{*t.context}, {
254+
.active_context = *result,
255+
.base_iri = p.base_iri,
256+
.override_protected = true,
257+
});
256258
if (!lc.has_value()) {
257259
return nonstd::unexpected(make_error(ParsingError::Type::BadSyntax, std::format("invalid scoped context ({})", lc.error().message)));
258260
}
@@ -457,7 +459,7 @@ namespace rdf4cpp::parser::json_ld {
457459
}
458460
static constexpr std::array invalid = {keyword_json, keyword_none, keyword_id, keyword_vocab};
459461
if (type->type == IRIMappingType::Keyword && !std::ranges::any_of(invalid, [&](std::string_view a) {
460-
return a == v;
462+
return a == type->data;
461463
})) {
462464
return make_error(ParsingError::Type::BadSyntax, "invalid type mapping (invalid keyword)");
463465
}
@@ -555,7 +557,7 @@ namespace rdf4cpp::parser::json_ld {
555557
p.term.iri_mapping.data.append(std::string_view(p.term.key).substr(colon_pos + 2));
556558
} else {
557559
p.term.iri_mapping.data = p.term.key;
558-
p.term.iri_mapping.type = std::string_view(p.term.key).substr(2) == "_:" ? IRIMappingType::BlankNode : IRIMappingType::IRI;
560+
p.term.iri_mapping.type = p.term.key.starts_with("_:") ? IRIMappingType::BlankNode : IRIMappingType::IRI;
559561
}
560562
}
561563
// 16
@@ -789,13 +791,13 @@ namespace rdf4cpp::parser::json_ld {
789791
p.term.parse_state = ParseState::Done;
790792
return std::nullopt;
791793
}
792-
nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_local_context(simdjson::padded_string_view json, Context const &active_context, std::string_view base_iri, bool override_protected, bool propagate) {
794+
nonstd::expected<Context, ContextParser::error_type> ContextParser::parse_local_context(simdjson::padded_string_view json, params::ParseContextParams p) {
793795
simdjson::ondemand::parser parser{};
794796
simdjson::ondemand::document doc = parser.iterate(json);
795797
if (doc.is_scalar()) {
796798
return nonstd::unexpected{make_error(ParsingError::Type::BadSyntax, doc.is_string() ? "remote context not supported" : "context free floating scalar")};
797799
}
798-
return parse_context(doc, active_context, base_iri, override_protected, propagate);
800+
return parse_context(doc, p);
799801
}
800802
nonstd::expected<IRIMapping, ContextParser::error_type> ContextParser::iri_expansion(Context const &active_context,
801803
std::optional<std::string_view> value,
@@ -901,6 +903,7 @@ namespace rdf4cpp::parser::json_ld {
901903
}
902904
// 9
903905
// no keyword, bn or valid iri, would have passed any further check
906+
// => not possible to result in a valid Node, ignore it
904907
return IRIMapping{std::string(""), IRIMappingType::None};
905908
}
906909
} // namespace rdf4cpp::parser::json_ld

private/rdf4cpp/parser/JsonLdContextParser.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
namespace rdf4cpp::parser {
1414
namespace params {
15+
struct ParseContextParams {
16+
json_ld::Context const &active_context;
17+
std::string_view base_iri;
18+
bool override_protected = false;
19+
bool propagate = true;
20+
};
1521
struct ParseContextTermParams {
1622
simdjson::ondemand::object local_context;
1723
json_ld::Context &active_context; // NOLINT(*-avoid-const-or-ref-data-members)
@@ -32,19 +38,12 @@ namespace rdf4cpp::parser {
3238
struct ContextParser {
3339
using error_type = ParsingError;
3440
IRIFactory *iri_factory;
41+
std::string original_base_iri;
3542

36-
nonstd::expected<Context, error_type> parse_context(simdjson::ondemand::value local_context,
37-
Context const &active_context,
38-
std::string_view base_iri,
39-
bool override_protected = false,
40-
bool propagate = true);
43+
nonstd::expected<Context, error_type> parse_context(simdjson::ondemand::value local_context, params::ParseContextParams p);
4144
std::optional<error_type> parse_context_term(params::ParseContextTermParams p);
4245

43-
nonstd::expected<Context, error_type> parse_local_context(simdjson::padded_string_view json,
44-
Context const &active_context,
45-
std::string_view base_iri,
46-
bool override_protected = false,
47-
bool propagate = true);
46+
nonstd::expected<Context, error_type> parse_local_context(simdjson::padded_string_view json, params::ParseContextParams p);
4847

4948

5049
nonstd::expected<IRIMapping, error_type> iri_expansion(Context const &active_context,

private/rdf4cpp/parser/JsonLdExpandParser.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ namespace rdf4cpp::parser::json_ld {
150150
}
151151
std::optional<Context> ctx = std::nullopt;
152152
if (property_scoped_context != nullptr) {
153-
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*property_scoped_context}, p.active_context, active_term->base_iri.has_value() ? *active_term->base_iri : p.base_iri);
153+
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*property_scoped_context}, {
154+
.active_context = p.active_context,
155+
.base_iri = active_term->base_iri.has_value() ? *active_term->base_iri : p.base_iri,
156+
});
154157
if (!r.has_value()) {
155158
return nonstd::unexpected(r.error());
156159
}
@@ -210,7 +213,11 @@ namespace rdf4cpp::parser::json_ld {
210213
// 8
211214
ExpandedMap result{};
212215
if (property_scoped_context != nullptr) {
213-
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*property_scoped_context}, *active_ctx_for_local, active_term->base_iri.has_value() ? *active_term->base_iri : p.base_iri, true);
216+
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*property_scoped_context}, {
217+
.active_context = *active_ctx_for_local,
218+
.base_iri = active_term->base_iri.has_value() ? *active_term->base_iri : p.base_iri,
219+
.override_protected = true,
220+
});
214221
if (!r.has_value()) {
215222
return nonstd::unexpected(r.error());
216223
}
@@ -224,7 +231,10 @@ namespace rdf4cpp::parser::json_ld {
224231
if (c != simdjson::SUCCESS) {
225232
return nonstd::unexpected(make_error(ParsingError::Type::BadSyntax, "invalid context"));
226233
}
227-
auto r = context_parser.parse_context(v, *active_ctx, p.base_iri);
234+
auto r = context_parser.parse_context(v, {
235+
.active_context = *active_ctx,
236+
.base_iri = p.base_iri,
237+
});
228238
if (!r.has_value()) {
229239
return nonstd::unexpected(r.error());
230240
}
@@ -260,7 +270,12 @@ namespace rdf4cpp::parser::json_ld {
260270
if (term == nullptr || !term->context.has_value()) {
261271
return std::nullopt;
262272
}
263-
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*term->context}, *active_ctx, p.base_iri, false, false);
273+
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*term->context}, {
274+
.active_context = *active_ctx,
275+
.base_iri = p.base_iri,
276+
.override_protected = false,
277+
.propagate = false,
278+
});
264279
if (!r.has_value()) {
265280
return r.error();
266281
}
@@ -684,7 +699,10 @@ namespace rdf4cpp::parser::json_ld {
684699
if (term_definition->has_container_mapping(keyword_type)) {
685700
auto *index_term = map_context->try_find_term(index);
686701
if (index_term != nullptr && index_term->context.has_value()) {
687-
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*index_term->context}, *map_context, index_term->base_iri.value_or(""));
702+
auto r = context_parser.parse_local_context(simdjson::padded_string_view{*index_term->context}, {
703+
.active_context = *map_context,
704+
.base_iri = index_term->base_iri.value_or(""),
705+
});
688706
if (!r.has_value()) {
689707
return r.error();
690708
}
@@ -892,7 +910,7 @@ namespace rdf4cpp::parser::json_ld {
892910
return false;
893911
}
894912
index = true;
895-
} else if (expanded_property->is_keyword(keyword_index)) {
913+
} else if (expanded_property->is_keyword(keyword_id)) {
896914
if (id) {
897915
ob.reset();
898916
return false;

private/rdf4cpp/parser/JsonLdExpandParser.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ namespace rdf4cpp::parser {
4141
using error_type = ParsingError;
4242
ContextParser context_parser;
4343

44-
inline explicit ExpandParser(IRIFactory &f)
45-
: context_parser(&f) {
44+
inline explicit ExpandParser(IRIFactory &f, std::string base_iri)
45+
: context_parser(&f, std::move(base_iri)) {
4646
}
4747

4848
nonstd::expected<ExpandedValue, error_type> value_expansion(Context const &active_conext,

private/rdf4cpp/parser/JsonLdParser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ namespace rdf4cpp::parser {
618618
*p.obj_out = next_bn;
619619
p.obj_out = nullptr;
620620
}
621-
if (curr_sub->type != json_ld::IRIMappingType::None && curr_sub->type != json_ld::IRIMappingType::None) {
621+
if (curr_sub->type != json_ld::IRIMappingType::None && curr_pred->type != json_ld::IRIMappingType::None) {
622622
co_yield make_quad(p.active_graph, *curr_sub, *curr_pred, next_bn);
623623
}
624624
if (std::holds_alternative<json_ld::IRIMapping>(curr_obj)) {
@@ -634,13 +634,13 @@ namespace rdf4cpp::parser {
634634
*p.obj_out = nil;
635635
p.obj_out = nullptr;
636636
}
637-
if (curr_sub->type != json_ld::IRIMappingType::None && curr_sub->type != json_ld::IRIMappingType::None) {
637+
if (curr_sub->type != json_ld::IRIMappingType::None && curr_pred->type != json_ld::IRIMappingType::None) {
638638
co_yield make_quad(p.active_graph, *curr_sub, *curr_pred, nil);
639639
}
640640
}
641641
IStreamQuadIterator::ImplJsonLd::result_generator IStreamQuadIterator::ImplJsonLd::parse() {
642642
simdjson::ondemand::parser parser{};
643-
auto c = parser.allocate(json_data_.size() * 5);
643+
auto c = parser.allocate(json_data_.size() * BufferSizeMult);
644644
if (c != simdjson::SUCCESS) {
645645
co_yield nonstd::unexpected(json_ld::make_error(ParsingError::Type::BadSyntax, "failed to allocate parser"));
646646
co_return;
@@ -681,7 +681,7 @@ namespace rdf4cpp::parser {
681681
: state_(initial_state == nullptr ? new state_type() : initial_state),
682682
state_is_owned_(initial_state == nullptr),
683683
json_data_(std::move(json)),
684-
expand_parser_(state_->iri_factory),
684+
expand_parser_(state_->iri_factory, std::string(state_->iri_factory.get_base())),
685685
direction_(flags.get_direction()),
686686
active_generator_(parse()),
687687
current_iter_(active_generator_.begin()) {

private/rdf4cpp/parser/JsonLdParser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ namespace rdf4cpp::parser {
8181
result_generator active_generator_;
8282
std::ranges::iterator_t<result_generator> current_iter_;
8383

84+
static constexpr size_t BufferSizeMult = 5;
85+
8486
public:
8587
[[nodiscard]] std::optional<nonstd::expected<ok_type, error_type>> next() override;
8688
[[nodiscard]] uint64_t current_line() const noexcept override;

private/rdf4cpp/parser/JsonLdParserTypes.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ namespace rdf4cpp::parser {
9191
};
9292
std::optional<BaseDirection> try_parse_base_direction(std::string_view d);
9393

94+
// corresponds to the defined map from the context parsing algorithms.
9495
enum class ParseState : uint8_t {
96+
// not in the map
9597
NotStarted,
98+
// false
9699
InProgress,
100+
// true
97101
Done,
98102
};
99103

0 commit comments

Comments
 (0)