MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / cbEnsureParserBinding

Method cbEnsureParserBinding

pj_runtime/src/DataSourceRuntimeHost.cpp:421–589  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

419}
420
421bool DataSourceRuntimeHost::cbEnsureParserBinding(
422 void* ctx, const PJ_parser_binding_request_t* request, PJ_parser_binding_handle_t* out,
423 PJ_error_t* out_error) noexcept {
424 auto* self = static_cast<DataSourceRuntimeHost*>(ctx);
425 try {
426 const std::string_view encoding(request->parser_encoding.data, request->parser_encoding.size);
427 const std::string_view topic_name(request->topic_name.data, request->topic_name.size);
428 const std::string_view type_name(request->type_name.data, request->type_name.size);
429
430 const LoadedMessageParser* parser_entry =
431 self->catalog_.findParserByEncoding(QString::fromUtf8(encoding.data(), static_cast<int>(encoding.size())));
432 if (parser_entry == nullptr) {
433 return self->fail(out_error, ("no parser found for encoding '" + std::string(encoding) + "'").c_str());
434 }
435
436 auto parser = std::make_unique<MessageParserHandle>(parser_entry->library.createHandle());
437 if (!parser->valid()) {
438 return self->fail(out_error, ("failed to create parser instance for '" + std::string(encoding) + "'").c_str());
439 }
440
441 auto topic_or = self->engine_.createTopic(self->dataset_id_, TopicDescriptor{.name = std::string(topic_name)});
442 if (!topic_or.has_value()) {
443 return self->fail(
444 out_error, ("failed to create topic '" + std::string(topic_name) + "': " + topic_or.error()).c_str());
445 }
446 const PJ_topic_handle_t topic_handle{static_cast<uint32_t>(*topic_or)};
447
448 // Lockstep-mirror into the secondary engine with the SAME TopicId. The two
449 // engines' TopicId counters drift whenever the primary gets topics the
450 // secondary doesn't (e.g. a file loaded between streams), so we force the
451 // secondary topic id to match the primary's instead of relying on the
452 // counters staying in step. A later push uses one id against whichever
453 // engine is the active target, so the ids MUST match.
454 if (self->secondary_data_engine_ != nullptr) {
455 auto mirrored = self->secondary_data_engine_->createTopic(
456 self->dataset_id_, TopicDescriptor{.name = std::string(topic_name)}, *topic_or);
457 if (!mirrored.has_value()) {
458 return self->fail(
459 out_error,
460 ("failed to mirror topic '" + std::string(topic_name) + "' into secondary engine: " + mirrored.error())
461 .c_str());
462 }
463 }
464
465 auto write_host = std::make_unique<DatastoreParserWriteHost>(self->engine_, topic_handle);
466 // Same lockstep wiring as the source-level write host (see the runtime
467 // host constructor). Closes the latent FieldHandle-stale bug for parser
468 // plugins that cache handles across messages (parser_protobuf et al.):
469 // every ensureField inside parserAppendRecord/appendBoundRecord is now
470 // mirrored to the secondary engine via DataEngine::createTopicField with
471 // the same FieldId, so the cached handle resolves after a pause/resume
472 // target swap.
473 write_host->setSecondaryEngine(self->secondary_data_engine_);
474
475 // Build the service registry the parser binds against. The builder must
476 // outlive bind() because the plugin may hold a view into it; we move it
477 // into the ParserBinding so its lifetime matches the parser's.
478 auto registry_builder = std::make_unique<ServiceRegistryBuilder>();

Callers

nothing calls this directly

Calls 15

failMethod · 0.95
nameFunction · 0.85
findParserByEncodingMethod · 0.80
createTopicMethod · 0.80
setSecondaryEngineMethod · 0.80
bindSchemaMethod · 0.80
loadConfigMethod · 0.80
findTopicMethod · 0.80
dataMethod · 0.45
sizeMethod · 0.45
validMethod · 0.45
rawMethod · 0.45

Tested by

no test coverage detected