#include #include #include #include #include // for strdup typedef void* TrieHandle; // Opaque pointer to represent the trie in C struct Entry { const std::string_view decoded_view; const uint64_t id; inline Entry(const std::string_view decoded_view, const uint64_t id) : decoded_view(decoded_view), id(id) {} }; TrieHandle load_trie_from_cstring(const char* cstr) { // Convert C-style string to C++ string std::string dict_file(cstr); // Print the file path to ensure it's correct try { // Load the trie object (using xcdat::load) xcdat::trie_15_type* trie = new xcdat::trie_15_type(xcdat::load(dict_file)); return reinterpret_cast(trie); // Return the pointer as an opaque handle } catch (const std::exception& e) { // Catch any exceptions related to loading the trie and print a friendly message // Return nullptr to indicate failure return nullptr; } } const char** search_prefix(TrieHandle handle, const char* search_str, size_t* result_count) { xcdat::trie_15_type* trie = reinterpret_cast(handle); xcdat::trie_15_type::prefix_iterator itr = trie->make_prefix_iterator(search_str); std::vector results; while (itr.next()) { results.push_back(std::string(itr.decoded_view())); } // Allocate memory to store the results + 1 for the null terminator *result_count = results.size(); const char** result_array = new const char*[*result_count + 1]; // +1 for null pointer // Copy the results from the vector to the array for (size_t i = 0; i < *result_count; ++i) { result_array[i] = strdup(results[i].c_str()); // Dynamically allocate strings } // Add a null terminator result_array[*result_count] = nullptr; return result_array; } // C territory // Wrapper function to load the trie, for C usage extern "C" TrieHandle load_trie(const char* dict_file) { return load_trie_from_cstring(dict_file); } // Wrapper function to perform a search and return results, for C usage extern "C" const char** perform_search(TrieHandle handle, const char* search_str, size_t* result_count) { return search_prefix(handle, search_str, result_count); } // Function to free the memory allocated for the trie (opaque pointer) extern "C" void free_trie(TrieHandle handle) { xcdat::trie_15_type* trie = reinterpret_cast(handle); delete trie; } // Function to free the memory allocated for search results (const char**) extern "C" void free_search_results(const char** results) { delete[] results; }