Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

follow up librime#806, avoid path-string conversion #310

Merged
merged 3 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions src/modules.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <rime/common.h>
#include <rime/registry.h>
#include <rime_api.h>
#include <rime/service.h>
#include "lib/lua_templates.h"
#include "lua_gears.h"

Expand All @@ -16,9 +17,37 @@ static bool file_exists(const char *fname) noexcept {
return false;
}

namespace {
template<typename> using void_t = void;

template<typename T, typename = void>
struct COMPAT {
static std::string get_shared_data_dir() {
return std::string(rime_get_api()->get_shared_data_dir());
}

static std::string get_user_data_dir() {
return std::string(rime_get_api()->get_user_data_dir());
}
};

template<typename T>
struct COMPAT<T, void_t<decltype(std::declval<T>().user_data_dir.string())>> {
static std::string get_shared_data_dir() {
// path::string() returns native encoding on Windows
return rime::Service::instance().deployer().shared_data_dir.string();
}

static std::string get_user_data_dir() {
return rime::Service::instance().deployer().user_data_dir.string();
}
};
}

static void lua_init(lua_State *L) {
const auto user_dir = std::string(RimeGetUserDataDir());
const auto shared_dir = std::string(RimeGetSharedDataDir());

const auto user_dir = COMPAT<rime::Deployer>::get_user_data_dir();
const auto shared_dir = COMPAT<rime::Deployer>::get_shared_data_dir();

types_init(L);
lua_getglobal(L, "package");
Expand Down
61 changes: 44 additions & 17 deletions src/opencc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#include <opencc/Dict.hpp>
#include <opencc/DictEntry.hpp>
#include <opencc/Common.hpp>
#include <rime_api.h>
#include <rime/common.h>
#include <rime/service.h>

#include "lib/lua_export_type.h"
#include "optional.h"
Expand All @@ -28,8 +28,8 @@ namespace {

class Opencc {
public:
//static shared_ptr<Opencc> create(const string &config_path);
Opencc(const string& config_path);
//static shared_ptr<Opencc> create(const path &config_path);
Opencc(const string& utf8_config_path);
bool ConvertWord(const string& text, vector<string>* forms);
bool RandomConvertText(const string& text, string* simplified);
bool ConvertText(const string& text, string* simplified);
Expand All @@ -43,9 +43,10 @@ class Opencc {
opencc::DictPtr dict_;
};

Opencc::Opencc(const string& config_path) {
Opencc::Opencc(const string& utf8_config_path) {
opencc::Config config;
converter_ = config.NewFromFile(config_path);
// OpenCC accepts UTF-8 encoded path.
converter_ = config.NewFromFile(utf8_config_path);
const list<opencc::ConversionPtr> conversions =
converter_->GetConversionChain()->GetConversions();
dict_ = conversions.front()->GetDict();
Expand Down Expand Up @@ -115,23 +116,49 @@ vector<string> Opencc::convert_word(const string& text){
namespace OpenccReg {
using T = Opencc;

optional<T> make(const string &filename) {
string user_path( RimeGetUserDataDir());
string shared_path(RimeGetSharedDataDir());
try{
return T(user_path + "/opencc/" + filename);
template<typename> using void_t = void;

template<typename U, typename = void>
struct COMPAT {
static optional<T> make(const string &filename) {
auto user_path = string(rime_get_api()->get_user_data_dir());
auto shared_path = string(rime_get_api()->get_shared_data_dir());
try{
return T(user_path + "/opencc/" + filename);
}
catch(...) {
try{
return T(shared_path + "/opencc/" + filename);
}
catch(...) {
LOG(ERROR) << " [" << user_path << "|" << shared_path << "]/opencc/"
<< filename << ": File not found or InvalidFormat";
return {};
}
}
}
catch(...) {
};

template<typename U>
struct COMPAT<U, void_t<decltype(std::declval<U>().user_data_dir.string())>> {
static optional<T> make(const string &filename) {
path user_path = Service::instance().deployer().user_data_dir;
path shared_path = Service::instance().deployer().shared_data_dir;
try{
return T(shared_path + "/opencc/" + filename);
return T((user_path / "opencc" / filename).u8string());
}
catch(...) {
LOG(ERROR) << " [" << user_path << "|" << shared_path << "]/opencc/"
<< filename << ": File not found or InvalidFormat";
return {};
try{
return T((shared_path / "opencc" / filename).u8string());
}
catch(...) {
LOG(ERROR) << " [" << user_path << "|" << shared_path << "]/opencc/"
<< filename << ": File not found or InvalidFormat";
return {};
}
}
}
}
};

optional<vector<string>> convert_word(T &t,const string &s) {
vector<string> res;
Expand All @@ -141,7 +168,7 @@ namespace OpenccReg {
}

static const luaL_Reg funcs[] = {
{"Opencc",WRAP(make)},
{"Opencc",WRAP(COMPAT<Deployer>::make)},
{ NULL, NULL },
};

Expand Down
82 changes: 52 additions & 30 deletions src/types.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <rime_api.h>
#include <rime/candidate.h>
#include <rime/translation.h>
#include <rime/segmentation.h>
Expand All @@ -15,9 +16,9 @@
#include <rime/gear/memory.h>
#include <rime/dict/dictionary.h>
#include <rime/dict/user_dictionary.h>
#include <rime/service.h>
#include <rime/switcher.h>
#include "lua_gears.h"
#include <rime/service.h>
#include <boost/regex.hpp>

#include "lib/lua_export_type.h"
Expand All @@ -29,6 +30,47 @@ using namespace rime;

namespace {

template<typename> using void_t = void;

template<typename T, typename = void>
struct COMPAT {
// fallback version if librime is old
static an<ReverseDb> new_ReverseDb(const std::string &file) {
return New<ReverseDb>(std::string(RimeGetUserDataDir()) + "/" + file);
}

static string get_shared_data_dir() {
return string(rime_get_api()->get_shared_data_dir());
}

static string get_user_data_dir() {
return string(rime_get_api()->get_user_data_dir());
}

static string get_sync_dir() {
return string(rime_get_api()->get_sync_dir());
}
};

template<typename T>
struct COMPAT<T, void_t<decltype(std::declval<T>().user_data_dir.string())>> {
static an<ReverseDb> new_ReverseDb(const std::string &file) {
return New<ReverseDb>(Service::instance().deployer().user_data_dir / file);
}

static string get_shared_data_dir() {
return Service::instance().deployer().shared_data_dir.string();
}

static string get_user_data_dir() {
return Service::instance().deployer().user_data_dir.string();
}

static string get_sync_dir() {
return Service::instance().deployer().sync_dir.string();
}
};

//--- wrappers for Segment
namespace SegmentReg {
using T = Segment;
Expand Down Expand Up @@ -308,7 +350,7 @@ namespace ReverseDbReg {
using T = ReverseDb;

an<T> make(const string &file) {
an<T> db = New<ReverseDb>(string(RimeGetUserDataDir()) + "/" + file);
an<T> db = COMPAT<Deployer>::new_ReverseDb(file);
db->Load();
return db;
}
Expand Down Expand Up @@ -1844,43 +1886,23 @@ namespace KeySequenceReg {

namespace RimeApiReg {
string get_rime_version() {
RimeApi* rime = rime_get_api();
return string(rime->get_version());
}

string get_shared_data_dir() {
RimeApi* rime = rime_get_api();
return string(rime->get_shared_data_dir());
Copy link
Contributor Author

@lotem lotem Feb 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, RimeApi::get_shared_data_dir is deprecated because its inefficiency. Internally it does the same as what the line has changed into, plus assigning the string to a static local variable, then return its c_str(). The C-string is constructed back into another string object in the original code. This string allocation is unnecessary but was needed simply because the original librime API was written in C.

}

string get_user_data_dir() {
RimeApi* rime = rime_get_api();
return string(rime->get_user_data_dir());
}

string get_sync_dir() {
RimeApi* rime = rime_get_api();
return string(rime->get_sync_dir());
return string(rime_get_api()->get_version());
}

string get_distribution_name(){
Deployer &deployer(Service::instance().deployer());
return deployer.distribution_name;
return Service::instance().deployer().distribution_name;
}

string get_distribution_code_name(){
Deployer &deployer(Service::instance().deployer());
return deployer.distribution_code_name;
return Service::instance().deployer().distribution_code_name;
}

string get_distribution_version(){
Deployer &deployer(Service::instance().deployer());
return deployer.distribution_version;
return Service::instance().deployer().distribution_version;
}

string get_user_id(){
Deployer &deployer(Service::instance().deployer());
return deployer.user_id;
return Service::instance().deployer().user_id;
}

// boost::regex api
Expand Down Expand Up @@ -1912,9 +1934,9 @@ namespace RimeApiReg {

static const luaL_Reg funcs[]= {
{ "get_rime_version", WRAP(get_rime_version) },
{ "get_shared_data_dir", WRAP(get_shared_data_dir) },
{ "get_user_data_dir", WRAP(get_user_data_dir) },
{ "get_sync_dir", WRAP(get_sync_dir) },
{ "get_shared_data_dir", WRAP(COMPAT<Deployer>::get_shared_data_dir) },
{ "get_user_data_dir", WRAP(COMPAT<Deployer>::get_user_data_dir) },
{ "get_sync_dir", WRAP(COMPAT<Deployer>::get_sync_dir) },
{ "get_distribution_name", WRAP(get_distribution_name) },
{ "get_distribution_code_name", WRAP(get_distribution_code_name) },
{ "get_distribution_version", WRAP(get_distribution_version) },
Expand Down
19 changes: 18 additions & 1 deletion src/types_ext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ struct COMPAT<T, void_t<decltype(std::declval<T>().name_space())>> {
}
};

// fallback version of file_path() if librime is old
template<typename> struct void_t1 { using t = int; };
template<typename T, typename void_t1<decltype(std::declval<T>().file_name())>::t = 0>
std::string get_UserDb_file_path_string(const T &t) {
return t.file_name();
}

template<typename T, typename void_t1<decltype(std::declval<T>().file_path())>::t = 0>
std::string get_UserDb_file_path_string(const T &t) {
return t.file_path().string();
}

namespace ProcessorReg{
using T = Processor;

Expand Down Expand Up @@ -263,6 +275,11 @@ namespace UserDbReg{
return {};
}

string file_name(const T& t) {
// returns ANSI encoded string on Windows
return t.file_path().string();
}

bool Open(T &t) { return t.Open(); }
bool Close(T &t) { return t.Close(); }
bool OpenReadOnly(T &t) { return t.OpenReadOnly(); }
Expand Down Expand Up @@ -300,7 +317,7 @@ namespace UserDbReg{
{"read_only",WRAPMEM(T, readonly)},
{"disabled",WRAPMEM(T, disabled)},
{"name", WRAPMEM(T, name)},
{"file_name", WRAPMEM(T, file_name)},
{"file_name", WRAP(get_UserDb_file_path_string<T>)},
{ NULL, NULL },
};

Expand Down
Loading