Loading main.c +97 −37 Original line number Diff line number Diff line #include <gio/gio.h> #include <glib-unix.h> #include "zero-pinyin-service.h" #include "../sqlite3_util.h" #include <sqlite3.h> struct _AppData { typedef struct { GApplication *app; GDBusNodeInfo *introspection_data; guint owner_id; }; typedef struct _AppData AppData; sqlite3 *db; gboolean init_done; } AppData; static AppData appdata; Loading @@ -18,6 +19,7 @@ static const gchar introspection_xml[] = " <interface name='com.emacsos.zero.ZeroPinyinService'>" " <method name='GetCandidates'>" " <arg type='s' name='preedit_str'/>" " <arg type='u' name='fetch_size'/>" " <arg type='as' name='candidates' direction='out'/>" " <arg type='au' name='matched_preedit_str_lengths' direction='out'/>" " </method>" Loading @@ -31,20 +33,33 @@ handle_method_get_candidates (GDBusMethodInvocation *invocation, GVariant *parameters) { gchar *preedit_str = NULL; guint fetch_size = 0; GVariant *result = NULL; GVariantBuilder *candidates_builder = NULL; GVariantBuilder *matched_lengths_builder = NULL; /* GVariant *candidates = NULL; */ /* GVariant *matched_preedit_str_lengths = NULL; */ g_variant_get (parameters, "(s)", &preedit_str); g_variant_get (parameters, "(su)", &preedit_str, &fetch_size); g_return_if_fail (preedit_str != NULL); g_return_if_fail (fetch_size > 0); if (preedit_str == NULL || fetch_size == 0) { g_dbus_method_invocation_return_dbus_error ( invocation, "org.gtk.GDBus.Failed", "Bad param"); if (preedit_str) g_free (preedit_str); return; } g_message ("get_candidates for preedit_str=%s fetch_size=%u", preedit_str, fetch_size); candidates_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); matched_lengths_builder = g_variant_builder_new (G_VARIANT_TYPE ("au")); /* test data */ get_candidates_test (preedit_str, candidates_builder, matched_lengths_builder); /* get_candidates_test (preedit_str, fetch_size, candidates_builder, matched_lengths_builder); */ get_candidates (appdata->db, preedit_str, fetch_size, candidates_builder, matched_lengths_builder); result = g_variant_new ("(asau)", candidates_builder, matched_lengths_builder); g_assert_nonnull (result); Loading Loading @@ -176,7 +191,7 @@ config_dbus_service (AppData *appdata) g_assert (appdata->introspection_data != NULL); appdata->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, "com.emacsos.zero.ZeroPinyinService", G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT|G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, on_name_acquired, on_name_lost, Loading @@ -197,37 +212,43 @@ on_sigterm_received (gpointer user_data) } static void activate (GApplication *app, AppData *appdata) config_db (AppData* appdata) { /* no-op */ g_message ("zero-pinyin-service activate()"); gint ri = 0; gboolean r = FALSE; static const char* SQLITE3_MEMORY_DB = ":memory:"; sqlite3* db = NULL; gchar* sql = NULL; ri = sqlite3_open (SQLITE3_MEMORY_DB, &db); g_assert_cmpint (ri, ==, SQLITE_OK); g_assert_nonnull (db); /* TODO make db path configurable */ /* TODO remove user name in db path */ sql = sqlite3_mprintf ("ATTACH %Q AS maindb", "/home/sylecn/.cache/ibus/pinyin/main.db"); r = sqlite3_exec_simple (db, sql); g_assert (r); sqlite3_free (sql); /* TODO make db path configurable */ sql = sqlite3_mprintf ("ATTACH %Q AS userdb", "/home/sylecn/.cache/ibus/pinyin/user-1.0.db"); r = sqlite3_exec_simple (db, sql); g_assert (r); sqlite3_free (sql); appdata->db = db; } static void startup (GApplication *app, zero_pinyin_service_init (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service startup()"); appdata->introspection_data = NULL; appdata->owner_id = 0; appdata->db = NULL; config_dbus_service (appdata); g_application_hold (app); } static void shutdown (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service shutdown()"); if (appdata->owner_id > 0) { g_bus_unown_name (appdata->owner_id); appdata->owner_id = 0; } if (appdata->introspection_data != NULL) { g_dbus_node_info_unref (appdata->introspection_data); appdata->introspection_data = NULL; } config_db (appdata); appdata->init_done = TRUE; } /** Loading @@ -248,6 +269,45 @@ setup_sigint_sigterm_handler (AppData *appdata) g_source_unref (source); } static void startup (GApplication* app, AppData* appdata) { g_message ("zero-pinyin-service startup()"); setup_sigint_sigterm_handler (appdata); g_assert_false (appdata->init_done); zero_pinyin_service_init (app, appdata); g_application_hold (app); } static void activate (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service activate()"); /* as a pure service, activate is a no-op. */ } static void shutdown (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service shutdown()"); if (appdata->owner_id > 0) { g_bus_unown_name (appdata->owner_id); appdata->owner_id = 0; } if (appdata->introspection_data != NULL) { g_dbus_node_info_unref (appdata->introspection_data); appdata->introspection_data = NULL; } if (appdata->db != NULL) { sqlite3_close (appdata->db); appdata->db = NULL; } } /** * provide zero-pinyin-service dbus service. * it's a console app based on glib and gio. Loading @@ -258,15 +318,15 @@ main (int argc, char *argv[]) GApplication *app = NULL; int status = 0; app = g_application_new ("com.emacsos.zero.App.ZeroPinyinService", app = g_application_new ("com.emacsos.zero.ZeroPinyinServiceApp", G_APPLICATION_FLAGS_NONE); g_assert_nonnull (app); appdata.app = app; appdata.init_done = FALSE; g_signal_connect (app, "activate", G_CALLBACK (activate), &appdata); g_signal_connect (app, "startup", G_CALLBACK (startup), &appdata); g_signal_connect (app, "activate", G_CALLBACK (activate), &appdata); g_signal_connect (app, "shutdown", G_CALLBACK (shutdown), &appdata); setup_sigint_sigterm_handler (&appdata); status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); Loading meson.build +14 −4 Original line number Diff line number Diff line # -*- mode: conf -*- project('zero-pinyin-service', ['c', 'cpp'], version: '0.1.0', version: '0.2.0', license: 'GPL', default_options: [ 'warning_level=2', Loading Loading @@ -33,12 +33,22 @@ endif glib = dependency('glib-2.0') gio = dependency('gio-unix-2.0') uuid = dependency('uuid') shared_dep = [glib, gio, uuid] sqlite3 = dependency('sqlite3') shared_dep = [glib, gio, uuid, sqlite3] src = ['../PinyinParser.cc', 'parse-pinyin.cpp', 'zero-pinyin-service.cc', 'main.c'] src = [ '../PinyinParser.cc', '../sqlite3_util.c', 'parse-pinyin.cpp', 'zero-pinyin-service.c', 'main.c'] executable('main', src, dependencies: shared_dep) test('zero-pinyin-service', test('parse-pinyin', executable('parse-pinyin', ['../PinyinParser.cc', 'parse-pinyin.cpp', 'parse-pinyin-test.cpp'], dependencies: shared_dep)) test('zero-pinyin-service-test', executable('zero-pinyin-service-test', ['zero-pinyin-service-test.c'], dependencies: shared_dep)) parse-pinyin-test.cpp +32 −4 Original line number Diff line number Diff line #include "parse-pinyin.hpp" #include "parse-pinyin.h" #include <iostream> #include <glib.h> static void test_parse_pinyin () test_parse_pinyin_cpp () { std::vector<Pinyin*>* result = parse_pinyin ("liyifeng"); std::vector<Pinyin*>* result = parse_pinyin_cpp ("liyifeng"); g_assert_cmpint (result->size (), ==, 3); g_assert_cmpint (result->at(0)->shengmu_i, ==, 10); Loading @@ -26,10 +25,39 @@ test_parse_pinyin () delete result; } static void test_parse_pinyin () { GList* result = NULL; Pinyin* thispy = NULL; result = parse_pinyin ("liyifeng", 15); g_assert_cmpint (g_list_length (result), ==, 3); thispy = (Pinyin*) g_list_nth_data (result, 0); g_assert_cmpint (thispy->shengmu_i, ==, 10); g_assert_cmpint (thispy->yunmu_i, ==, 34); g_assert_cmpint (thispy->length, ==, 2); thispy = (Pinyin*) g_list_nth_data (result, 1); g_assert_cmpint (thispy->shengmu_i, ==, 21); g_assert_cmpint (thispy->yunmu_i, ==, 34); g_assert_cmpint (thispy->length, ==, 2); thispy = (Pinyin*) g_list_nth_data (result, 2); g_assert_cmpint (thispy->shengmu_i, ==, 5); g_assert_cmpint (thispy->yunmu_i, ==, 32); g_assert_cmpint (thispy->length, ==, 4); g_list_free_full (result, g_free); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/zero/test_parse_pinyin_cpp", test_parse_pinyin_cpp); g_test_add_func ("/zero/test_parse_pinyin", test_parse_pinyin); Loading parse-pinyin.cpp +20 −2 Original line number Diff line number Diff line #include "parse-pinyin.hpp" #include "parse-pinyin.h" #include "../PinyinArray.h" #include "../PinyinParser.h" Loading @@ -11,7 +11,7 @@ * returns: a list of Pinyin */ std::vector<Pinyin*>* parse_pinyin (const char* preedit_str, guint max_pinyin) parse_pinyin_cpp (const char* preedit_str, const guint max_pinyin) { std::vector<Pinyin*>* result = new std::vector<Pinyin*>(); PyZy::PinyinArray pyar = {0}; Loading @@ -25,3 +25,21 @@ parse_pinyin (const char* preedit_str, guint max_pinyin) } return result; } GList* parse_pinyin (const char* preedit_str, const guint max_pinyin) { GList* result = NULL; PyZy::PinyinArray pyar = {0}; Pinyin* thispy = NULL; PyZy::PinyinParser::parse (preedit_str, strlen(preedit_str), 0, pyar, max_pinyin); for (guint i = 0; i < pyar.size(); ++i) { thispy = g_new (Pinyin, 1); thispy->shengmu_i = (int) pyar[i].pinyin->pinyin_id[0].sheng; thispy->yunmu_i = (int) pyar[i].pinyin->pinyin_id[0].yun; thispy->length = pyar[i].len; result = g_list_append (result, thispy); } return result; } parse-pinyin.hpp→parse-pinyin.h +31 −0 Original line number Diff line number Diff line #ifndef _PARSE_PINYIN_H_ #define _PARSE_PINYIN_H_ #include <vector> #include <glib.h> #include "zero-pinyin-service.h" #ifdef __cplusplus #include <vector> /** * parse preedit_str to groups of pinyin. * caller should free each Pinyin and the vector after use. */ std::vector<Pinyin*>* parse_pinyin (const char* preedit_str, guint max_pinyin=15); std::vector<Pinyin*>* parse_pinyin_cpp (const char* preedit_str, const guint max_pinyin=15); extern "C" { #endif /** * parse preedit_str to groups of pinyin. * caller should free each Pinyin and the GList after use. */ GList* parse_pinyin (const char* preedit_str, const guint max_pinyin); #ifdef __cplusplus } #endif #endif /* _PARSE_PINYIN_H_ */ Loading
main.c +97 −37 Original line number Diff line number Diff line #include <gio/gio.h> #include <glib-unix.h> #include "zero-pinyin-service.h" #include "../sqlite3_util.h" #include <sqlite3.h> struct _AppData { typedef struct { GApplication *app; GDBusNodeInfo *introspection_data; guint owner_id; }; typedef struct _AppData AppData; sqlite3 *db; gboolean init_done; } AppData; static AppData appdata; Loading @@ -18,6 +19,7 @@ static const gchar introspection_xml[] = " <interface name='com.emacsos.zero.ZeroPinyinService'>" " <method name='GetCandidates'>" " <arg type='s' name='preedit_str'/>" " <arg type='u' name='fetch_size'/>" " <arg type='as' name='candidates' direction='out'/>" " <arg type='au' name='matched_preedit_str_lengths' direction='out'/>" " </method>" Loading @@ -31,20 +33,33 @@ handle_method_get_candidates (GDBusMethodInvocation *invocation, GVariant *parameters) { gchar *preedit_str = NULL; guint fetch_size = 0; GVariant *result = NULL; GVariantBuilder *candidates_builder = NULL; GVariantBuilder *matched_lengths_builder = NULL; /* GVariant *candidates = NULL; */ /* GVariant *matched_preedit_str_lengths = NULL; */ g_variant_get (parameters, "(s)", &preedit_str); g_variant_get (parameters, "(su)", &preedit_str, &fetch_size); g_return_if_fail (preedit_str != NULL); g_return_if_fail (fetch_size > 0); if (preedit_str == NULL || fetch_size == 0) { g_dbus_method_invocation_return_dbus_error ( invocation, "org.gtk.GDBus.Failed", "Bad param"); if (preedit_str) g_free (preedit_str); return; } g_message ("get_candidates for preedit_str=%s fetch_size=%u", preedit_str, fetch_size); candidates_builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); matched_lengths_builder = g_variant_builder_new (G_VARIANT_TYPE ("au")); /* test data */ get_candidates_test (preedit_str, candidates_builder, matched_lengths_builder); /* get_candidates_test (preedit_str, fetch_size, candidates_builder, matched_lengths_builder); */ get_candidates (appdata->db, preedit_str, fetch_size, candidates_builder, matched_lengths_builder); result = g_variant_new ("(asau)", candidates_builder, matched_lengths_builder); g_assert_nonnull (result); Loading Loading @@ -176,7 +191,7 @@ config_dbus_service (AppData *appdata) g_assert (appdata->introspection_data != NULL); appdata->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, "com.emacsos.zero.ZeroPinyinService", G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT|G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, on_name_acquired, on_name_lost, Loading @@ -197,37 +212,43 @@ on_sigterm_received (gpointer user_data) } static void activate (GApplication *app, AppData *appdata) config_db (AppData* appdata) { /* no-op */ g_message ("zero-pinyin-service activate()"); gint ri = 0; gboolean r = FALSE; static const char* SQLITE3_MEMORY_DB = ":memory:"; sqlite3* db = NULL; gchar* sql = NULL; ri = sqlite3_open (SQLITE3_MEMORY_DB, &db); g_assert_cmpint (ri, ==, SQLITE_OK); g_assert_nonnull (db); /* TODO make db path configurable */ /* TODO remove user name in db path */ sql = sqlite3_mprintf ("ATTACH %Q AS maindb", "/home/sylecn/.cache/ibus/pinyin/main.db"); r = sqlite3_exec_simple (db, sql); g_assert (r); sqlite3_free (sql); /* TODO make db path configurable */ sql = sqlite3_mprintf ("ATTACH %Q AS userdb", "/home/sylecn/.cache/ibus/pinyin/user-1.0.db"); r = sqlite3_exec_simple (db, sql); g_assert (r); sqlite3_free (sql); appdata->db = db; } static void startup (GApplication *app, zero_pinyin_service_init (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service startup()"); appdata->introspection_data = NULL; appdata->owner_id = 0; appdata->db = NULL; config_dbus_service (appdata); g_application_hold (app); } static void shutdown (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service shutdown()"); if (appdata->owner_id > 0) { g_bus_unown_name (appdata->owner_id); appdata->owner_id = 0; } if (appdata->introspection_data != NULL) { g_dbus_node_info_unref (appdata->introspection_data); appdata->introspection_data = NULL; } config_db (appdata); appdata->init_done = TRUE; } /** Loading @@ -248,6 +269,45 @@ setup_sigint_sigterm_handler (AppData *appdata) g_source_unref (source); } static void startup (GApplication* app, AppData* appdata) { g_message ("zero-pinyin-service startup()"); setup_sigint_sigterm_handler (appdata); g_assert_false (appdata->init_done); zero_pinyin_service_init (app, appdata); g_application_hold (app); } static void activate (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service activate()"); /* as a pure service, activate is a no-op. */ } static void shutdown (GApplication *app, AppData *appdata) { g_message ("zero-pinyin-service shutdown()"); if (appdata->owner_id > 0) { g_bus_unown_name (appdata->owner_id); appdata->owner_id = 0; } if (appdata->introspection_data != NULL) { g_dbus_node_info_unref (appdata->introspection_data); appdata->introspection_data = NULL; } if (appdata->db != NULL) { sqlite3_close (appdata->db); appdata->db = NULL; } } /** * provide zero-pinyin-service dbus service. * it's a console app based on glib and gio. Loading @@ -258,15 +318,15 @@ main (int argc, char *argv[]) GApplication *app = NULL; int status = 0; app = g_application_new ("com.emacsos.zero.App.ZeroPinyinService", app = g_application_new ("com.emacsos.zero.ZeroPinyinServiceApp", G_APPLICATION_FLAGS_NONE); g_assert_nonnull (app); appdata.app = app; appdata.init_done = FALSE; g_signal_connect (app, "activate", G_CALLBACK (activate), &appdata); g_signal_connect (app, "startup", G_CALLBACK (startup), &appdata); g_signal_connect (app, "activate", G_CALLBACK (activate), &appdata); g_signal_connect (app, "shutdown", G_CALLBACK (shutdown), &appdata); setup_sigint_sigterm_handler (&appdata); status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); Loading
meson.build +14 −4 Original line number Diff line number Diff line # -*- mode: conf -*- project('zero-pinyin-service', ['c', 'cpp'], version: '0.1.0', version: '0.2.0', license: 'GPL', default_options: [ 'warning_level=2', Loading Loading @@ -33,12 +33,22 @@ endif glib = dependency('glib-2.0') gio = dependency('gio-unix-2.0') uuid = dependency('uuid') shared_dep = [glib, gio, uuid] sqlite3 = dependency('sqlite3') shared_dep = [glib, gio, uuid, sqlite3] src = ['../PinyinParser.cc', 'parse-pinyin.cpp', 'zero-pinyin-service.cc', 'main.c'] src = [ '../PinyinParser.cc', '../sqlite3_util.c', 'parse-pinyin.cpp', 'zero-pinyin-service.c', 'main.c'] executable('main', src, dependencies: shared_dep) test('zero-pinyin-service', test('parse-pinyin', executable('parse-pinyin', ['../PinyinParser.cc', 'parse-pinyin.cpp', 'parse-pinyin-test.cpp'], dependencies: shared_dep)) test('zero-pinyin-service-test', executable('zero-pinyin-service-test', ['zero-pinyin-service-test.c'], dependencies: shared_dep))
parse-pinyin-test.cpp +32 −4 Original line number Diff line number Diff line #include "parse-pinyin.hpp" #include "parse-pinyin.h" #include <iostream> #include <glib.h> static void test_parse_pinyin () test_parse_pinyin_cpp () { std::vector<Pinyin*>* result = parse_pinyin ("liyifeng"); std::vector<Pinyin*>* result = parse_pinyin_cpp ("liyifeng"); g_assert_cmpint (result->size (), ==, 3); g_assert_cmpint (result->at(0)->shengmu_i, ==, 10); Loading @@ -26,10 +25,39 @@ test_parse_pinyin () delete result; } static void test_parse_pinyin () { GList* result = NULL; Pinyin* thispy = NULL; result = parse_pinyin ("liyifeng", 15); g_assert_cmpint (g_list_length (result), ==, 3); thispy = (Pinyin*) g_list_nth_data (result, 0); g_assert_cmpint (thispy->shengmu_i, ==, 10); g_assert_cmpint (thispy->yunmu_i, ==, 34); g_assert_cmpint (thispy->length, ==, 2); thispy = (Pinyin*) g_list_nth_data (result, 1); g_assert_cmpint (thispy->shengmu_i, ==, 21); g_assert_cmpint (thispy->yunmu_i, ==, 34); g_assert_cmpint (thispy->length, ==, 2); thispy = (Pinyin*) g_list_nth_data (result, 2); g_assert_cmpint (thispy->shengmu_i, ==, 5); g_assert_cmpint (thispy->yunmu_i, ==, 32); g_assert_cmpint (thispy->length, ==, 4); g_list_free_full (result, g_free); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/zero/test_parse_pinyin_cpp", test_parse_pinyin_cpp); g_test_add_func ("/zero/test_parse_pinyin", test_parse_pinyin); Loading
parse-pinyin.cpp +20 −2 Original line number Diff line number Diff line #include "parse-pinyin.hpp" #include "parse-pinyin.h" #include "../PinyinArray.h" #include "../PinyinParser.h" Loading @@ -11,7 +11,7 @@ * returns: a list of Pinyin */ std::vector<Pinyin*>* parse_pinyin (const char* preedit_str, guint max_pinyin) parse_pinyin_cpp (const char* preedit_str, const guint max_pinyin) { std::vector<Pinyin*>* result = new std::vector<Pinyin*>(); PyZy::PinyinArray pyar = {0}; Loading @@ -25,3 +25,21 @@ parse_pinyin (const char* preedit_str, guint max_pinyin) } return result; } GList* parse_pinyin (const char* preedit_str, const guint max_pinyin) { GList* result = NULL; PyZy::PinyinArray pyar = {0}; Pinyin* thispy = NULL; PyZy::PinyinParser::parse (preedit_str, strlen(preedit_str), 0, pyar, max_pinyin); for (guint i = 0; i < pyar.size(); ++i) { thispy = g_new (Pinyin, 1); thispy->shengmu_i = (int) pyar[i].pinyin->pinyin_id[0].sheng; thispy->yunmu_i = (int) pyar[i].pinyin->pinyin_id[0].yun; thispy->length = pyar[i].len; result = g_list_append (result, thispy); } return result; }
parse-pinyin.hpp→parse-pinyin.h +31 −0 Original line number Diff line number Diff line #ifndef _PARSE_PINYIN_H_ #define _PARSE_PINYIN_H_ #include <vector> #include <glib.h> #include "zero-pinyin-service.h" #ifdef __cplusplus #include <vector> /** * parse preedit_str to groups of pinyin. * caller should free each Pinyin and the vector after use. */ std::vector<Pinyin*>* parse_pinyin (const char* preedit_str, guint max_pinyin=15); std::vector<Pinyin*>* parse_pinyin_cpp (const char* preedit_str, const guint max_pinyin=15); extern "C" { #endif /** * parse preedit_str to groups of pinyin. * caller should free each Pinyin and the GList after use. */ GList* parse_pinyin (const char* preedit_str, const guint max_pinyin); #ifdef __cplusplus } #endif #endif /* _PARSE_PINYIN_H_ */