| 472 | } // namespace |
| 473 | |
| 474 | SegmentationPtr CreatePluginSegmentation(const std::string& type, |
| 475 | const PluginConfigPairs& configPairs) { |
| 476 | // Allow explicit plugin library path via __plugin_library config pair, |
| 477 | // bypassing search-based discovery (used by language bindings to bundle |
| 478 | // plugins as optional packages with deterministic paths). |
| 479 | std::string pluginLibraryPath; |
| 480 | for (const auto& pair : configPairs) { |
| 481 | if (pair.first == "__plugin_library") { |
| 482 | pluginLibraryPath = pair.second; |
| 483 | break; |
| 484 | } |
| 485 | } |
| 486 | std::shared_ptr<PluginLibrary> plugin = |
| 487 | pluginLibraryPath.empty() |
| 488 | ? GetPluginManager().LoadByType(type) |
| 489 | : GetPluginManager().LoadByPath(pluginLibraryPath, type); |
| 490 | std::vector<opencc_kv_pair_t> rawConfig; |
| 491 | rawConfig.reserve(configPairs.size()); |
| 492 | for (const auto& pair : configPairs) { |
| 493 | rawConfig.push_back( |
| 494 | {sizeof(opencc_kv_pair_t), pair.first.c_str(), pair.second.c_str()}); |
| 495 | } |
| 496 | |
| 497 | opencc_segmentation_handle_t* handle = nullptr; |
| 498 | opencc_error_t error = {}; |
| 499 | error.struct_size = sizeof(error); |
| 500 | opencc_segmentation_create_args_t args = {}; |
| 501 | args.struct_size = sizeof(args); |
| 502 | args.config = rawConfig.empty() ? nullptr : rawConfig.data(); |
| 503 | args.config_size = rawConfig.size(); |
| 504 | args.out = &handle; |
| 505 | args.error = &error; |
| 506 | const int status = plugin->descriptor->create(&args); |
| 507 | if (status != 0 || handle == nullptr) { |
| 508 | const std::string message = |
| 509 | TakeErrorMessage(plugin->descriptor, &error, "unknown error"); |
| 510 | throw InvalidFormat("Failed to initialize segmentation plugin '" + type + |
| 511 | "': " + message); |
| 512 | } |
| 513 | return SegmentationPtr(new PluginSegmentationAdapter(plugin, handle)); |
| 514 | } |
| 515 | |
| 516 | } // namespace opencc |
no test coverage detected