-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
210 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
#include <node_api.h> | ||
#include <rime_api.h> | ||
#include <stdio.h> | ||
|
||
#define DEFAULT_BUFFER_SIZE 1024 | ||
#ifndef __STRING | ||
#define __STRING(x) #x | ||
#endif /* ifndef */ | ||
#define STRING(x) __STRING(x) | ||
#define NODE_API_CALL(env, call) \ | ||
do { \ | ||
napi_status status = (call); \ | ||
if (status != napi_ok) { \ | ||
const napi_extended_error_info *error_info = NULL; \ | ||
napi_get_last_error_info((env), &error_info); \ | ||
const char *err_message = error_info->error_message; \ | ||
bool is_pending; \ | ||
napi_is_exception_pending((env), &is_pending); \ | ||
/* If an exception is already pending, don't rethrow it */ \ | ||
if (!is_pending) { \ | ||
const char *message = \ | ||
(err_message == NULL) ? "empty error message" : err_message; \ | ||
napi_throw_error((env), NULL, message); \ | ||
} \ | ||
return NULL; \ | ||
} \ | ||
} while (0) | ||
#define SET_ARGV(env, argv) \ | ||
do { \ | ||
size_t argc = sizeof(argv) / sizeof((argv)[0]); \ | ||
size_t original_argc = argc; \ | ||
NODE_API_CALL(env, \ | ||
napi_get_cb_info((env), info, &argc, (argv), NULL, NULL)); \ | ||
if (argc < original_argc) { \ | ||
char str[DEFAULT_BUFFER_SIZE]; \ | ||
sprintf(str, "need %zd arguments, only get %zd arguments", \ | ||
original_argc, argc); \ | ||
napi_throw_error((env), NULL, str); \ | ||
return NULL; \ | ||
} \ | ||
} while (0) | ||
#define SET_SESSION_ID(env, value, session_id) \ | ||
do { \ | ||
bool lossless; \ | ||
NODE_API_CALL((env), napi_get_value_bigint_uint64( \ | ||
(env), (value), &(session_id), &lossless)); \ | ||
} while (0); | ||
#define SET_STRING(env, value, str) \ | ||
do { \ | ||
size_t size; \ | ||
NODE_API_CALL((env), \ | ||
napi_get_value_string_utf8((env), (value), (str), \ | ||
DEFAULT_BUFFER_SIZE, &size)); \ | ||
if (size == DEFAULT_BUFFER_SIZE) { \ | ||
napi_throw_error((env), NULL, \ | ||
"path length is longer than buffer size " STRING( \ | ||
DEFAULT_BUFFER_SIZE)); \ | ||
return NULL; \ | ||
} \ | ||
} while (0) | ||
|
||
static napi_value init_rime(napi_env env, napi_callback_info info) { | ||
napi_value result, argv[3]; | ||
char dirs[sizeof(argv) / sizeof(argv[0])][DEFAULT_BUFFER_SIZE]; | ||
SET_ARGV(env, argv); | ||
SET_STRING(env, argv[0], dirs[0]); | ||
SET_STRING(env, argv[1], dirs[1]); | ||
SET_STRING(env, argv[2], dirs[2]); | ||
RIME_STRUCT(RimeTraits, rime_traits); | ||
rime_traits.shared_data_dir = dirs[0]; | ||
rime_traits.user_data_dir = dirs[1]; | ||
rime_traits.log_dir = dirs[2]; | ||
rime_traits.distribution_name = "Rime"; | ||
rime_traits.distribution_code_name = PROJECT_NAME; | ||
rime_traits.distribution_version = PROJECT_VERSION; | ||
rime_traits.app_name = "rime." PROJECT_NAME; | ||
RimeSetup(&rime_traits); | ||
RimeInitialize(&rime_traits); | ||
RimeStartMaintenance(false); | ||
RimeSessionId session_id = RimeCreateSession(); | ||
if (session_id == 0) { | ||
napi_throw_error(env, NULL, "rime cannot create session"); | ||
return NULL; | ||
} | ||
NODE_API_CALL(env, napi_create_bigint_uint64(env, session_id, &result)); | ||
return result; | ||
} | ||
|
||
static napi_value deinit_rime(napi_env env, napi_callback_info info) { | ||
napi_value argv[1]; | ||
RimeSessionId session_id; | ||
SET_ARGV(env, argv); | ||
SET_SESSION_ID(env, argv[0], session_id); | ||
if (!RimeDestroySession(session_id)) { | ||
char str[DEFAULT_BUFFER_SIZE]; | ||
sprintf(str, "cannot destroy session %ld", session_id); | ||
napi_throw_error(env, NULL, str); | ||
} | ||
RimeFinalize(); | ||
return NULL; | ||
} | ||
|
||
static napi_value get_current_schema(napi_env env, napi_callback_info info) { | ||
napi_value schema_id, argv[1]; | ||
RimeSessionId session_id; | ||
char buffer[DEFAULT_BUFFER_SIZE]; | ||
SET_ARGV(env, argv); | ||
SET_SESSION_ID(env, argv[0], session_id); | ||
if (!RimeGetCurrentSchema(session_id, buffer, DEFAULT_BUFFER_SIZE)) { | ||
napi_throw_error(env, NULL, "cannot get current schema"); | ||
return NULL; | ||
} | ||
NODE_API_CALL( | ||
env, napi_create_string_utf8(env, buffer, NAPI_AUTO_LENGTH, &schema_id)); | ||
return schema_id; | ||
} | ||
|
||
static napi_value get_schema_list(napi_env env, napi_callback_info info) { | ||
napi_value result, argv[1]; | ||
RimeSessionId session_id; | ||
RimeSchemaList schema_list; | ||
SET_ARGV(env, argv); | ||
SET_SESSION_ID(env, argv[0], session_id); | ||
if (!RimeGetSchemaList(&schema_list)) { | ||
napi_throw_error(env, NULL, "cannot get schema list"); | ||
return NULL; | ||
} | ||
NODE_API_CALL(env, | ||
napi_create_array_with_length(env, schema_list.size, &result)); | ||
for (size_t i = 0; i < schema_list.size; i++) { | ||
napi_value element, schema_id, name; | ||
RimeSchemaListItem schema_list_item = schema_list.list[i]; | ||
NODE_API_CALL(env, napi_create_object(env, &element)); | ||
NODE_API_CALL(env, napi_create_string_utf8(env, schema_list_item.schema_id, | ||
NAPI_AUTO_LENGTH, &schema_id)); | ||
NODE_API_CALL(env, napi_create_string_utf8(env, schema_list_item.name, | ||
NAPI_AUTO_LENGTH, &name)); | ||
NODE_API_CALL(env, napi_set_element(env, result, i, element)); | ||
NODE_API_CALL(env, | ||
napi_set_named_property(env, result, "schema_id", schema_id)); | ||
NODE_API_CALL(env, napi_set_named_property(env, result, "name", name)); | ||
} | ||
return result; | ||
} | ||
|
||
static napi_value select_schema(napi_env env, napi_callback_info info) { | ||
napi_value argv[2]; | ||
RimeSessionId session_id; | ||
char schema_id[DEFAULT_BUFFER_SIZE]; | ||
SET_ARGV(env, argv); | ||
SET_SESSION_ID(env, argv[0], session_id); | ||
SET_STRING(env, argv[1], schema_id); | ||
if (!RimeSelectSchema(session_id, schema_id)) { | ||
char str[DEFAULT_BUFFER_SIZE]; | ||
sprintf(str, "cannot select schema %s", schema_id); | ||
napi_throw_error(env, NULL, str); | ||
} | ||
return NULL; | ||
} | ||
|
||
static napi_value get_context(napi_env env, napi_callback_info info) { | ||
return NULL; | ||
} | ||
|
||
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) { | ||
char *names[] = {"init_rime", "deinit_rime", "get_current_schema", | ||
"get_schema_list", "select_schema", "get_context"}; | ||
napi_callback callbacks[] = {init_rime, deinit_rime, | ||
get_current_schema, get_schema_list, | ||
select_schema, get_context}; | ||
napi_value functions[sizeof(names) / sizeof(names[0])]; | ||
for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) { | ||
NODE_API_CALL(env, napi_create_function(env, names[i], NAPI_AUTO_LENGTH, | ||
callbacks[i], NULL, &functions[i])); | ||
|
||
NODE_API_CALL( | ||
env, napi_set_named_property(env, exports, names[i], functions[i])); | ||
} | ||
|
||
return exports; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ | |
src = self; | ||
buildInputs = [ | ||
pkg-config | ||
json_c.dev | ||
librime | ||
nodejs | ||
( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { resolve } from 'path'; | ||
import { default as build } from 'node-gyp-build'; | ||
|
||
export default build(resolve(__dirname, '..')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters