Format code style.
This commit is contained in:
parent
a70be3f810
commit
422c73fd1e
|
@ -24,11 +24,10 @@
|
||||||
static ChineseSegmentation *global_instance_chinese_segmentation = nullptr;
|
static ChineseSegmentation *global_instance_chinese_segmentation = nullptr;
|
||||||
QMutex ChineseSegmentation::m_mutex;
|
QMutex ChineseSegmentation::m_mutex;
|
||||||
|
|
||||||
ChineseSegmentation::ChineseSegmentation()
|
ChineseSegmentation::ChineseSegmentation() {
|
||||||
{
|
|
||||||
const char * const DICT_PATH = "/usr/share/ukui-search/res/dict/jieba.dict.utf8";
|
const char * const DICT_PATH = "/usr/share/ukui-search/res/dict/jieba.dict.utf8";
|
||||||
const char * const HMM_PATH = "/usr/share/ukui-search/res/dict/hmm_model.utf8";
|
const char * const HMM_PATH = "/usr/share/ukui-search/res/dict/hmm_model.utf8";
|
||||||
const char * const USER_DICT_PATH ="/usr/share/ukui-search/res/dict/user.dict.utf8";
|
const char * const USER_DICT_PATH = "/usr/share/ukui-search/res/dict/user.dict.utf8";
|
||||||
const char * const IDF_PATH = "/usr/share/ukui-search/res/dict/idf.utf8";
|
const char * const IDF_PATH = "/usr/share/ukui-search/res/dict/idf.utf8";
|
||||||
const char * const STOP_WORD_PATH = "/usr/share/ukui-search/res/dict/stop_words.utf8";
|
const char * const STOP_WORD_PATH = "/usr/share/ukui-search/res/dict/stop_words.utf8";
|
||||||
|
|
||||||
|
@ -39,26 +38,23 @@ ChineseSegmentation::ChineseSegmentation()
|
||||||
STOP_WORD_PATH);
|
STOP_WORD_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChineseSegmentation::~ChineseSegmentation()
|
ChineseSegmentation::~ChineseSegmentation() {
|
||||||
{
|
|
||||||
if(m_jieba)
|
if(m_jieba)
|
||||||
delete m_jieba;
|
delete m_jieba;
|
||||||
m_jieba = nullptr;
|
m_jieba = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChineseSegmentation *ChineseSegmentation::getInstance()
|
ChineseSegmentation *ChineseSegmentation::getInstance() {
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
if (!global_instance_chinese_segmentation) {
|
if(!global_instance_chinese_segmentation) {
|
||||||
global_instance_chinese_segmentation = new ChineseSegmentation;
|
global_instance_chinese_segmentation = new ChineseSegmentation;
|
||||||
}
|
}
|
||||||
return global_instance_chinese_segmentation;
|
return global_instance_chinese_segmentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<SKeyWord> ChineseSegmentation::callSegement(QString str)
|
QVector<SKeyWord> ChineseSegmentation::callSegement(QString str) {
|
||||||
{
|
|
||||||
std::string s;
|
std::string s;
|
||||||
s=str.toStdString();
|
s = str.toStdString();
|
||||||
str.squeeze();
|
str.squeeze();
|
||||||
|
|
||||||
const size_t topk = -1;
|
const size_t topk = -1;
|
||||||
|
@ -76,9 +72,8 @@ QVector<SKeyWord> ChineseSegmentation::callSegement(QString str)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChineseSegmentation::convert(std::vector<cppjieba::KeywordExtractor::Word> &keywordres, QVector<SKeyWord> &kw)
|
void ChineseSegmentation::convert(std::vector<cppjieba::KeywordExtractor::Word> &keywordres, QVector<SKeyWord> &kw) {
|
||||||
{
|
for(auto i : keywordres) {
|
||||||
for (auto i : keywordres){
|
|
||||||
SKeyWord temp;
|
SKeyWord temp;
|
||||||
temp.word = i.word;
|
temp.word = i.word;
|
||||||
temp.offsets = QVector<size_t>::fromStdVector(i.offsets);
|
temp.offsets = QVector<size_t>::fromStdVector(i.offsets);
|
||||||
|
|
|
@ -32,24 +32,23 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
struct SKeyWord{
|
struct SKeyWord {
|
||||||
std::string word;
|
std::string word;
|
||||||
QVector<size_t> offsets;
|
QVector<size_t> offsets;
|
||||||
double weight;
|
double weight;
|
||||||
~SKeyWord(){
|
~SKeyWord() {
|
||||||
word = std::move("");
|
word = std::move("");
|
||||||
offsets.clear();
|
offsets.clear();
|
||||||
offsets.shrink_to_fit();
|
offsets.shrink_to_fit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CHINESESEGMENTATION_EXPORT ChineseSegmentation
|
class CHINESESEGMENTATION_EXPORT ChineseSegmentation {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static ChineseSegmentation *getInstance();
|
static ChineseSegmentation *getInstance();
|
||||||
~ChineseSegmentation();
|
~ChineseSegmentation();
|
||||||
QVector<SKeyWord> callSegement(QString str);
|
QVector<SKeyWord> callSegement(QString str);
|
||||||
void convert(std::vector<cppjieba::KeywordExtractor::Word>& keywordres,QVector<SKeyWord>& kw);
|
void convert(std::vector<cppjieba::KeywordExtractor::Word>& keywordres, QVector<SKeyWord>& kw);
|
||||||
private:
|
private:
|
||||||
static QMutex m_mutex;
|
static QMutex m_mutex;
|
||||||
cppjieba::Jieba *m_jieba;
|
cppjieba::Jieba *m_jieba;
|
||||||
|
|
|
@ -43,252 +43,247 @@ const size_t DICT_COLUMN_NUM = 3;
|
||||||
const char* const UNKNOWN_TAG = "";
|
const char* const UNKNOWN_TAG = "";
|
||||||
|
|
||||||
class DictTrie {
|
class DictTrie {
|
||||||
public:
|
public:
|
||||||
enum UserWordWeightOption {
|
enum UserWordWeightOption {
|
||||||
WordWeightMin,
|
WordWeightMin,
|
||||||
WordWeightMedian,
|
WordWeightMedian,
|
||||||
WordWeightMax,
|
WordWeightMax,
|
||||||
}; // enum UserWordWeightOption
|
}; // enum UserWordWeightOption
|
||||||
|
|
||||||
DictTrie(const string& dict_path, const string& user_dict_paths = "", UserWordWeightOption user_word_weight_opt = WordWeightMedian) {
|
DictTrie(const string& dict_path, const string& user_dict_paths = "", UserWordWeightOption user_word_weight_opt = WordWeightMedian) {
|
||||||
Init(dict_path, user_dict_paths, user_word_weight_opt);
|
Init(dict_path, user_dict_paths, user_word_weight_opt);
|
||||||
}
|
|
||||||
|
|
||||||
~DictTrie() {
|
|
||||||
delete trie_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InsertUserWord(const string& word, const string& tag = UNKNOWN_TAG) {
|
|
||||||
DictUnit node_info;
|
|
||||||
if (!MakeNodeInfo(node_info, word, user_word_default_weight_, tag)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
active_node_infos_.push_back(node_info);
|
|
||||||
trie_->InsertNode(node_info.word, &active_node_infos_.back());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InsertUserWord(const string& word,int freq, const string& tag = UNKNOWN_TAG) {
|
~DictTrie() {
|
||||||
DictUnit node_info;
|
delete trie_;
|
||||||
double weight = freq ? log(1.0 * freq / freq_sum_) : user_word_default_weight_ ;
|
|
||||||
if (!MakeNodeInfo(node_info, word, weight , tag)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
active_node_infos_.push_back(node_info);
|
|
||||||
trie_->InsertNode(node_info.word, &active_node_infos_.back());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DictUnit* Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
bool InsertUserWord(const string& word, const string& tag = UNKNOWN_TAG) {
|
||||||
return trie_->Find(begin, end);
|
DictUnit node_info;
|
||||||
}
|
if(!MakeNodeInfo(node_info, word, user_word_default_weight_, tag)) {
|
||||||
|
return false;
|
||||||
void Find(RuneStrArray::const_iterator begin,
|
}
|
||||||
RuneStrArray::const_iterator end,
|
active_node_infos_.push_back(node_info);
|
||||||
vector<struct Dag>&res,
|
trie_->InsertNode(node_info.word, &active_node_infos_.back());
|
||||||
size_t max_word_len = MAX_WORD_LENGTH) const {
|
return true;
|
||||||
trie_->Find(begin, end, res, max_word_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Find(const string& word)
|
|
||||||
{
|
|
||||||
const DictUnit *tmp = NULL;
|
|
||||||
RuneStrArray runes;
|
|
||||||
if (!DecodeRunesInString(word, runes))
|
|
||||||
{
|
|
||||||
XLOG(ERROR) << "Decode failed.";
|
|
||||||
}
|
}
|
||||||
tmp = Find(runes.begin(), runes.end());
|
|
||||||
if (tmp == NULL)
|
bool InsertUserWord(const string& word, int freq, const string& tag = UNKNOWN_TAG) {
|
||||||
{
|
DictUnit node_info;
|
||||||
return false;
|
double weight = freq ? log(1.0 * freq / freq_sum_) : user_word_default_weight_ ;
|
||||||
|
if(!MakeNodeInfo(node_info, word, weight, tag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
active_node_infos_.push_back(node_info);
|
||||||
|
trie_->InsertNode(node_info.word, &active_node_infos_.back());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
const DictUnit* Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
||||||
return true;
|
return trie_->Find(begin, end);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUserDictSingleChineseWord(const Rune& word) const {
|
void Find(RuneStrArray::const_iterator begin,
|
||||||
return IsIn(user_dict_single_chinese_word_, word);
|
RuneStrArray::const_iterator end,
|
||||||
}
|
vector<struct Dag>&res,
|
||||||
|
size_t max_word_len = MAX_WORD_LENGTH) const {
|
||||||
|
trie_->Find(begin, end, res, max_word_len);
|
||||||
|
}
|
||||||
|
|
||||||
double GetMinWeight() const {
|
bool Find(const string& word) {
|
||||||
return min_weight_;
|
const DictUnit *tmp = NULL;
|
||||||
}
|
RuneStrArray runes;
|
||||||
|
if(!DecodeRunesInString(word, runes)) {
|
||||||
|
XLOG(ERROR) << "Decode failed.";
|
||||||
|
}
|
||||||
|
tmp = Find(runes.begin(), runes.end());
|
||||||
|
if(tmp == NULL) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InserUserDictNode(const string& line) {
|
bool IsUserDictSingleChineseWord(const Rune& word) const {
|
||||||
vector<string> buf;
|
return IsIn(user_dict_single_chinese_word_, word);
|
||||||
DictUnit node_info;
|
}
|
||||||
Split(line, buf, " ");
|
|
||||||
if(buf.size() == 1){
|
double GetMinWeight() const {
|
||||||
MakeNodeInfo(node_info,
|
return min_weight_;
|
||||||
buf[0],
|
}
|
||||||
user_word_default_weight_,
|
|
||||||
UNKNOWN_TAG);
|
void InserUserDictNode(const string& line) {
|
||||||
} else if (buf.size() == 2) {
|
vector<string> buf;
|
||||||
MakeNodeInfo(node_info,
|
DictUnit node_info;
|
||||||
buf[0],
|
Split(line, buf, " ");
|
||||||
user_word_default_weight_,
|
if(buf.size() == 1) {
|
||||||
buf[1]);
|
MakeNodeInfo(node_info,
|
||||||
} else if (buf.size() == 3) {
|
buf[0],
|
||||||
int freq = atoi(buf[1].c_str());
|
user_word_default_weight_,
|
||||||
assert(freq_sum_ > 0.0);
|
UNKNOWN_TAG);
|
||||||
double weight = log(1.0 * freq / freq_sum_);
|
} else if(buf.size() == 2) {
|
||||||
MakeNodeInfo(node_info, buf[0], weight, buf[2]);
|
MakeNodeInfo(node_info,
|
||||||
|
buf[0],
|
||||||
|
user_word_default_weight_,
|
||||||
|
buf[1]);
|
||||||
|
} else if(buf.size() == 3) {
|
||||||
|
int freq = atoi(buf[1].c_str());
|
||||||
|
assert(freq_sum_ > 0.0);
|
||||||
|
double weight = log(1.0 * freq / freq_sum_);
|
||||||
|
MakeNodeInfo(node_info, buf[0], weight, buf[2]);
|
||||||
}
|
}
|
||||||
static_node_infos_.push_back(node_info);
|
static_node_infos_.push_back(node_info);
|
||||||
if (node_info.word.size() == 1) {
|
if(node_info.word.size() == 1) {
|
||||||
user_dict_single_chinese_word_.insert(node_info.word[0]);
|
user_dict_single_chinese_word_.insert(node_info.word[0]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void LoadUserDict(const vector<string>& buf) {
|
|
||||||
for (size_t i = 0; i < buf.size(); i++) {
|
|
||||||
InserUserDictNode(buf[i]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void LoadUserDict(const set<string>& buf) {
|
void LoadUserDict(const vector<string>& buf) {
|
||||||
std::set<string>::const_iterator iter;
|
for(size_t i = 0; i < buf.size(); i++) {
|
||||||
for (iter = buf.begin(); iter != buf.end(); iter++){
|
InserUserDictNode(buf[i]);
|
||||||
InserUserDictNode(*iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadUserDict(const string& filePaths) {
|
|
||||||
vector<string> files = limonp::Split(filePaths, "|;");
|
|
||||||
size_t lineno = 0;
|
|
||||||
for (size_t i = 0; i < files.size(); i++) {
|
|
||||||
ifstream ifs(files[i].c_str());
|
|
||||||
XCHECK(ifs.is_open()) << "open " << files[i] << " failed";
|
|
||||||
string line;
|
|
||||||
|
|
||||||
for (; getline(ifs, line); lineno++) {
|
|
||||||
if (line.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
InserUserDictNode(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Init(const string& dict_path, const string& user_dict_paths, UserWordWeightOption user_word_weight_opt) {
|
|
||||||
LoadDict(dict_path);
|
|
||||||
freq_sum_ = CalcFreqSum(static_node_infos_);
|
|
||||||
CalculateWeight(static_node_infos_, freq_sum_);
|
|
||||||
SetStaticWordWeights(user_word_weight_opt);
|
|
||||||
|
|
||||||
if (user_dict_paths.size()) {
|
|
||||||
LoadUserDict(user_dict_paths);
|
|
||||||
}
|
|
||||||
Shrink(static_node_infos_);
|
|
||||||
CreateTrie(static_node_infos_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateTrie(const vector<DictUnit>& dictUnits) {
|
|
||||||
assert(dictUnits.size());
|
|
||||||
vector<Unicode> words;
|
|
||||||
vector<const DictUnit*> valuePointers;
|
|
||||||
for (size_t i = 0 ; i < dictUnits.size(); i ++) {
|
|
||||||
words.push_back(dictUnits[i].word);
|
|
||||||
valuePointers.push_back(&dictUnits[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trie_ = new Trie(words, valuePointers);
|
void LoadUserDict(const set<string>& buf) {
|
||||||
}
|
std::set<string>::const_iterator iter;
|
||||||
|
for(iter = buf.begin(); iter != buf.end(); iter++) {
|
||||||
|
InserUserDictNode(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
bool MakeNodeInfo(DictUnit& node_info,
|
|
||||||
const string& word,
|
|
||||||
double weight,
|
|
||||||
const string& tag) {
|
|
||||||
if (!DecodeRunesInString(word, node_info.word)) {
|
|
||||||
XLOG(ERROR) << "Decode " << word << " failed.";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
node_info.weight = weight;
|
|
||||||
node_info.tag = tag;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadDict(const string& filePath) {
|
void LoadUserDict(const string& filePaths) {
|
||||||
ifstream ifs(filePath.c_str());
|
vector<string> files = limonp::Split(filePaths, "|;");
|
||||||
XCHECK(ifs.is_open()) << "open " << filePath << " failed.";
|
size_t lineno = 0;
|
||||||
string line;
|
for(size_t i = 0; i < files.size(); i++) {
|
||||||
vector<string> buf;
|
ifstream ifs(files[i].c_str());
|
||||||
|
XCHECK(ifs.is_open()) << "open " << files[i] << " failed";
|
||||||
|
string line;
|
||||||
|
|
||||||
DictUnit node_info;
|
for(; getline(ifs, line); lineno++) {
|
||||||
for (size_t lineno = 0; getline(ifs, line); lineno++) {
|
if(line.size() == 0) {
|
||||||
Split(line, buf, " ");
|
continue;
|
||||||
XCHECK(buf.size() == DICT_COLUMN_NUM) << "split result illegal, line:" << line;
|
}
|
||||||
MakeNodeInfo(node_info,
|
InserUserDictNode(line);
|
||||||
buf[0],
|
}
|
||||||
atof(buf[1].c_str()),
|
}
|
||||||
buf[2]);
|
|
||||||
static_node_infos_.push_back(node_info);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static bool WeightCompare(const DictUnit& lhs, const DictUnit& rhs) {
|
|
||||||
return lhs.weight < rhs.weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetStaticWordWeights(UserWordWeightOption option) {
|
private:
|
||||||
XCHECK(!static_node_infos_.empty());
|
void Init(const string& dict_path, const string& user_dict_paths, UserWordWeightOption user_word_weight_opt) {
|
||||||
vector<DictUnit> x = static_node_infos_;
|
LoadDict(dict_path);
|
||||||
sort(x.begin(), x.end(), WeightCompare);
|
freq_sum_ = CalcFreqSum(static_node_infos_);
|
||||||
min_weight_ = x[0].weight;
|
CalculateWeight(static_node_infos_, freq_sum_);
|
||||||
max_weight_ = x[x.size() - 1].weight;
|
SetStaticWordWeights(user_word_weight_opt);
|
||||||
median_weight_ = x[x.size() / 2].weight;
|
|
||||||
switch (option) {
|
if(user_dict_paths.size()) {
|
||||||
case WordWeightMin:
|
LoadUserDict(user_dict_paths);
|
||||||
user_word_default_weight_ = min_weight_;
|
}
|
||||||
break;
|
Shrink(static_node_infos_);
|
||||||
case WordWeightMedian:
|
CreateTrie(static_node_infos_);
|
||||||
user_word_default_weight_ = median_weight_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
user_word_default_weight_ = max_weight_;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
double CalcFreqSum(const vector<DictUnit>& node_infos) const {
|
void CreateTrie(const vector<DictUnit>& dictUnits) {
|
||||||
double sum = 0.0;
|
assert(dictUnits.size());
|
||||||
for (size_t i = 0; i < node_infos.size(); i++) {
|
vector<Unicode> words;
|
||||||
sum += node_infos[i].weight;
|
vector<const DictUnit*> valuePointers;
|
||||||
|
for(size_t i = 0 ; i < dictUnits.size(); i ++) {
|
||||||
|
words.push_back(dictUnits[i].word);
|
||||||
|
valuePointers.push_back(&dictUnits[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
trie_ = new Trie(words, valuePointers);
|
||||||
}
|
}
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CalculateWeight(vector<DictUnit>& node_infos, double sum) const {
|
|
||||||
assert(sum > 0.0);
|
|
||||||
for (size_t i = 0; i < node_infos.size(); i++) {
|
|
||||||
DictUnit& node_info = node_infos[i];
|
bool MakeNodeInfo(DictUnit& node_info,
|
||||||
assert(node_info.weight > 0.0);
|
const string& word,
|
||||||
node_info.weight = log(double(node_info.weight)/sum);
|
double weight,
|
||||||
|
const string& tag) {
|
||||||
|
if(!DecodeRunesInString(word, node_info.word)) {
|
||||||
|
XLOG(ERROR) << "Decode " << word << " failed.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node_info.weight = weight;
|
||||||
|
node_info.tag = tag;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Shrink(vector<DictUnit>& units) const {
|
void LoadDict(const string& filePath) {
|
||||||
vector<DictUnit>(units.begin(), units.end()).swap(units);
|
ifstream ifs(filePath.c_str());
|
||||||
}
|
XCHECK(ifs.is_open()) << "open " << filePath << " failed.";
|
||||||
|
string line;
|
||||||
|
vector<string> buf;
|
||||||
|
|
||||||
vector<DictUnit> static_node_infos_;
|
DictUnit node_info;
|
||||||
deque<DictUnit> active_node_infos_; // must not be vector
|
for(size_t lineno = 0; getline(ifs, line); lineno++) {
|
||||||
Trie * trie_;
|
Split(line, buf, " ");
|
||||||
|
XCHECK(buf.size() == DICT_COLUMN_NUM) << "split result illegal, line:" << line;
|
||||||
|
MakeNodeInfo(node_info,
|
||||||
|
buf[0],
|
||||||
|
atof(buf[1].c_str()),
|
||||||
|
buf[2]);
|
||||||
|
static_node_infos_.push_back(node_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double freq_sum_;
|
static bool WeightCompare(const DictUnit& lhs, const DictUnit& rhs) {
|
||||||
double min_weight_;
|
return lhs.weight < rhs.weight;
|
||||||
double max_weight_;
|
}
|
||||||
double median_weight_;
|
|
||||||
double user_word_default_weight_;
|
void SetStaticWordWeights(UserWordWeightOption option) {
|
||||||
unordered_set<Rune> user_dict_single_chinese_word_;
|
XCHECK(!static_node_infos_.empty());
|
||||||
|
vector<DictUnit> x = static_node_infos_;
|
||||||
|
sort(x.begin(), x.end(), WeightCompare);
|
||||||
|
min_weight_ = x[0].weight;
|
||||||
|
max_weight_ = x[x.size() - 1].weight;
|
||||||
|
median_weight_ = x[x.size() / 2].weight;
|
||||||
|
switch(option) {
|
||||||
|
case WordWeightMin:
|
||||||
|
user_word_default_weight_ = min_weight_;
|
||||||
|
break;
|
||||||
|
case WordWeightMedian:
|
||||||
|
user_word_default_weight_ = median_weight_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
user_word_default_weight_ = max_weight_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double CalcFreqSum(const vector<DictUnit>& node_infos) const {
|
||||||
|
double sum = 0.0;
|
||||||
|
for(size_t i = 0; i < node_infos.size(); i++) {
|
||||||
|
sum += node_infos[i].weight;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalculateWeight(vector<DictUnit>& node_infos, double sum) const {
|
||||||
|
assert(sum > 0.0);
|
||||||
|
for(size_t i = 0; i < node_infos.size(); i++) {
|
||||||
|
DictUnit& node_info = node_infos[i];
|
||||||
|
assert(node_info.weight > 0.0);
|
||||||
|
node_info.weight = log(double(node_info.weight) / sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shrink(vector<DictUnit>& units) const {
|
||||||
|
vector<DictUnit>(units.begin(), units.end()).swap(units);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<DictUnit> static_node_infos_;
|
||||||
|
deque<DictUnit> active_node_infos_; // must not be vector
|
||||||
|
Trie * trie_;
|
||||||
|
|
||||||
|
double freq_sum_;
|
||||||
|
double min_weight_;
|
||||||
|
double max_weight_;
|
||||||
|
double median_weight_;
|
||||||
|
double user_word_default_weight_;
|
||||||
|
unordered_set<Rune> user_dict_single_chinese_word_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,82 +29,82 @@
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
class FullSegment: public SegmentBase {
|
class FullSegment: public SegmentBase {
|
||||||
public:
|
public:
|
||||||
FullSegment(const string& dictPath) {
|
FullSegment(const string& dictPath) {
|
||||||
dictTrie_ = new DictTrie(dictPath);
|
dictTrie_ = new DictTrie(dictPath);
|
||||||
isNeedDestroy_ = true;
|
isNeedDestroy_ = true;
|
||||||
}
|
|
||||||
FullSegment(const DictTrie* dictTrie)
|
|
||||||
: dictTrie_(dictTrie), isNeedDestroy_(false) {
|
|
||||||
assert(dictTrie_);
|
|
||||||
}
|
|
||||||
~FullSegment() {
|
|
||||||
if (isNeedDestroy_) {
|
|
||||||
delete dictTrie_;
|
|
||||||
}
|
}
|
||||||
}
|
FullSegment(const DictTrie* dictTrie)
|
||||||
void Cut(const string& sentence,
|
: dictTrie_(dictTrie), isNeedDestroy_(false) {
|
||||||
vector<string>& words) const {
|
assert(dictTrie_);
|
||||||
vector<Word> tmp;
|
|
||||||
Cut(sentence, tmp);
|
|
||||||
GetStringsFromWords(tmp, words);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence,
|
|
||||||
vector<Word>& words) const {
|
|
||||||
PreFilter pre_filter(symbols_, sentence);
|
|
||||||
PreFilter::Range range;
|
|
||||||
vector<WordRange> wrs;
|
|
||||||
wrs.reserve(sentence.size()/2);
|
|
||||||
while (pre_filter.HasNext()) {
|
|
||||||
range = pre_filter.Next();
|
|
||||||
Cut(range.begin, range.end, wrs);
|
|
||||||
}
|
}
|
||||||
words.clear();
|
~FullSegment() {
|
||||||
words.reserve(wrs.size());
|
if(isNeedDestroy_) {
|
||||||
GetWordsFromWordRanges(sentence, wrs, words);
|
delete dictTrie_;
|
||||||
}
|
|
||||||
void Cut(RuneStrArray::const_iterator begin,
|
|
||||||
RuneStrArray::const_iterator end,
|
|
||||||
vector<WordRange>& res) const {
|
|
||||||
// result of searching in trie tree
|
|
||||||
LocalVector<pair<size_t, const DictUnit*> > tRes;
|
|
||||||
|
|
||||||
// max index of res's words
|
|
||||||
size_t maxIdx = 0;
|
|
||||||
|
|
||||||
// always equals to (uItr - begin)
|
|
||||||
size_t uIdx = 0;
|
|
||||||
|
|
||||||
// tmp variables
|
|
||||||
size_t wordLen = 0;
|
|
||||||
assert(dictTrie_);
|
|
||||||
vector<struct Dag> dags;
|
|
||||||
dictTrie_->Find(begin, end, dags);
|
|
||||||
for (size_t i = 0; i < dags.size(); i++) {
|
|
||||||
for (size_t j = 0; j < dags[i].nexts.size(); j++) {
|
|
||||||
size_t nextoffset = dags[i].nexts[j].first;
|
|
||||||
assert(nextoffset < dags.size());
|
|
||||||
const DictUnit* du = dags[i].nexts[j].second;
|
|
||||||
if (du == NULL) {
|
|
||||||
if (dags[i].nexts.size() == 1 && maxIdx <= uIdx) {
|
|
||||||
WordRange wr(begin + i, begin + nextoffset);
|
|
||||||
res.push_back(wr);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wordLen = du->word.size();
|
|
||||||
if (wordLen >= 2 || (dags[i].nexts.size() == 1 && maxIdx <= uIdx)) {
|
|
||||||
WordRange wr(begin + i, begin + nextoffset);
|
|
||||||
res.push_back(wr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
maxIdx = uIdx + wordLen > maxIdx ? uIdx + wordLen : maxIdx;
|
|
||||||
}
|
|
||||||
uIdx++;
|
|
||||||
}
|
}
|
||||||
}
|
void Cut(const string& sentence,
|
||||||
private:
|
vector<string>& words) const {
|
||||||
const DictTrie* dictTrie_;
|
vector<Word> tmp;
|
||||||
bool isNeedDestroy_;
|
Cut(sentence, tmp);
|
||||||
|
GetStringsFromWords(tmp, words);
|
||||||
|
}
|
||||||
|
void Cut(const string& sentence,
|
||||||
|
vector<Word>& words) const {
|
||||||
|
PreFilter pre_filter(symbols_, sentence);
|
||||||
|
PreFilter::Range range;
|
||||||
|
vector<WordRange> wrs;
|
||||||
|
wrs.reserve(sentence.size() / 2);
|
||||||
|
while(pre_filter.HasNext()) {
|
||||||
|
range = pre_filter.Next();
|
||||||
|
Cut(range.begin, range.end, wrs);
|
||||||
|
}
|
||||||
|
words.clear();
|
||||||
|
words.reserve(wrs.size());
|
||||||
|
GetWordsFromWordRanges(sentence, wrs, words);
|
||||||
|
}
|
||||||
|
void Cut(RuneStrArray::const_iterator begin,
|
||||||
|
RuneStrArray::const_iterator end,
|
||||||
|
vector<WordRange>& res) const {
|
||||||
|
// result of searching in trie tree
|
||||||
|
LocalVector<pair<size_t, const DictUnit*> > tRes;
|
||||||
|
|
||||||
|
// max index of res's words
|
||||||
|
size_t maxIdx = 0;
|
||||||
|
|
||||||
|
// always equals to (uItr - begin)
|
||||||
|
size_t uIdx = 0;
|
||||||
|
|
||||||
|
// tmp variables
|
||||||
|
size_t wordLen = 0;
|
||||||
|
assert(dictTrie_);
|
||||||
|
vector<struct Dag> dags;
|
||||||
|
dictTrie_->Find(begin, end, dags);
|
||||||
|
for(size_t i = 0; i < dags.size(); i++) {
|
||||||
|
for(size_t j = 0; j < dags[i].nexts.size(); j++) {
|
||||||
|
size_t nextoffset = dags[i].nexts[j].first;
|
||||||
|
assert(nextoffset < dags.size());
|
||||||
|
const DictUnit* du = dags[i].nexts[j].second;
|
||||||
|
if(du == NULL) {
|
||||||
|
if(dags[i].nexts.size() == 1 && maxIdx <= uIdx) {
|
||||||
|
WordRange wr(begin + i, begin + nextoffset);
|
||||||
|
res.push_back(wr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wordLen = du->word.size();
|
||||||
|
if(wordLen >= 2 || (dags[i].nexts.size() == 1 && maxIdx <= uIdx)) {
|
||||||
|
WordRange wr(begin + i, begin + nextoffset);
|
||||||
|
res.push_back(wr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maxIdx = uIdx + wordLen > maxIdx ? uIdx + wordLen : maxIdx;
|
||||||
|
}
|
||||||
|
uIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const DictTrie* dictTrie_;
|
||||||
|
bool isNeedDestroy_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,118 +28,118 @@ using namespace limonp;
|
||||||
typedef unordered_map<Rune, double> EmitProbMap;
|
typedef unordered_map<Rune, double> EmitProbMap;
|
||||||
|
|
||||||
struct HMMModel {
|
struct HMMModel {
|
||||||
/*
|
/*
|
||||||
* STATUS:
|
* STATUS:
|
||||||
* 0: HMMModel::B, 1: HMMModel::E, 2: HMMModel::M, 3:HMMModel::S
|
* 0: HMMModel::B, 1: HMMModel::E, 2: HMMModel::M, 3:HMMModel::S
|
||||||
* */
|
* */
|
||||||
enum {B = 0, E = 1, M = 2, S = 3, STATUS_SUM = 4};
|
enum {B = 0, E = 1, M = 2, S = 3, STATUS_SUM = 4};
|
||||||
|
|
||||||
HMMModel(const string& modelPath) {
|
HMMModel(const string& modelPath) {
|
||||||
memset(startProb, 0, sizeof(startProb));
|
memset(startProb, 0, sizeof(startProb));
|
||||||
memset(transProb, 0, sizeof(transProb));
|
memset(transProb, 0, sizeof(transProb));
|
||||||
statMap[0] = 'B';
|
statMap[0] = 'B';
|
||||||
statMap[1] = 'E';
|
statMap[1] = 'E';
|
||||||
statMap[2] = 'M';
|
statMap[2] = 'M';
|
||||||
statMap[3] = 'S';
|
statMap[3] = 'S';
|
||||||
emitProbVec.push_back(&emitProbB);
|
emitProbVec.push_back(&emitProbB);
|
||||||
emitProbVec.push_back(&emitProbE);
|
emitProbVec.push_back(&emitProbE);
|
||||||
emitProbVec.push_back(&emitProbM);
|
emitProbVec.push_back(&emitProbM);
|
||||||
emitProbVec.push_back(&emitProbS);
|
emitProbVec.push_back(&emitProbS);
|
||||||
LoadModel(modelPath);
|
LoadModel(modelPath);
|
||||||
}
|
|
||||||
~HMMModel() {
|
|
||||||
}
|
|
||||||
void LoadModel(const string& filePath) {
|
|
||||||
ifstream ifile(filePath.c_str());
|
|
||||||
XCHECK(ifile.is_open()) << "open " << filePath << " failed";
|
|
||||||
string line;
|
|
||||||
vector<string> tmp;
|
|
||||||
vector<string> tmp2;
|
|
||||||
//Load startProb
|
|
||||||
XCHECK(GetLine(ifile, line));
|
|
||||||
Split(line, tmp, " ");
|
|
||||||
XCHECK(tmp.size() == STATUS_SUM);
|
|
||||||
for (size_t j = 0; j< tmp.size(); j++) {
|
|
||||||
startProb[j] = atof(tmp[j].c_str());
|
|
||||||
}
|
}
|
||||||
|
~HMMModel() {
|
||||||
//Load transProb
|
|
||||||
for (size_t i = 0; i < STATUS_SUM; i++) {
|
|
||||||
XCHECK(GetLine(ifile, line));
|
|
||||||
Split(line, tmp, " ");
|
|
||||||
XCHECK(tmp.size() == STATUS_SUM);
|
|
||||||
for (size_t j =0; j < STATUS_SUM; j++) {
|
|
||||||
transProb[i][j] = atof(tmp[j].c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
void LoadModel(const string& filePath) {
|
||||||
|
ifstream ifile(filePath.c_str());
|
||||||
|
XCHECK(ifile.is_open()) << "open " << filePath << " failed";
|
||||||
|
string line;
|
||||||
|
vector<string> tmp;
|
||||||
|
vector<string> tmp2;
|
||||||
|
//Load startProb
|
||||||
|
XCHECK(GetLine(ifile, line));
|
||||||
|
Split(line, tmp, " ");
|
||||||
|
XCHECK(tmp.size() == STATUS_SUM);
|
||||||
|
for(size_t j = 0; j < tmp.size(); j++) {
|
||||||
|
startProb[j] = atof(tmp[j].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//Load emitProbB
|
//Load transProb
|
||||||
XCHECK(GetLine(ifile, line));
|
for(size_t i = 0; i < STATUS_SUM; i++) {
|
||||||
XCHECK(LoadEmitProb(line, emitProbB));
|
XCHECK(GetLine(ifile, line));
|
||||||
|
Split(line, tmp, " ");
|
||||||
|
XCHECK(tmp.size() == STATUS_SUM);
|
||||||
|
for(size_t j = 0; j < STATUS_SUM; j++) {
|
||||||
|
transProb[i][j] = atof(tmp[j].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Load emitProbE
|
//Load emitProbB
|
||||||
XCHECK(GetLine(ifile, line));
|
XCHECK(GetLine(ifile, line));
|
||||||
XCHECK(LoadEmitProb(line, emitProbE));
|
XCHECK(LoadEmitProb(line, emitProbB));
|
||||||
|
|
||||||
//Load emitProbM
|
//Load emitProbE
|
||||||
XCHECK(GetLine(ifile, line));
|
XCHECK(GetLine(ifile, line));
|
||||||
XCHECK(LoadEmitProb(line, emitProbM));
|
XCHECK(LoadEmitProb(line, emitProbE));
|
||||||
|
|
||||||
//Load emitProbS
|
//Load emitProbM
|
||||||
XCHECK(GetLine(ifile, line));
|
XCHECK(GetLine(ifile, line));
|
||||||
XCHECK(LoadEmitProb(line, emitProbS));
|
XCHECK(LoadEmitProb(line, emitProbM));
|
||||||
}
|
|
||||||
double GetEmitProb(const EmitProbMap* ptMp, Rune key,
|
//Load emitProbS
|
||||||
double defVal)const {
|
XCHECK(GetLine(ifile, line));
|
||||||
EmitProbMap::const_iterator cit = ptMp->find(key);
|
XCHECK(LoadEmitProb(line, emitProbS));
|
||||||
if (cit == ptMp->end()) {
|
|
||||||
return defVal;
|
|
||||||
}
|
}
|
||||||
return cit->second;
|
double GetEmitProb(const EmitProbMap* ptMp, Rune key,
|
||||||
}
|
double defVal)const {
|
||||||
bool GetLine(ifstream& ifile, string& line) {
|
EmitProbMap::const_iterator cit = ptMp->find(key);
|
||||||
while (getline(ifile, line)) {
|
if(cit == ptMp->end()) {
|
||||||
Trim(line);
|
return defVal;
|
||||||
if (line.empty()) {
|
}
|
||||||
continue;
|
return cit->second;
|
||||||
}
|
|
||||||
if (StartsWith(line, "#")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
bool GetLine(ifstream& ifile, string& line) {
|
||||||
}
|
while(getline(ifile, line)) {
|
||||||
bool LoadEmitProb(const string& line, EmitProbMap& mp) {
|
Trim(line);
|
||||||
if (line.empty()) {
|
if(line.empty()) {
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
vector<string> tmp, tmp2;
|
if(StartsWith(line, "#")) {
|
||||||
Unicode unicode;
|
continue;
|
||||||
Split(line, tmp, ",");
|
}
|
||||||
for (size_t i = 0; i < tmp.size(); i++) {
|
return true;
|
||||||
Split(tmp[i], tmp2, ":");
|
}
|
||||||
if (2 != tmp2.size()) {
|
|
||||||
XLOG(ERROR) << "emitProb illegal.";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
if (!DecodeRunesInString(tmp2[0], unicode) || unicode.size() != 1) {
|
|
||||||
XLOG(ERROR) << "TransCode failed.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mp[unicode[0]] = atof(tmp2[1].c_str());
|
|
||||||
}
|
}
|
||||||
return true;
|
bool LoadEmitProb(const string& line, EmitProbMap& mp) {
|
||||||
}
|
if(line.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vector<string> tmp, tmp2;
|
||||||
|
Unicode unicode;
|
||||||
|
Split(line, tmp, ",");
|
||||||
|
for(size_t i = 0; i < tmp.size(); i++) {
|
||||||
|
Split(tmp[i], tmp2, ":");
|
||||||
|
if(2 != tmp2.size()) {
|
||||||
|
XLOG(ERROR) << "emitProb illegal.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!DecodeRunesInString(tmp2[0], unicode) || unicode.size() != 1) {
|
||||||
|
XLOG(ERROR) << "TransCode failed.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mp[unicode[0]] = atof(tmp2[1].c_str());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
char statMap[STATUS_SUM];
|
char statMap[STATUS_SUM];
|
||||||
double startProb[STATUS_SUM];
|
double startProb[STATUS_SUM];
|
||||||
double transProb[STATUS_SUM][STATUS_SUM];
|
double transProb[STATUS_SUM][STATUS_SUM];
|
||||||
EmitProbMap emitProbB;
|
EmitProbMap emitProbB;
|
||||||
EmitProbMap emitProbE;
|
EmitProbMap emitProbE;
|
||||||
EmitProbMap emitProbM;
|
EmitProbMap emitProbM;
|
||||||
EmitProbMap emitProbS;
|
EmitProbMap emitProbS;
|
||||||
vector<EmitProbMap* > emitProbVec;
|
vector<EmitProbMap* > emitProbVec;
|
||||||
}; // struct HMMModel
|
}; // struct HMMModel
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -28,179 +28,179 @@
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
class HMMSegment: public SegmentBase {
|
class HMMSegment: public SegmentBase {
|
||||||
public:
|
public:
|
||||||
HMMSegment(const string& filePath)
|
HMMSegment(const string& filePath)
|
||||||
: model_(new HMMModel(filePath)), isNeedDestroy_(true) {
|
: model_(new HMMModel(filePath)), isNeedDestroy_(true) {
|
||||||
}
|
|
||||||
HMMSegment(const HMMModel* model)
|
|
||||||
: model_(model), isNeedDestroy_(false) {
|
|
||||||
}
|
|
||||||
~HMMSegment() {
|
|
||||||
if (isNeedDestroy_) {
|
|
||||||
delete model_;
|
|
||||||
}
|
}
|
||||||
}
|
HMMSegment(const HMMModel* model)
|
||||||
|
: model_(model), isNeedDestroy_(false) {
|
||||||
void Cut(const string& sentence,
|
|
||||||
vector<string>& words) const {
|
|
||||||
vector<Word> tmp;
|
|
||||||
Cut(sentence, tmp);
|
|
||||||
GetStringsFromWords(tmp, words);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence,
|
|
||||||
vector<Word>& words) const {
|
|
||||||
PreFilter pre_filter(symbols_, sentence);
|
|
||||||
PreFilter::Range range;
|
|
||||||
vector<WordRange> wrs;
|
|
||||||
wrs.reserve(sentence.size()/2);
|
|
||||||
while (pre_filter.HasNext()) {
|
|
||||||
range = pre_filter.Next();
|
|
||||||
Cut(range.begin, range.end, wrs);
|
|
||||||
}
|
}
|
||||||
words.clear();
|
~HMMSegment() {
|
||||||
words.reserve(wrs.size());
|
if(isNeedDestroy_) {
|
||||||
GetWordsFromWordRanges(sentence, wrs, words);
|
delete model_;
|
||||||
}
|
|
||||||
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res) const {
|
|
||||||
RuneStrArray::const_iterator left = begin;
|
|
||||||
RuneStrArray::const_iterator right = begin;
|
|
||||||
while (right != end) {
|
|
||||||
if (right->rune < 0x80) {
|
|
||||||
if (left != right) {
|
|
||||||
InternalCut(left, right, res);
|
|
||||||
}
|
}
|
||||||
left = right;
|
|
||||||
do {
|
|
||||||
right = SequentialLetterRule(left, end);
|
|
||||||
if (right != left) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
right = NumbersRule(left, end);
|
|
||||||
if (right != left) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
right ++;
|
|
||||||
} while (false);
|
|
||||||
WordRange wr(left, right - 1);
|
|
||||||
res.push_back(wr);
|
|
||||||
left = right;
|
|
||||||
} else {
|
|
||||||
right++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left != right) {
|
|
||||||
InternalCut(left, right, res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
// sequential letters rule
|
|
||||||
RuneStrArray::const_iterator SequentialLetterRule(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
|
||||||
Rune x = begin->rune;
|
|
||||||
if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) {
|
|
||||||
begin ++;
|
|
||||||
} else {
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
while (begin != end) {
|
|
||||||
x = begin->rune;
|
|
||||||
if (('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z') || ('0' <= x && x <= '9')) {
|
|
||||||
begin ++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
RuneStrArray::const_iterator NumbersRule(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
|
||||||
Rune x = begin->rune;
|
|
||||||
if ('0' <= x && x <= '9') {
|
|
||||||
begin ++;
|
|
||||||
} else {
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
while (begin != end) {
|
|
||||||
x = begin->rune;
|
|
||||||
if ( ('0' <= x && x <= '9') || x == '.') {
|
|
||||||
begin++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
void InternalCut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res) const {
|
|
||||||
vector<size_t> status;
|
|
||||||
Viterbi(begin, end, status);
|
|
||||||
|
|
||||||
RuneStrArray::const_iterator left = begin;
|
|
||||||
RuneStrArray::const_iterator right;
|
|
||||||
for (size_t i = 0; i < status.size(); i++) {
|
|
||||||
if (status[i] % 2) { //if (HMMModel::E == status[i] || HMMModel::S == status[i])
|
|
||||||
right = begin + i + 1;
|
|
||||||
WordRange wr(left, right - 1);
|
|
||||||
res.push_back(wr);
|
|
||||||
left = right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viterbi(RuneStrArray::const_iterator begin,
|
|
||||||
RuneStrArray::const_iterator end,
|
|
||||||
vector<size_t>& status) const {
|
|
||||||
size_t Y = HMMModel::STATUS_SUM;
|
|
||||||
size_t X = end - begin;
|
|
||||||
|
|
||||||
size_t XYSize = X * Y;
|
|
||||||
size_t now, old, stat;
|
|
||||||
double tmp, endE, endS;
|
|
||||||
|
|
||||||
vector<int> path(XYSize);
|
|
||||||
vector<double> weight(XYSize);
|
|
||||||
|
|
||||||
//start
|
|
||||||
for (size_t y = 0; y < Y; y++) {
|
|
||||||
weight[0 + y * X] = model_->startProb[y] + model_->GetEmitProb(model_->emitProbVec[y], begin->rune, MIN_DOUBLE);
|
|
||||||
path[0 + y * X] = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double emitProb;
|
void Cut(const string& sentence,
|
||||||
|
vector<string>& words) const {
|
||||||
for (size_t x = 1; x < X; x++) {
|
vector<Word> tmp;
|
||||||
for (size_t y = 0; y < Y; y++) {
|
Cut(sentence, tmp);
|
||||||
now = x + y*X;
|
GetStringsFromWords(tmp, words);
|
||||||
weight[now] = MIN_DOUBLE;
|
}
|
||||||
path[now] = HMMModel::E; // warning
|
void Cut(const string& sentence,
|
||||||
emitProb = model_->GetEmitProb(model_->emitProbVec[y], (begin+x)->rune, MIN_DOUBLE);
|
vector<Word>& words) const {
|
||||||
for (size_t preY = 0; preY < Y; preY++) {
|
PreFilter pre_filter(symbols_, sentence);
|
||||||
old = x - 1 + preY * X;
|
PreFilter::Range range;
|
||||||
tmp = weight[old] + model_->transProb[preY][y] + emitProb;
|
vector<WordRange> wrs;
|
||||||
if (tmp > weight[now]) {
|
wrs.reserve(sentence.size() / 2);
|
||||||
weight[now] = tmp;
|
while(pre_filter.HasNext()) {
|
||||||
path[now] = preY;
|
range = pre_filter.Next();
|
||||||
}
|
Cut(range.begin, range.end, wrs);
|
||||||
|
}
|
||||||
|
words.clear();
|
||||||
|
words.reserve(wrs.size());
|
||||||
|
GetWordsFromWordRanges(sentence, wrs, words);
|
||||||
|
}
|
||||||
|
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res) const {
|
||||||
|
RuneStrArray::const_iterator left = begin;
|
||||||
|
RuneStrArray::const_iterator right = begin;
|
||||||
|
while(right != end) {
|
||||||
|
if(right->rune < 0x80) {
|
||||||
|
if(left != right) {
|
||||||
|
InternalCut(left, right, res);
|
||||||
|
}
|
||||||
|
left = right;
|
||||||
|
do {
|
||||||
|
right = SequentialLetterRule(left, end);
|
||||||
|
if(right != left) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
right = NumbersRule(left, end);
|
||||||
|
if(right != left) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
right ++;
|
||||||
|
} while(false);
|
||||||
|
WordRange wr(left, right - 1);
|
||||||
|
res.push_back(wr);
|
||||||
|
left = right;
|
||||||
|
} else {
|
||||||
|
right++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(left != right) {
|
||||||
|
InternalCut(left, right, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// sequential letters rule
|
||||||
|
RuneStrArray::const_iterator SequentialLetterRule(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
||||||
|
Rune x = begin->rune;
|
||||||
|
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z')) {
|
||||||
|
begin ++;
|
||||||
|
} else {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
while(begin != end) {
|
||||||
|
x = begin->rune;
|
||||||
|
if(('a' <= x && x <= 'z') || ('A' <= x && x <= 'Z') || ('0' <= x && x <= '9')) {
|
||||||
|
begin ++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
RuneStrArray::const_iterator NumbersRule(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
||||||
|
Rune x = begin->rune;
|
||||||
|
if('0' <= x && x <= '9') {
|
||||||
|
begin ++;
|
||||||
|
} else {
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
while(begin != end) {
|
||||||
|
x = begin->rune;
|
||||||
|
if(('0' <= x && x <= '9') || x == '.') {
|
||||||
|
begin++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
void InternalCut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res) const {
|
||||||
|
vector<size_t> status;
|
||||||
|
Viterbi(begin, end, status);
|
||||||
|
|
||||||
|
RuneStrArray::const_iterator left = begin;
|
||||||
|
RuneStrArray::const_iterator right;
|
||||||
|
for(size_t i = 0; i < status.size(); i++) {
|
||||||
|
if(status[i] % 2) { //if (HMMModel::E == status[i] || HMMModel::S == status[i])
|
||||||
|
right = begin + i + 1;
|
||||||
|
WordRange wr(left, right - 1);
|
||||||
|
res.push_back(wr);
|
||||||
|
left = right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endE = weight[X-1+HMMModel::E*X];
|
void Viterbi(RuneStrArray::const_iterator begin,
|
||||||
endS = weight[X-1+HMMModel::S*X];
|
RuneStrArray::const_iterator end,
|
||||||
stat = 0;
|
vector<size_t>& status) const {
|
||||||
if (endE >= endS) {
|
size_t Y = HMMModel::STATUS_SUM;
|
||||||
stat = HMMModel::E;
|
size_t X = end - begin;
|
||||||
} else {
|
|
||||||
stat = HMMModel::S;
|
size_t XYSize = X * Y;
|
||||||
|
size_t now, old, stat;
|
||||||
|
double tmp, endE, endS;
|
||||||
|
|
||||||
|
vector<int> path(XYSize);
|
||||||
|
vector<double> weight(XYSize);
|
||||||
|
|
||||||
|
//start
|
||||||
|
for(size_t y = 0; y < Y; y++) {
|
||||||
|
weight[0 + y * X] = model_->startProb[y] + model_->GetEmitProb(model_->emitProbVec[y], begin->rune, MIN_DOUBLE);
|
||||||
|
path[0 + y * X] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double emitProb;
|
||||||
|
|
||||||
|
for(size_t x = 1; x < X; x++) {
|
||||||
|
for(size_t y = 0; y < Y; y++) {
|
||||||
|
now = x + y * X;
|
||||||
|
weight[now] = MIN_DOUBLE;
|
||||||
|
path[now] = HMMModel::E; // warning
|
||||||
|
emitProb = model_->GetEmitProb(model_->emitProbVec[y], (begin + x)->rune, MIN_DOUBLE);
|
||||||
|
for(size_t preY = 0; preY < Y; preY++) {
|
||||||
|
old = x - 1 + preY * X;
|
||||||
|
tmp = weight[old] + model_->transProb[preY][y] + emitProb;
|
||||||
|
if(tmp > weight[now]) {
|
||||||
|
weight[now] = tmp;
|
||||||
|
path[now] = preY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endE = weight[X - 1 + HMMModel::E * X];
|
||||||
|
endS = weight[X - 1 + HMMModel::S * X];
|
||||||
|
stat = 0;
|
||||||
|
if(endE >= endS) {
|
||||||
|
stat = HMMModel::E;
|
||||||
|
} else {
|
||||||
|
stat = HMMModel::S;
|
||||||
|
}
|
||||||
|
|
||||||
|
status.resize(X);
|
||||||
|
for(int x = X - 1 ; x >= 0; x--) {
|
||||||
|
status[x] = stat;
|
||||||
|
stat = path[x + stat * X];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status.resize(X);
|
const HMMModel* model_;
|
||||||
for (int x = X -1 ; x >= 0; x--) {
|
bool isNeedDestroy_;
|
||||||
status[x] = stat;
|
|
||||||
stat = path[x + stat*X];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const HMMModel* model_;
|
|
||||||
bool isNeedDestroy_;
|
|
||||||
}; // class HMMSegment
|
}; // class HMMSegment
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -25,123 +25,122 @@
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
|
|
||||||
class Jieba {
|
class Jieba {
|
||||||
public:
|
public:
|
||||||
Jieba(const string& dict_path,
|
Jieba(const string& dict_path,
|
||||||
const string& model_path,
|
const string& model_path,
|
||||||
const string& user_dict_path,
|
const string& user_dict_path,
|
||||||
const string& idfPath,
|
const string& idfPath,
|
||||||
const string& stopWordPath)
|
const string& stopWordPath)
|
||||||
: dict_trie_(dict_path, user_dict_path),
|
: dict_trie_(dict_path, user_dict_path),
|
||||||
model_(model_path),
|
model_(model_path),
|
||||||
mp_seg_(&dict_trie_),
|
mp_seg_(&dict_trie_),
|
||||||
hmm_seg_(&model_),
|
hmm_seg_(&model_),
|
||||||
mix_seg_(&dict_trie_, &model_),
|
mix_seg_(&dict_trie_, &model_),
|
||||||
full_seg_(&dict_trie_),
|
full_seg_(&dict_trie_),
|
||||||
query_seg_(&dict_trie_, &model_),
|
query_seg_(&dict_trie_, &model_),
|
||||||
extractor(&dict_trie_, &model_, idfPath, stopWordPath) {
|
extractor(&dict_trie_, &model_, idfPath, stopWordPath) {
|
||||||
|
|
||||||
}
|
}
|
||||||
~Jieba() {
|
~Jieba() {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocWord {
|
struct LocWord {
|
||||||
string word;
|
string word;
|
||||||
size_t begin;
|
size_t begin;
|
||||||
size_t end;
|
size_t end;
|
||||||
}; // struct LocWord
|
}; // struct LocWord
|
||||||
|
|
||||||
void Cut(const string& sentence, vector<string>& words, bool hmm = true) const {
|
void Cut(const string& sentence, vector<string>& words, bool hmm = true) const {
|
||||||
mix_seg_.Cut(sentence, words, hmm);
|
mix_seg_.Cut(sentence, words, hmm);
|
||||||
}
|
}
|
||||||
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
||||||
mix_seg_.Cut(sentence, words, hmm);
|
mix_seg_.Cut(sentence, words, hmm);
|
||||||
}
|
}
|
||||||
void CutAll(const string& sentence, vector<string>& words) const {
|
void CutAll(const string& sentence, vector<string>& words) const {
|
||||||
full_seg_.Cut(sentence, words);
|
full_seg_.Cut(sentence, words);
|
||||||
}
|
}
|
||||||
void CutAll(const string& sentence, vector<Word>& words) const {
|
void CutAll(const string& sentence, vector<Word>& words) const {
|
||||||
full_seg_.Cut(sentence, words);
|
full_seg_.Cut(sentence, words);
|
||||||
}
|
}
|
||||||
void CutForSearch(const string& sentence, vector<string>& words, bool hmm = true) const {
|
void CutForSearch(const string& sentence, vector<string>& words, bool hmm = true) const {
|
||||||
query_seg_.Cut(sentence, words, hmm);
|
query_seg_.Cut(sentence, words, hmm);
|
||||||
}
|
}
|
||||||
void CutForSearch(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
void CutForSearch(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
||||||
query_seg_.Cut(sentence, words, hmm);
|
query_seg_.Cut(sentence, words, hmm);
|
||||||
}
|
}
|
||||||
void CutHMM(const string& sentence, vector<string>& words) const {
|
void CutHMM(const string& sentence, vector<string>& words) const {
|
||||||
hmm_seg_.Cut(sentence, words);
|
hmm_seg_.Cut(sentence, words);
|
||||||
}
|
}
|
||||||
void CutHMM(const string& sentence, vector<Word>& words) const {
|
void CutHMM(const string& sentence, vector<Word>& words) const {
|
||||||
hmm_seg_.Cut(sentence, words);
|
hmm_seg_.Cut(sentence, words);
|
||||||
}
|
}
|
||||||
void CutSmall(const string& sentence, vector<string>& words, size_t max_word_len) const {
|
void CutSmall(const string& sentence, vector<string>& words, size_t max_word_len) const {
|
||||||
mp_seg_.Cut(sentence, words, max_word_len);
|
mp_seg_.Cut(sentence, words, max_word_len);
|
||||||
}
|
}
|
||||||
void CutSmall(const string& sentence, vector<Word>& words, size_t max_word_len) const {
|
void CutSmall(const string& sentence, vector<Word>& words, size_t max_word_len) const {
|
||||||
mp_seg_.Cut(sentence, words, max_word_len);
|
mp_seg_.Cut(sentence, words, max_word_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tag(const string& sentence, vector<pair<string, string> >& words) const {
|
|
||||||
mix_seg_.Tag(sentence, words);
|
|
||||||
}
|
|
||||||
string LookupTag(const string &str) const {
|
|
||||||
return mix_seg_.LookupTag(str);
|
|
||||||
}
|
|
||||||
bool InsertUserWord(const string& word, const string& tag = UNKNOWN_TAG) {
|
|
||||||
return dict_trie_.InsertUserWord(word, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InsertUserWord(const string& word,int freq, const string& tag = UNKNOWN_TAG) {
|
void Tag(const string& sentence, vector<pair<string, string> >& words) const {
|
||||||
return dict_trie_.InsertUserWord(word,freq, tag);
|
mix_seg_.Tag(sentence, words);
|
||||||
}
|
}
|
||||||
|
string LookupTag(const string &str) const {
|
||||||
|
return mix_seg_.LookupTag(str);
|
||||||
|
}
|
||||||
|
bool InsertUserWord(const string& word, const string& tag = UNKNOWN_TAG) {
|
||||||
|
return dict_trie_.InsertUserWord(word, tag);
|
||||||
|
}
|
||||||
|
|
||||||
bool Find(const string& word)
|
bool InsertUserWord(const string& word, int freq, const string& tag = UNKNOWN_TAG) {
|
||||||
{
|
return dict_trie_.InsertUserWord(word, freq, tag);
|
||||||
return dict_trie_.Find(word);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ResetSeparators(const string& s) {
|
bool Find(const string& word) {
|
||||||
//TODO
|
return dict_trie_.Find(word);
|
||||||
mp_seg_.ResetSeparators(s);
|
}
|
||||||
hmm_seg_.ResetSeparators(s);
|
|
||||||
mix_seg_.ResetSeparators(s);
|
|
||||||
full_seg_.ResetSeparators(s);
|
|
||||||
query_seg_.ResetSeparators(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DictTrie* GetDictTrie() const {
|
void ResetSeparators(const string& s) {
|
||||||
return &dict_trie_;
|
//TODO
|
||||||
}
|
mp_seg_.ResetSeparators(s);
|
||||||
|
hmm_seg_.ResetSeparators(s);
|
||||||
const HMMModel* GetHMMModel() const {
|
mix_seg_.ResetSeparators(s);
|
||||||
return &model_;
|
full_seg_.ResetSeparators(s);
|
||||||
}
|
query_seg_.ResetSeparators(s);
|
||||||
|
}
|
||||||
|
|
||||||
void LoadUserDict(const vector<string>& buf) {
|
const DictTrie* GetDictTrie() const {
|
||||||
dict_trie_.LoadUserDict(buf);
|
return &dict_trie_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadUserDict(const set<string>& buf) {
|
const HMMModel* GetHMMModel() const {
|
||||||
dict_trie_.LoadUserDict(buf);
|
return &model_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadUserDict(const string& path) {
|
void LoadUserDict(const vector<string>& buf) {
|
||||||
dict_trie_.LoadUserDict(path);
|
dict_trie_.LoadUserDict(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
void LoadUserDict(const set<string>& buf) {
|
||||||
DictTrie dict_trie_;
|
dict_trie_.LoadUserDict(buf);
|
||||||
HMMModel model_;
|
}
|
||||||
|
|
||||||
// They share the same dict trie and model
|
|
||||||
MPSegment mp_seg_;
|
|
||||||
HMMSegment hmm_seg_;
|
|
||||||
MixSegment mix_seg_;
|
|
||||||
FullSegment full_seg_;
|
|
||||||
QuerySegment query_seg_;
|
|
||||||
|
|
||||||
public:
|
void LoadUserDict(const string& path) {
|
||||||
KeywordExtractor extractor;
|
dict_trie_.LoadUserDict(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DictTrie dict_trie_;
|
||||||
|
HMMModel model_;
|
||||||
|
|
||||||
|
// They share the same dict trie and model
|
||||||
|
MPSegment mp_seg_;
|
||||||
|
HMMSegment hmm_seg_;
|
||||||
|
MixSegment mix_seg_;
|
||||||
|
FullSegment full_seg_;
|
||||||
|
QuerySegment query_seg_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
KeywordExtractor extractor;
|
||||||
}; // class Jieba
|
}; // class Jieba
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -30,138 +30,138 @@ using namespace std;
|
||||||
|
|
||||||
/*utf8*/
|
/*utf8*/
|
||||||
class KeywordExtractor {
|
class KeywordExtractor {
|
||||||
public:
|
public:
|
||||||
struct Word {
|
struct Word {
|
||||||
string word;
|
string word;
|
||||||
vector<size_t> offsets;
|
vector<size_t> offsets;
|
||||||
double weight;
|
double weight;
|
||||||
}; // struct Word
|
}; // struct Word
|
||||||
|
|
||||||
KeywordExtractor(const string& dictPath,
|
KeywordExtractor(const string& dictPath,
|
||||||
const string& hmmFilePath,
|
const string& hmmFilePath,
|
||||||
const string& idfPath,
|
const string& idfPath,
|
||||||
const string& stopWordPath,
|
const string& stopWordPath,
|
||||||
const string& userDict = "")
|
const string& userDict = "")
|
||||||
: segment_(dictPath, hmmFilePath, userDict) {
|
: segment_(dictPath, hmmFilePath, userDict) {
|
||||||
LoadIdfDict(idfPath);
|
LoadIdfDict(idfPath);
|
||||||
LoadStopWordDict(stopWordPath);
|
LoadStopWordDict(stopWordPath);
|
||||||
}
|
|
||||||
KeywordExtractor(const DictTrie* dictTrie,
|
|
||||||
const HMMModel* model,
|
|
||||||
const string& idfPath,
|
|
||||||
const string& stopWordPath)
|
|
||||||
: segment_(dictTrie, model) {
|
|
||||||
LoadIdfDict(idfPath);
|
|
||||||
LoadStopWordDict(stopWordPath);
|
|
||||||
}
|
|
||||||
~KeywordExtractor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Extract(const string& sentence, vector<string>& keywords, size_t topN) const {
|
|
||||||
vector<Word> topWords;
|
|
||||||
Extract(sentence, topWords, topN);
|
|
||||||
for (size_t i = 0; i < topWords.size(); i++) {
|
|
||||||
keywords.push_back(topWords[i].word);
|
|
||||||
}
|
}
|
||||||
}
|
KeywordExtractor(const DictTrie* dictTrie,
|
||||||
|
const HMMModel* model,
|
||||||
void Extract(const string& sentence, vector<pair<string, double> >& keywords, size_t topN) const {
|
const string& idfPath,
|
||||||
vector<Word> topWords;
|
const string& stopWordPath)
|
||||||
Extract(sentence, topWords, topN);
|
: segment_(dictTrie, model) {
|
||||||
for (size_t i = 0; i < topWords.size(); i++) {
|
LoadIdfDict(idfPath);
|
||||||
keywords.push_back(pair<string, double>(topWords[i].word, topWords[i].weight));
|
LoadStopWordDict(stopWordPath);
|
||||||
}
|
}
|
||||||
}
|
~KeywordExtractor() {
|
||||||
|
|
||||||
void Extract(const string& sentence, vector<Word>& keywords, size_t topN) const {
|
|
||||||
vector<string> words;
|
|
||||||
segment_.Cut(sentence, words);
|
|
||||||
|
|
||||||
map<string, Word> wordmap;
|
|
||||||
size_t offset = 0;
|
|
||||||
for (size_t i = 0; i < words.size(); ++i) {
|
|
||||||
size_t t = offset;
|
|
||||||
offset += words[i].size();
|
|
||||||
if (IsSingleWord(words[i]) || stopWords_.find(words[i]) != stopWords_.end()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wordmap[words[i]].offsets.push_back(t);
|
|
||||||
wordmap[words[i]].weight += 1.0;
|
|
||||||
}
|
|
||||||
if (offset != sentence.size()) {
|
|
||||||
XLOG(ERROR) << "words illegal";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
keywords.clear();
|
void Extract(const string& sentence, vector<string>& keywords, size_t topN) const {
|
||||||
keywords.reserve(wordmap.size());
|
vector<Word> topWords;
|
||||||
for (map<string, Word>::iterator itr = wordmap.begin(); itr != wordmap.end(); ++itr) {
|
Extract(sentence, topWords, topN);
|
||||||
unordered_map<string, double>::const_iterator cit = idfMap_.find(itr->first);
|
for(size_t i = 0; i < topWords.size(); i++) {
|
||||||
if (cit != idfMap_.end()) {
|
keywords.push_back(topWords[i].word);
|
||||||
itr->second.weight *= cit->second;
|
}
|
||||||
} else {
|
|
||||||
itr->second.weight *= idfAverage_;
|
|
||||||
}
|
|
||||||
itr->second.word = itr->first;
|
|
||||||
keywords.push_back(itr->second);
|
|
||||||
}
|
|
||||||
topN = min(topN, keywords.size());
|
|
||||||
partial_sort(keywords.begin(), keywords.begin() + topN, keywords.end(), Compare);
|
|
||||||
keywords.resize(topN);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void LoadIdfDict(const string& idfPath) {
|
|
||||||
ifstream ifs(idfPath.c_str());
|
|
||||||
XCHECK(ifs.is_open()) << "open " << idfPath << " failed";
|
|
||||||
string line ;
|
|
||||||
vector<string> buf;
|
|
||||||
double idf = 0.0;
|
|
||||||
double idfSum = 0.0;
|
|
||||||
size_t lineno = 0;
|
|
||||||
for (; getline(ifs, line); lineno++) {
|
|
||||||
buf.clear();
|
|
||||||
if (line.empty()) {
|
|
||||||
XLOG(ERROR) << "lineno: " << lineno << " empty. skipped.";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Split(line, buf, " ");
|
|
||||||
if (buf.size() != 2) {
|
|
||||||
XLOG(ERROR) << "line: " << line << ", lineno: " << lineno << " empty. skipped.";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
idf = atof(buf[1].c_str());
|
|
||||||
idfMap_[buf[0]] = idf;
|
|
||||||
idfSum += idf;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(lineno);
|
void Extract(const string& sentence, vector<pair<string, double> >& keywords, size_t topN) const {
|
||||||
idfAverage_ = idfSum / lineno;
|
vector<Word> topWords;
|
||||||
assert(idfAverage_ > 0.0);
|
Extract(sentence, topWords, topN);
|
||||||
}
|
for(size_t i = 0; i < topWords.size(); i++) {
|
||||||
void LoadStopWordDict(const string& filePath) {
|
keywords.push_back(pair<string, double>(topWords[i].word, topWords[i].weight));
|
||||||
ifstream ifs(filePath.c_str());
|
}
|
||||||
XCHECK(ifs.is_open()) << "open " << filePath << " failed";
|
|
||||||
string line ;
|
|
||||||
while (getline(ifs, line)) {
|
|
||||||
stopWords_.insert(line);
|
|
||||||
}
|
}
|
||||||
assert(stopWords_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool Compare(const Word& lhs, const Word& rhs) {
|
void Extract(const string& sentence, vector<Word>& keywords, size_t topN) const {
|
||||||
return lhs.weight > rhs.weight;
|
vector<string> words;
|
||||||
}
|
segment_.Cut(sentence, words);
|
||||||
|
|
||||||
MixSegment segment_;
|
map<string, Word> wordmap;
|
||||||
unordered_map<string, double> idfMap_;
|
size_t offset = 0;
|
||||||
double idfAverage_;
|
for(size_t i = 0; i < words.size(); ++i) {
|
||||||
|
size_t t = offset;
|
||||||
|
offset += words[i].size();
|
||||||
|
if(IsSingleWord(words[i]) || stopWords_.find(words[i]) != stopWords_.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wordmap[words[i]].offsets.push_back(t);
|
||||||
|
wordmap[words[i]].weight += 1.0;
|
||||||
|
}
|
||||||
|
if(offset != sentence.size()) {
|
||||||
|
XLOG(ERROR) << "words illegal";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
unordered_set<string> stopWords_;
|
keywords.clear();
|
||||||
|
keywords.reserve(wordmap.size());
|
||||||
|
for(map<string, Word>::iterator itr = wordmap.begin(); itr != wordmap.end(); ++itr) {
|
||||||
|
unordered_map<string, double>::const_iterator cit = idfMap_.find(itr->first);
|
||||||
|
if(cit != idfMap_.end()) {
|
||||||
|
itr->second.weight *= cit->second;
|
||||||
|
} else {
|
||||||
|
itr->second.weight *= idfAverage_;
|
||||||
|
}
|
||||||
|
itr->second.word = itr->first;
|
||||||
|
keywords.push_back(itr->second);
|
||||||
|
}
|
||||||
|
topN = min(topN, keywords.size());
|
||||||
|
partial_sort(keywords.begin(), keywords.begin() + topN, keywords.end(), Compare);
|
||||||
|
keywords.resize(topN);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void LoadIdfDict(const string& idfPath) {
|
||||||
|
ifstream ifs(idfPath.c_str());
|
||||||
|
XCHECK(ifs.is_open()) << "open " << idfPath << " failed";
|
||||||
|
string line ;
|
||||||
|
vector<string> buf;
|
||||||
|
double idf = 0.0;
|
||||||
|
double idfSum = 0.0;
|
||||||
|
size_t lineno = 0;
|
||||||
|
for(; getline(ifs, line); lineno++) {
|
||||||
|
buf.clear();
|
||||||
|
if(line.empty()) {
|
||||||
|
XLOG(ERROR) << "lineno: " << lineno << " empty. skipped.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Split(line, buf, " ");
|
||||||
|
if(buf.size() != 2) {
|
||||||
|
XLOG(ERROR) << "line: " << line << ", lineno: " << lineno << " empty. skipped.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
idf = atof(buf[1].c_str());
|
||||||
|
idfMap_[buf[0]] = idf;
|
||||||
|
idfSum += idf;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(lineno);
|
||||||
|
idfAverage_ = idfSum / lineno;
|
||||||
|
assert(idfAverage_ > 0.0);
|
||||||
|
}
|
||||||
|
void LoadStopWordDict(const string& filePath) {
|
||||||
|
ifstream ifs(filePath.c_str());
|
||||||
|
XCHECK(ifs.is_open()) << "open " << filePath << " failed";
|
||||||
|
string line ;
|
||||||
|
while(getline(ifs, line)) {
|
||||||
|
stopWords_.insert(line);
|
||||||
|
}
|
||||||
|
assert(stopWords_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Compare(const Word& lhs, const Word& rhs) {
|
||||||
|
return lhs.weight > rhs.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
MixSegment segment_;
|
||||||
|
unordered_map<string, double> idfMap_;
|
||||||
|
double idfAverage_;
|
||||||
|
|
||||||
|
unordered_set<string> stopWords_;
|
||||||
}; // class KeywordExtractor
|
}; // class KeywordExtractor
|
||||||
|
|
||||||
inline ostream& operator << (ostream& os, const KeywordExtractor::Word& word) {
|
inline ostream& operator << (ostream& os, const KeywordExtractor::Word& word) {
|
||||||
return os << "{\"word\": \"" << word.word << "\", \"offset\": " << word.offsets << ", \"weight\": " << word.weight << "}";
|
return os << "{\"word\": \"" << word.word << "\", \"offset\": " << word.offsets << ", \"weight\": " << word.weight << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -30,123 +30,123 @@
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
|
|
||||||
class MPSegment: public SegmentTagged {
|
class MPSegment: public SegmentTagged {
|
||||||
public:
|
public:
|
||||||
MPSegment(const string& dictPath, const string& userDictPath = "")
|
MPSegment(const string& dictPath, const string& userDictPath = "")
|
||||||
: dictTrie_(new DictTrie(dictPath, userDictPath)), isNeedDestroy_(true) {
|
: dictTrie_(new DictTrie(dictPath, userDictPath)), isNeedDestroy_(true) {
|
||||||
}
|
|
||||||
MPSegment(const DictTrie* dictTrie)
|
|
||||||
: dictTrie_(dictTrie), isNeedDestroy_(false) {
|
|
||||||
assert(dictTrie_);
|
|
||||||
}
|
|
||||||
~MPSegment() {
|
|
||||||
if (isNeedDestroy_) {
|
|
||||||
delete dictTrie_;
|
|
||||||
}
|
}
|
||||||
}
|
MPSegment(const DictTrie* dictTrie)
|
||||||
|
: dictTrie_(dictTrie), isNeedDestroy_(false) {
|
||||||
void Cut(const string& sentence, vector<string>& words) const {
|
assert(dictTrie_);
|
||||||
Cut(sentence, words, MAX_WORD_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cut(const string& sentence,
|
|
||||||
vector<string>& words,
|
|
||||||
size_t max_word_len) const {
|
|
||||||
vector<Word> tmp;
|
|
||||||
Cut(sentence, tmp, max_word_len);
|
|
||||||
GetStringsFromWords(tmp, words);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence,
|
|
||||||
vector<Word>& words,
|
|
||||||
size_t max_word_len = MAX_WORD_LENGTH) const {
|
|
||||||
PreFilter pre_filter(symbols_, sentence);
|
|
||||||
PreFilter::Range range;
|
|
||||||
vector<WordRange> wrs;
|
|
||||||
wrs.reserve(sentence.size()/2);
|
|
||||||
while (pre_filter.HasNext()) {
|
|
||||||
range = pre_filter.Next();
|
|
||||||
Cut(range.begin, range.end, wrs, max_word_len);
|
|
||||||
}
|
}
|
||||||
words.clear();
|
~MPSegment() {
|
||||||
words.reserve(wrs.size());
|
if(isNeedDestroy_) {
|
||||||
GetWordsFromWordRanges(sentence, wrs, words);
|
delete dictTrie_;
|
||||||
}
|
|
||||||
void Cut(RuneStrArray::const_iterator begin,
|
|
||||||
RuneStrArray::const_iterator end,
|
|
||||||
vector<WordRange>& words,
|
|
||||||
size_t max_word_len = MAX_WORD_LENGTH) const {
|
|
||||||
vector<Dag> dags;
|
|
||||||
dictTrie_->Find(begin,
|
|
||||||
end,
|
|
||||||
dags,
|
|
||||||
max_word_len);
|
|
||||||
CalcDP(dags);
|
|
||||||
CutByDag(begin, end, dags, words);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DictTrie* GetDictTrie() const {
|
|
||||||
return dictTrie_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Tag(const string& src, vector<pair<string, string> >& res) const {
|
|
||||||
return tagger_.Tag(src, res, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsUserDictSingleChineseWord(const Rune& value) const {
|
|
||||||
return dictTrie_->IsUserDictSingleChineseWord(value);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void CalcDP(vector<Dag>& dags) const {
|
|
||||||
size_t nextPos;
|
|
||||||
const DictUnit* p;
|
|
||||||
double val;
|
|
||||||
|
|
||||||
for (vector<Dag>::reverse_iterator rit = dags.rbegin(); rit != dags.rend(); rit++) {
|
|
||||||
rit->pInfo = NULL;
|
|
||||||
rit->weight = MIN_DOUBLE;
|
|
||||||
assert(!rit->nexts.empty());
|
|
||||||
for (LocalVector<pair<size_t, const DictUnit*> >::const_iterator it = rit->nexts.begin(); it != rit->nexts.end(); it++) {
|
|
||||||
nextPos = it->first;
|
|
||||||
p = it->second;
|
|
||||||
val = 0.0;
|
|
||||||
if (nextPos + 1 < dags.size()) {
|
|
||||||
val += dags[nextPos + 1].weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p) {
|
|
||||||
val += p->weight;
|
|
||||||
} else {
|
|
||||||
val += dictTrie_->GetMinWeight();
|
|
||||||
}
|
|
||||||
if (val > rit->weight) {
|
|
||||||
rit->pInfo = p;
|
|
||||||
rit->weight = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
void CutByDag(RuneStrArray::const_iterator begin,
|
|
||||||
RuneStrArray::const_iterator end,
|
|
||||||
const vector<Dag>& dags,
|
|
||||||
vector<WordRange>& words) const {
|
|
||||||
size_t i = 0;
|
|
||||||
while (i < dags.size()) {
|
|
||||||
const DictUnit* p = dags[i].pInfo;
|
|
||||||
if (p) {
|
|
||||||
assert(p->word.size() >= 1);
|
|
||||||
WordRange wr(begin + i, begin + i + p->word.size() - 1);
|
|
||||||
words.push_back(wr);
|
|
||||||
i += p->word.size();
|
|
||||||
} else { //single chinese word
|
|
||||||
WordRange wr(begin + i, begin + i);
|
|
||||||
words.push_back(wr);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const DictTrie* dictTrie_;
|
void Cut(const string& sentence, vector<string>& words) const {
|
||||||
bool isNeedDestroy_;
|
Cut(sentence, words, MAX_WORD_LENGTH);
|
||||||
PosTagger tagger_;
|
}
|
||||||
|
|
||||||
|
void Cut(const string& sentence,
|
||||||
|
vector<string>& words,
|
||||||
|
size_t max_word_len) const {
|
||||||
|
vector<Word> tmp;
|
||||||
|
Cut(sentence, tmp, max_word_len);
|
||||||
|
GetStringsFromWords(tmp, words);
|
||||||
|
}
|
||||||
|
void Cut(const string& sentence,
|
||||||
|
vector<Word>& words,
|
||||||
|
size_t max_word_len = MAX_WORD_LENGTH) const {
|
||||||
|
PreFilter pre_filter(symbols_, sentence);
|
||||||
|
PreFilter::Range range;
|
||||||
|
vector<WordRange> wrs;
|
||||||
|
wrs.reserve(sentence.size() / 2);
|
||||||
|
while(pre_filter.HasNext()) {
|
||||||
|
range = pre_filter.Next();
|
||||||
|
Cut(range.begin, range.end, wrs, max_word_len);
|
||||||
|
}
|
||||||
|
words.clear();
|
||||||
|
words.reserve(wrs.size());
|
||||||
|
GetWordsFromWordRanges(sentence, wrs, words);
|
||||||
|
}
|
||||||
|
void Cut(RuneStrArray::const_iterator begin,
|
||||||
|
RuneStrArray::const_iterator end,
|
||||||
|
vector<WordRange>& words,
|
||||||
|
size_t max_word_len = MAX_WORD_LENGTH) const {
|
||||||
|
vector<Dag> dags;
|
||||||
|
dictTrie_->Find(begin,
|
||||||
|
end,
|
||||||
|
dags,
|
||||||
|
max_word_len);
|
||||||
|
CalcDP(dags);
|
||||||
|
CutByDag(begin, end, dags, words);
|
||||||
|
}
|
||||||
|
|
||||||
|
const DictTrie* GetDictTrie() const {
|
||||||
|
return dictTrie_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tag(const string& src, vector<pair<string, string> >& res) const {
|
||||||
|
return tagger_.Tag(src, res, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsUserDictSingleChineseWord(const Rune& value) const {
|
||||||
|
return dictTrie_->IsUserDictSingleChineseWord(value);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void CalcDP(vector<Dag>& dags) const {
|
||||||
|
size_t nextPos;
|
||||||
|
const DictUnit* p;
|
||||||
|
double val;
|
||||||
|
|
||||||
|
for(vector<Dag>::reverse_iterator rit = dags.rbegin(); rit != dags.rend(); rit++) {
|
||||||
|
rit->pInfo = NULL;
|
||||||
|
rit->weight = MIN_DOUBLE;
|
||||||
|
assert(!rit->nexts.empty());
|
||||||
|
for(LocalVector<pair<size_t, const DictUnit*> >::const_iterator it = rit->nexts.begin(); it != rit->nexts.end(); it++) {
|
||||||
|
nextPos = it->first;
|
||||||
|
p = it->second;
|
||||||
|
val = 0.0;
|
||||||
|
if(nextPos + 1 < dags.size()) {
|
||||||
|
val += dags[nextPos + 1].weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p) {
|
||||||
|
val += p->weight;
|
||||||
|
} else {
|
||||||
|
val += dictTrie_->GetMinWeight();
|
||||||
|
}
|
||||||
|
if(val > rit->weight) {
|
||||||
|
rit->pInfo = p;
|
||||||
|
rit->weight = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CutByDag(RuneStrArray::const_iterator begin,
|
||||||
|
RuneStrArray::const_iterator end,
|
||||||
|
const vector<Dag>& dags,
|
||||||
|
vector<WordRange>& words) const {
|
||||||
|
size_t i = 0;
|
||||||
|
while(i < dags.size()) {
|
||||||
|
const DictUnit* p = dags[i].pInfo;
|
||||||
|
if(p) {
|
||||||
|
assert(p->word.size() >= 1);
|
||||||
|
WordRange wr(begin + i, begin + i + p->word.size() - 1);
|
||||||
|
words.push_back(wr);
|
||||||
|
i += p->word.size();
|
||||||
|
} else { //single chinese word
|
||||||
|
WordRange wr(begin + i, begin + i);
|
||||||
|
words.push_back(wr);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DictTrie* dictTrie_;
|
||||||
|
bool isNeedDestroy_;
|
||||||
|
PosTagger tagger_;
|
||||||
|
|
||||||
}; // class MPSegment
|
}; // class MPSegment
|
||||||
|
|
||||||
|
|
|
@ -27,98 +27,98 @@
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
class MixSegment: public SegmentTagged {
|
class MixSegment: public SegmentTagged {
|
||||||
public:
|
public:
|
||||||
MixSegment(const string& mpSegDict, const string& hmmSegDict,
|
MixSegment(const string& mpSegDict, const string& hmmSegDict,
|
||||||
const string& userDict = "")
|
const string& userDict = "")
|
||||||
: mpSeg_(mpSegDict, userDict),
|
: mpSeg_(mpSegDict, userDict),
|
||||||
hmmSeg_(hmmSegDict) {
|
hmmSeg_(hmmSegDict) {
|
||||||
}
|
|
||||||
MixSegment(const DictTrie* dictTrie, const HMMModel* model)
|
|
||||||
: mpSeg_(dictTrie), hmmSeg_(model) {
|
|
||||||
}
|
|
||||||
~MixSegment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cut(const string& sentence, vector<string>& words) const {
|
|
||||||
Cut(sentence, words, true);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence, vector<string>& words, bool hmm) const {
|
|
||||||
vector<Word> tmp;
|
|
||||||
Cut(sentence, tmp, hmm);
|
|
||||||
GetStringsFromWords(tmp, words);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
|
||||||
PreFilter pre_filter(symbols_, sentence);
|
|
||||||
PreFilter::Range range;
|
|
||||||
vector<WordRange> wrs;
|
|
||||||
wrs.reserve(sentence.size() / 2);
|
|
||||||
while (pre_filter.HasNext()) {
|
|
||||||
range = pre_filter.Next();
|
|
||||||
Cut(range.begin, range.end, wrs, hmm);
|
|
||||||
}
|
}
|
||||||
words.clear();
|
MixSegment(const DictTrie* dictTrie, const HMMModel* model)
|
||||||
words.reserve(wrs.size());
|
: mpSeg_(dictTrie), hmmSeg_(model) {
|
||||||
GetWordsFromWordRanges(sentence, wrs, words);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res, bool hmm) const {
|
|
||||||
if (!hmm) {
|
|
||||||
mpSeg_.Cut(begin, end, res);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
vector<WordRange> words;
|
~MixSegment() {
|
||||||
assert(end >= begin);
|
|
||||||
words.reserve(end - begin);
|
|
||||||
mpSeg_.Cut(begin, end, words);
|
|
||||||
|
|
||||||
vector<WordRange> hmmRes;
|
|
||||||
hmmRes.reserve(end - begin);
|
|
||||||
for (size_t i = 0; i < words.size(); i++) {
|
|
||||||
//if mp Get a word, it's ok, put it into result
|
|
||||||
if (words[i].left != words[i].right || (words[i].left == words[i].right && mpSeg_.IsUserDictSingleChineseWord(words[i].left->rune))) {
|
|
||||||
res.push_back(words[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if mp Get a single one and it is not in userdict, collect it in sequence
|
|
||||||
size_t j = i;
|
|
||||||
while (j < words.size() && words[j].left == words[j].right && !mpSeg_.IsUserDictSingleChineseWord(words[j].left->rune)) {
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cut the sequence with hmm
|
|
||||||
assert(j - 1 >= i);
|
|
||||||
// TODO
|
|
||||||
hmmSeg_.Cut(words[i].left, words[j - 1].left + 1, hmmRes);
|
|
||||||
//put hmm result to result
|
|
||||||
for (size_t k = 0; k < hmmRes.size(); k++) {
|
|
||||||
res.push_back(hmmRes[k]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//clear tmp vars
|
|
||||||
hmmRes.clear();
|
|
||||||
|
|
||||||
//let i jump over this piece
|
|
||||||
i = j - 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const DictTrie* GetDictTrie() const {
|
void Cut(const string& sentence, vector<string>& words) const {
|
||||||
return mpSeg_.GetDictTrie();
|
Cut(sentence, words, true);
|
||||||
}
|
}
|
||||||
|
void Cut(const string& sentence, vector<string>& words, bool hmm) const {
|
||||||
|
vector<Word> tmp;
|
||||||
|
Cut(sentence, tmp, hmm);
|
||||||
|
GetStringsFromWords(tmp, words);
|
||||||
|
}
|
||||||
|
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
||||||
|
PreFilter pre_filter(symbols_, sentence);
|
||||||
|
PreFilter::Range range;
|
||||||
|
vector<WordRange> wrs;
|
||||||
|
wrs.reserve(sentence.size() / 2);
|
||||||
|
while(pre_filter.HasNext()) {
|
||||||
|
range = pre_filter.Next();
|
||||||
|
Cut(range.begin, range.end, wrs, hmm);
|
||||||
|
}
|
||||||
|
words.clear();
|
||||||
|
words.reserve(wrs.size());
|
||||||
|
GetWordsFromWordRanges(sentence, wrs, words);
|
||||||
|
}
|
||||||
|
|
||||||
bool Tag(const string& src, vector<pair<string, string> >& res) const {
|
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res, bool hmm) const {
|
||||||
return tagger_.Tag(src, res, *this);
|
if(!hmm) {
|
||||||
}
|
mpSeg_.Cut(begin, end, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vector<WordRange> words;
|
||||||
|
assert(end >= begin);
|
||||||
|
words.reserve(end - begin);
|
||||||
|
mpSeg_.Cut(begin, end, words);
|
||||||
|
|
||||||
string LookupTag(const string &str) const {
|
vector<WordRange> hmmRes;
|
||||||
return tagger_.LookupTag(str, *this);
|
hmmRes.reserve(end - begin);
|
||||||
}
|
for(size_t i = 0; i < words.size(); i++) {
|
||||||
|
//if mp Get a word, it's ok, put it into result
|
||||||
|
if(words[i].left != words[i].right || (words[i].left == words[i].right && mpSeg_.IsUserDictSingleChineseWord(words[i].left->rune))) {
|
||||||
|
res.push_back(words[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
// if mp Get a single one and it is not in userdict, collect it in sequence
|
||||||
MPSegment mpSeg_;
|
size_t j = i;
|
||||||
HMMSegment hmmSeg_;
|
while(j < words.size() && words[j].left == words[j].right && !mpSeg_.IsUserDictSingleChineseWord(words[j].left->rune)) {
|
||||||
PosTagger tagger_;
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cut the sequence with hmm
|
||||||
|
assert(j - 1 >= i);
|
||||||
|
// TODO
|
||||||
|
hmmSeg_.Cut(words[i].left, words[j - 1].left + 1, hmmRes);
|
||||||
|
//put hmm result to result
|
||||||
|
for(size_t k = 0; k < hmmRes.size(); k++) {
|
||||||
|
res.push_back(hmmRes[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//clear tmp vars
|
||||||
|
hmmRes.clear();
|
||||||
|
|
||||||
|
//let i jump over this piece
|
||||||
|
i = j - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DictTrie* GetDictTrie() const {
|
||||||
|
return mpSeg_.GetDictTrie();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tag(const string& src, vector<pair<string, string> >& res) const {
|
||||||
|
return tagger_.Tag(src, res, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
string LookupTag(const string &str) const {
|
||||||
|
return tagger_.LookupTag(str, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MPSegment mpSeg_;
|
||||||
|
HMMSegment hmmSeg_;
|
||||||
|
PosTagger tagger_;
|
||||||
|
|
||||||
}; // class MixSegment
|
}; // class MixSegment
|
||||||
|
|
||||||
|
|
|
@ -31,62 +31,62 @@ static const char* const POS_ENG = "eng";
|
||||||
static const char* const POS_X = "x";
|
static const char* const POS_X = "x";
|
||||||
|
|
||||||
class PosTagger {
|
class PosTagger {
|
||||||
public:
|
public:
|
||||||
PosTagger() {
|
PosTagger() {
|
||||||
}
|
}
|
||||||
~PosTagger() {
|
~PosTagger() {
|
||||||
}
|
|
||||||
|
|
||||||
bool Tag(const string& src, vector<pair<string, string> >& res, const SegmentTagged& segment) const {
|
|
||||||
vector<string> CutRes;
|
|
||||||
segment.Cut(src, CutRes);
|
|
||||||
|
|
||||||
for (vector<string>::iterator itr = CutRes.begin(); itr != CutRes.end(); ++itr) {
|
|
||||||
res.push_back(make_pair(*itr, LookupTag(*itr, segment)));
|
|
||||||
}
|
}
|
||||||
return !res.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
string LookupTag(const string &str, const SegmentTagged& segment) const {
|
bool Tag(const string& src, vector<pair<string, string> >& res, const SegmentTagged& segment) const {
|
||||||
const DictUnit *tmp = NULL;
|
vector<string> CutRes;
|
||||||
RuneStrArray runes;
|
segment.Cut(src, CutRes);
|
||||||
const DictTrie * dict = segment.GetDictTrie();
|
|
||||||
assert(dict != NULL);
|
|
||||||
if (!DecodeRunesInString(str, runes)) {
|
|
||||||
XLOG(ERROR) << "Decode failed.";
|
|
||||||
return POS_X;
|
|
||||||
}
|
|
||||||
tmp = dict->Find(runes.begin(), runes.end());
|
|
||||||
if (tmp == NULL || tmp->tag.empty()) {
|
|
||||||
return SpecialRule(runes);
|
|
||||||
} else {
|
|
||||||
return tmp->tag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
for(vector<string>::iterator itr = CutRes.begin(); itr != CutRes.end(); ++itr) {
|
||||||
const char* SpecialRule(const RuneStrArray& unicode) const {
|
res.push_back(make_pair(*itr, LookupTag(*itr, segment)));
|
||||||
size_t m = 0;
|
|
||||||
size_t eng = 0;
|
|
||||||
for (size_t i = 0; i < unicode.size() && eng < unicode.size() / 2; i++) {
|
|
||||||
if (unicode[i].rune < 0x80) {
|
|
||||||
eng ++;
|
|
||||||
if ('0' <= unicode[i].rune && unicode[i].rune <= '9') {
|
|
||||||
m++;
|
|
||||||
}
|
}
|
||||||
}
|
return !res.empty();
|
||||||
}
|
}
|
||||||
// ascii char is not found
|
|
||||||
if (eng == 0) {
|
string LookupTag(const string &str, const SegmentTagged& segment) const {
|
||||||
return POS_X;
|
const DictUnit *tmp = NULL;
|
||||||
|
RuneStrArray runes;
|
||||||
|
const DictTrie * dict = segment.GetDictTrie();
|
||||||
|
assert(dict != NULL);
|
||||||
|
if(!DecodeRunesInString(str, runes)) {
|
||||||
|
XLOG(ERROR) << "Decode failed.";
|
||||||
|
return POS_X;
|
||||||
|
}
|
||||||
|
tmp = dict->Find(runes.begin(), runes.end());
|
||||||
|
if(tmp == NULL || tmp->tag.empty()) {
|
||||||
|
return SpecialRule(runes);
|
||||||
|
} else {
|
||||||
|
return tmp->tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// all the ascii is number char
|
|
||||||
if (m == eng) {
|
private:
|
||||||
return POS_M;
|
const char* SpecialRule(const RuneStrArray& unicode) const {
|
||||||
|
size_t m = 0;
|
||||||
|
size_t eng = 0;
|
||||||
|
for(size_t i = 0; i < unicode.size() && eng < unicode.size() / 2; i++) {
|
||||||
|
if(unicode[i].rune < 0x80) {
|
||||||
|
eng ++;
|
||||||
|
if('0' <= unicode[i].rune && unicode[i].rune <= '9') {
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ascii char is not found
|
||||||
|
if(eng == 0) {
|
||||||
|
return POS_X;
|
||||||
|
}
|
||||||
|
// all the ascii is number char
|
||||||
|
if(m == eng) {
|
||||||
|
return POS_M;
|
||||||
|
}
|
||||||
|
// the ascii chars contain english letter
|
||||||
|
return POS_ENG;
|
||||||
}
|
}
|
||||||
// the ascii chars contain english letter
|
|
||||||
return POS_ENG;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class PosTagger
|
}; // class PosTagger
|
||||||
|
|
||||||
|
|
|
@ -25,46 +25,46 @@
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
|
|
||||||
class PreFilter {
|
class PreFilter {
|
||||||
public:
|
public:
|
||||||
//TODO use WordRange instead of Range
|
//TODO use WordRange instead of Range
|
||||||
struct Range {
|
struct Range {
|
||||||
RuneStrArray::const_iterator begin;
|
RuneStrArray::const_iterator begin;
|
||||||
RuneStrArray::const_iterator end;
|
RuneStrArray::const_iterator end;
|
||||||
}; // struct Range
|
}; // struct Range
|
||||||
|
|
||||||
PreFilter(const unordered_set<Rune>& symbols,
|
PreFilter(const unordered_set<Rune>& symbols,
|
||||||
const string& sentence)
|
const string& sentence)
|
||||||
: symbols_(symbols) {
|
: symbols_(symbols) {
|
||||||
if (!DecodeRunesInString(sentence, sentence_)) {
|
if(!DecodeRunesInString(sentence, sentence_)) {
|
||||||
XLOG(ERROR) << "decode failed. ";
|
XLOG(ERROR) << "decode failed. ";
|
||||||
}
|
|
||||||
cursor_ = sentence_.begin();
|
|
||||||
}
|
|
||||||
~PreFilter() {
|
|
||||||
}
|
|
||||||
bool HasNext() const {
|
|
||||||
return cursor_ != sentence_.end();
|
|
||||||
}
|
|
||||||
Range Next() {
|
|
||||||
Range range;
|
|
||||||
range.begin = cursor_;
|
|
||||||
while (cursor_ != sentence_.end()) {
|
|
||||||
if (IsIn(symbols_, cursor_->rune)) {
|
|
||||||
if (range.begin == cursor_) {
|
|
||||||
cursor_ ++;
|
|
||||||
}
|
}
|
||||||
range.end = cursor_;
|
cursor_ = sentence_.begin();
|
||||||
return range;
|
|
||||||
}
|
|
||||||
cursor_ ++;
|
|
||||||
}
|
}
|
||||||
range.end = sentence_.end();
|
~PreFilter() {
|
||||||
return range;
|
}
|
||||||
}
|
bool HasNext() const {
|
||||||
private:
|
return cursor_ != sentence_.end();
|
||||||
RuneStrArray::const_iterator cursor_;
|
}
|
||||||
RuneStrArray sentence_;
|
Range Next() {
|
||||||
const unordered_set<Rune>& symbols_;
|
Range range;
|
||||||
|
range.begin = cursor_;
|
||||||
|
while(cursor_ != sentence_.end()) {
|
||||||
|
if(IsIn(symbols_, cursor_->rune)) {
|
||||||
|
if(range.begin == cursor_) {
|
||||||
|
cursor_ ++;
|
||||||
|
}
|
||||||
|
range.end = cursor_;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
cursor_ ++;
|
||||||
|
}
|
||||||
|
range.end = sentence_.end();
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
RuneStrArray::const_iterator cursor_;
|
||||||
|
RuneStrArray sentence_;
|
||||||
|
const unordered_set<Rune>& symbols_;
|
||||||
}; // class PreFilter
|
}; // class PreFilter
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -31,75 +31,75 @@
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
class QuerySegment: public SegmentBase {
|
class QuerySegment: public SegmentBase {
|
||||||
public:
|
public:
|
||||||
QuerySegment(const string& dict, const string& model, const string& userDict = "")
|
QuerySegment(const string& dict, const string& model, const string& userDict = "")
|
||||||
: mixSeg_(dict, model, userDict),
|
: mixSeg_(dict, model, userDict),
|
||||||
trie_(mixSeg_.GetDictTrie()) {
|
trie_(mixSeg_.GetDictTrie()) {
|
||||||
}
|
|
||||||
QuerySegment(const DictTrie* dictTrie, const HMMModel* model)
|
|
||||||
: mixSeg_(dictTrie, model), trie_(dictTrie) {
|
|
||||||
}
|
|
||||||
~QuerySegment() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cut(const string& sentence, vector<string>& words) const {
|
|
||||||
Cut(sentence, words, true);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence, vector<string>& words, bool hmm) const {
|
|
||||||
vector<Word> tmp;
|
|
||||||
Cut(sentence, tmp, hmm);
|
|
||||||
GetStringsFromWords(tmp, words);
|
|
||||||
}
|
|
||||||
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
|
||||||
PreFilter pre_filter(symbols_, sentence);
|
|
||||||
PreFilter::Range range;
|
|
||||||
vector<WordRange> wrs;
|
|
||||||
wrs.reserve(sentence.size()/2);
|
|
||||||
while (pre_filter.HasNext()) {
|
|
||||||
range = pre_filter.Next();
|
|
||||||
Cut(range.begin, range.end, wrs, hmm);
|
|
||||||
}
|
}
|
||||||
words.clear();
|
QuerySegment(const DictTrie* dictTrie, const HMMModel* model)
|
||||||
words.reserve(wrs.size());
|
: mixSeg_(dictTrie, model), trie_(dictTrie) {
|
||||||
GetWordsFromWordRanges(sentence, wrs, words);
|
|
||||||
}
|
|
||||||
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res, bool hmm) const {
|
|
||||||
//use mix Cut first
|
|
||||||
vector<WordRange> mixRes;
|
|
||||||
mixSeg_.Cut(begin, end, mixRes, hmm);
|
|
||||||
|
|
||||||
vector<WordRange> fullRes;
|
|
||||||
for (vector<WordRange>::const_iterator mixResItr = mixRes.begin(); mixResItr != mixRes.end(); mixResItr++) {
|
|
||||||
if (mixResItr->Length() > 2) {
|
|
||||||
for (size_t i = 0; i + 1 < mixResItr->Length(); i++) {
|
|
||||||
WordRange wr(mixResItr->left + i, mixResItr->left + i + 1);
|
|
||||||
if (trie_->Find(wr.left, wr.right + 1) != NULL) {
|
|
||||||
res.push_back(wr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mixResItr->Length() > 3) {
|
|
||||||
for (size_t i = 0; i + 2 < mixResItr->Length(); i++) {
|
|
||||||
WordRange wr(mixResItr->left + i, mixResItr->left + i + 2);
|
|
||||||
if (trie_->Find(wr.left, wr.right + 1) != NULL) {
|
|
||||||
res.push_back(wr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.push_back(*mixResItr);
|
|
||||||
}
|
}
|
||||||
}
|
~QuerySegment() {
|
||||||
private:
|
}
|
||||||
bool IsAllAscii(const Unicode& s) const {
|
|
||||||
for(size_t i = 0; i < s.size(); i++) {
|
void Cut(const string& sentence, vector<string>& words) const {
|
||||||
if (s[i] >= 0x80) {
|
Cut(sentence, words, true);
|
||||||
return false;
|
}
|
||||||
}
|
void Cut(const string& sentence, vector<string>& words, bool hmm) const {
|
||||||
}
|
vector<Word> tmp;
|
||||||
return true;
|
Cut(sentence, tmp, hmm);
|
||||||
}
|
GetStringsFromWords(tmp, words);
|
||||||
MixSegment mixSeg_;
|
}
|
||||||
const DictTrie* trie_;
|
void Cut(const string& sentence, vector<Word>& words, bool hmm = true) const {
|
||||||
|
PreFilter pre_filter(symbols_, sentence);
|
||||||
|
PreFilter::Range range;
|
||||||
|
vector<WordRange> wrs;
|
||||||
|
wrs.reserve(sentence.size() / 2);
|
||||||
|
while(pre_filter.HasNext()) {
|
||||||
|
range = pre_filter.Next();
|
||||||
|
Cut(range.begin, range.end, wrs, hmm);
|
||||||
|
}
|
||||||
|
words.clear();
|
||||||
|
words.reserve(wrs.size());
|
||||||
|
GetWordsFromWordRanges(sentence, wrs, words);
|
||||||
|
}
|
||||||
|
void Cut(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end, vector<WordRange>& res, bool hmm) const {
|
||||||
|
//use mix Cut first
|
||||||
|
vector<WordRange> mixRes;
|
||||||
|
mixSeg_.Cut(begin, end, mixRes, hmm);
|
||||||
|
|
||||||
|
vector<WordRange> fullRes;
|
||||||
|
for(vector<WordRange>::const_iterator mixResItr = mixRes.begin(); mixResItr != mixRes.end(); mixResItr++) {
|
||||||
|
if(mixResItr->Length() > 2) {
|
||||||
|
for(size_t i = 0; i + 1 < mixResItr->Length(); i++) {
|
||||||
|
WordRange wr(mixResItr->left + i, mixResItr->left + i + 1);
|
||||||
|
if(trie_->Find(wr.left, wr.right + 1) != NULL) {
|
||||||
|
res.push_back(wr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(mixResItr->Length() > 3) {
|
||||||
|
for(size_t i = 0; i + 2 < mixResItr->Length(); i++) {
|
||||||
|
WordRange wr(mixResItr->left + i, mixResItr->left + i + 2);
|
||||||
|
if(trie_->Find(wr.left, wr.right + 1) != NULL) {
|
||||||
|
res.push_back(wr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.push_back(*mixResItr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool IsAllAscii(const Unicode& s) const {
|
||||||
|
for(size_t i = 0; i < s.size(); i++) {
|
||||||
|
if(s[i] >= 0x80) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
MixSegment mixSeg_;
|
||||||
|
const DictTrie* trie_;
|
||||||
}; // QuerySegment
|
}; // QuerySegment
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -31,32 +31,32 @@ const char* const SPECIAL_SEPARATORS = " \t\n\xEF\xBC\x8C\xE3\x80\x82";
|
||||||
using namespace limonp;
|
using namespace limonp;
|
||||||
|
|
||||||
class SegmentBase {
|
class SegmentBase {
|
||||||
public:
|
public:
|
||||||
SegmentBase() {
|
SegmentBase() {
|
||||||
XCHECK(ResetSeparators(SPECIAL_SEPARATORS));
|
XCHECK(ResetSeparators(SPECIAL_SEPARATORS));
|
||||||
}
|
|
||||||
virtual ~SegmentBase() {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Cut(const string& sentence, vector<string>& words) const = 0;
|
|
||||||
|
|
||||||
bool ResetSeparators(const string& s) {
|
|
||||||
symbols_.clear();
|
|
||||||
RuneStrArray runes;
|
|
||||||
if (!DecodeRunesInString(s, runes)) {
|
|
||||||
XLOG(ERROR) << "decode " << s << " failed";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < runes.size(); i++) {
|
virtual ~SegmentBase() {
|
||||||
if (!symbols_.insert(runes[i].rune).second) {
|
|
||||||
XLOG(ERROR) << s.substr(runes[i].offset, runes[i].len) << " already exists";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
virtual void Cut(const string& sentence, vector<string>& words) const = 0;
|
||||||
protected:
|
|
||||||
unordered_set<Rune> symbols_;
|
bool ResetSeparators(const string& s) {
|
||||||
|
symbols_.clear();
|
||||||
|
RuneStrArray runes;
|
||||||
|
if(!DecodeRunesInString(s, runes)) {
|
||||||
|
XLOG(ERROR) << "decode " << s << " failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < runes.size(); i++) {
|
||||||
|
if(!symbols_.insert(runes[i].rune).second) {
|
||||||
|
XLOG(ERROR) << s.substr(runes[i].offset, runes[i].len) << " already exists";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
unordered_set<Rune> symbols_;
|
||||||
}; // class SegmentBase
|
}; // class SegmentBase
|
||||||
|
|
||||||
} // cppjieba
|
} // cppjieba
|
||||||
|
|
|
@ -23,16 +23,16 @@
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
|
|
||||||
class SegmentTagged : public SegmentBase{
|
class SegmentTagged : public SegmentBase {
|
||||||
public:
|
public:
|
||||||
SegmentTagged() {
|
SegmentTagged() {
|
||||||
}
|
}
|
||||||
virtual ~SegmentTagged() {
|
virtual ~SegmentTagged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Tag(const string& src, vector<pair<string, string> >& res) const = 0;
|
virtual bool Tag(const string& src, vector<pair<string, string> >& res) const = 0;
|
||||||
|
|
||||||
virtual const DictTrie* GetDictTrie() const = 0;
|
virtual const DictTrie* GetDictTrie() const = 0;
|
||||||
|
|
||||||
}; // class SegmentTagged
|
}; // class SegmentTagged
|
||||||
|
|
||||||
|
|
|
@ -23,100 +23,104 @@
|
||||||
#include "Jieba.hpp"
|
#include "Jieba.hpp"
|
||||||
|
|
||||||
namespace cppjieba {
|
namespace cppjieba {
|
||||||
using namespace limonp;
|
using namespace limonp;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class TextRankExtractor {
|
class TextRankExtractor {
|
||||||
public:
|
public:
|
||||||
typedef struct _Word {string word;vector<size_t> offsets;double weight;} Word; // struct Word
|
typedef struct _Word {
|
||||||
private:
|
string word;
|
||||||
typedef std::map<string,Word> WordMap;
|
vector<size_t> offsets;
|
||||||
|
double weight;
|
||||||
class WordGraph{
|
} Word; // struct Word
|
||||||
|
private:
|
||||||
|
typedef std::map<string, Word> WordMap;
|
||||||
|
|
||||||
|
class WordGraph {
|
||||||
private:
|
private:
|
||||||
typedef double Score;
|
typedef double Score;
|
||||||
typedef string Node;
|
typedef string Node;
|
||||||
typedef std::set<Node> NodeSet;
|
typedef std::set<Node> NodeSet;
|
||||||
|
|
||||||
typedef std::map<Node,double> Edges;
|
typedef std::map<Node, double> Edges;
|
||||||
typedef std::map<Node,Edges> Graph;
|
typedef std::map<Node, Edges> Graph;
|
||||||
//typedef std::unordered_map<Node,double> Edges;
|
//typedef std::unordered_map<Node,double> Edges;
|
||||||
//typedef std::unordered_map<Node,Edges> Graph;
|
//typedef std::unordered_map<Node,Edges> Graph;
|
||||||
|
|
||||||
double d;
|
double d;
|
||||||
Graph graph;
|
Graph graph;
|
||||||
NodeSet nodeSet;
|
NodeSet nodeSet;
|
||||||
public:
|
public:
|
||||||
WordGraph(): d(0.85) {};
|
WordGraph(): d(0.85) {};
|
||||||
WordGraph(double in_d): d(in_d) {};
|
WordGraph(double in_d): d(in_d) {};
|
||||||
|
|
||||||
void addEdge(Node start,Node end,double weight){
|
void addEdge(Node start, Node end, double weight) {
|
||||||
Edges temp;
|
Edges temp;
|
||||||
Edges::iterator gotEdges;
|
Edges::iterator gotEdges;
|
||||||
nodeSet.insert(start);
|
nodeSet.insert(start);
|
||||||
nodeSet.insert(end);
|
nodeSet.insert(end);
|
||||||
graph[start][end]+=weight;
|
graph[start][end] += weight;
|
||||||
graph[end][start]+=weight;
|
graph[end][start] += weight;
|
||||||
}
|
|
||||||
|
|
||||||
void rank(WordMap &ws,size_t rankTime=10){
|
|
||||||
WordMap outSum;
|
|
||||||
Score wsdef, min_rank, max_rank;
|
|
||||||
|
|
||||||
if( graph.size() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wsdef = 1.0 / graph.size();
|
|
||||||
|
|
||||||
for(Graph::iterator edges=graph.begin();edges!=graph.end();++edges){
|
|
||||||
// edges->first start节点;edge->first end节点;edge->second 权重
|
|
||||||
ws[edges->first].word=edges->first;
|
|
||||||
ws[edges->first].weight=wsdef;
|
|
||||||
outSum[edges->first].weight=0;
|
|
||||||
for(Edges::iterator edge=edges->second.begin();edge!=edges->second.end();++edge){
|
|
||||||
outSum[edges->first].weight+=edge->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//sort(nodeSet.begin(),nodeSet.end()); 是否需要排序?
|
|
||||||
for( size_t i=0; i<rankTime; i++ ){
|
|
||||||
for(NodeSet::iterator node = nodeSet.begin(); node != nodeSet.end(); node++ ){
|
|
||||||
double s = 0;
|
|
||||||
for( Edges::iterator edge= graph[*node].begin(); edge != graph[*node].end(); edge++ )
|
|
||||||
// edge->first end节点;edge->second 权重
|
|
||||||
s += edge->second / outSum[edge->first].weight * ws[edge->first].weight;
|
|
||||||
ws[*node].weight = (1 - d) + d * s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
min_rank=max_rank=ws.begin()->second.weight;
|
void rank(WordMap &ws, size_t rankTime = 10) {
|
||||||
for(WordMap::iterator i = ws.begin(); i != ws.end(); i ++){
|
WordMap outSum;
|
||||||
if( i->second.weight < min_rank ){
|
Score wsdef, min_rank, max_rank;
|
||||||
min_rank = i->second.weight;
|
|
||||||
}
|
if(graph.size() == 0)
|
||||||
if( i->second.weight > max_rank ){
|
return;
|
||||||
max_rank = i->second.weight;
|
|
||||||
}
|
wsdef = 1.0 / graph.size();
|
||||||
|
|
||||||
|
for(Graph::iterator edges = graph.begin(); edges != graph.end(); ++edges) {
|
||||||
|
// edges->first start节点;edge->first end节点;edge->second 权重
|
||||||
|
ws[edges->first].word = edges->first;
|
||||||
|
ws[edges->first].weight = wsdef;
|
||||||
|
outSum[edges->first].weight = 0;
|
||||||
|
for(Edges::iterator edge = edges->second.begin(); edge != edges->second.end(); ++edge) {
|
||||||
|
outSum[edges->first].weight += edge->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//sort(nodeSet.begin(),nodeSet.end()); 是否需要排序?
|
||||||
|
for(size_t i = 0; i < rankTime; i++) {
|
||||||
|
for(NodeSet::iterator node = nodeSet.begin(); node != nodeSet.end(); node++) {
|
||||||
|
double s = 0;
|
||||||
|
for(Edges::iterator edge = graph[*node].begin(); edge != graph[*node].end(); edge++)
|
||||||
|
// edge->first end节点;edge->second 权重
|
||||||
|
s += edge->second / outSum[edge->first].weight * ws[edge->first].weight;
|
||||||
|
ws[*node].weight = (1 - d) + d * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
min_rank = max_rank = ws.begin()->second.weight;
|
||||||
|
for(WordMap::iterator i = ws.begin(); i != ws.end(); i ++) {
|
||||||
|
if(i->second.weight < min_rank) {
|
||||||
|
min_rank = i->second.weight;
|
||||||
|
}
|
||||||
|
if(i->second.weight > max_rank) {
|
||||||
|
max_rank = i->second.weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(WordMap::iterator i = ws.begin(); i != ws.end(); i ++) {
|
||||||
|
ws[i->first].weight = (i->second.weight - min_rank / 10.0) / (max_rank - min_rank / 10.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for(WordMap::iterator i = ws.begin(); i != ws.end(); i ++){
|
|
||||||
ws[i->first].weight = (i->second.weight - min_rank / 10.0) / (max_rank - min_rank / 10.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextRankExtractor(const string& dictPath,
|
TextRankExtractor(const string& dictPath,
|
||||||
const string& hmmFilePath,
|
const string& hmmFilePath,
|
||||||
const string& stopWordPath,
|
const string& stopWordPath,
|
||||||
const string& userDict = "")
|
const string& userDict = "")
|
||||||
: segment_(dictPath, hmmFilePath, userDict) {
|
: segment_(dictPath, hmmFilePath, userDict) {
|
||||||
LoadStopWordDict(stopWordPath);
|
LoadStopWordDict(stopWordPath);
|
||||||
}
|
}
|
||||||
TextRankExtractor(const DictTrie* dictTrie,
|
TextRankExtractor(const DictTrie* dictTrie,
|
||||||
const HMMModel* model,
|
const HMMModel* model,
|
||||||
const string& stopWordPath)
|
const string& stopWordPath)
|
||||||
: segment_(dictTrie, model) {
|
: segment_(dictTrie, model) {
|
||||||
LoadStopWordDict(stopWordPath);
|
LoadStopWordDict(stopWordPath);
|
||||||
}
|
}
|
||||||
TextRankExtractor(const Jieba& jieba, const string& stopWordPath) : segment_(jieba.GetDictTrie(), jieba.GetHMMModel()) {
|
TextRankExtractor(const Jieba& jieba, const string& stopWordPath) : segment_(jieba.GetDictTrie(), jieba.GetHMMModel()) {
|
||||||
LoadStopWordDict(stopWordPath);
|
LoadStopWordDict(stopWordPath);
|
||||||
}
|
}
|
||||||
|
@ -124,83 +128,83 @@ namespace cppjieba {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extract(const string& sentence, vector<string>& keywords, size_t topN) const {
|
void Extract(const string& sentence, vector<string>& keywords, size_t topN) const {
|
||||||
vector<Word> topWords;
|
vector<Word> topWords;
|
||||||
Extract(sentence, topWords, topN);
|
Extract(sentence, topWords, topN);
|
||||||
for (size_t i = 0; i < topWords.size(); i++) {
|
for(size_t i = 0; i < topWords.size(); i++) {
|
||||||
keywords.push_back(topWords[i].word);
|
keywords.push_back(topWords[i].word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extract(const string& sentence, vector<pair<string, double> >& keywords, size_t topN) const {
|
void Extract(const string& sentence, vector<pair<string, double> >& keywords, size_t topN) const {
|
||||||
vector<Word> topWords;
|
vector<Word> topWords;
|
||||||
Extract(sentence, topWords, topN);
|
Extract(sentence, topWords, topN);
|
||||||
for (size_t i = 0; i < topWords.size(); i++) {
|
for(size_t i = 0; i < topWords.size(); i++) {
|
||||||
keywords.push_back(pair<string, double>(topWords[i].word, topWords[i].weight));
|
keywords.push_back(pair<string, double>(topWords[i].word, topWords[i].weight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extract(const string& sentence, vector<Word>& keywords, size_t topN, size_t span=5,size_t rankTime=10) const {
|
void Extract(const string& sentence, vector<Word>& keywords, size_t topN, size_t span = 5, size_t rankTime = 10) const {
|
||||||
vector<string> words;
|
vector<string> words;
|
||||||
segment_.Cut(sentence, words);
|
segment_.Cut(sentence, words);
|
||||||
|
|
||||||
TextRankExtractor::WordGraph graph;
|
TextRankExtractor::WordGraph graph;
|
||||||
WordMap wordmap;
|
WordMap wordmap;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
for(size_t i=0; i < words.size(); i++){
|
for(size_t i = 0; i < words.size(); i++) {
|
||||||
size_t t = offset;
|
size_t t = offset;
|
||||||
offset += words[i].size();
|
offset += words[i].size();
|
||||||
if (IsSingleWord(words[i]) || stopWords_.find(words[i]) != stopWords_.end()) {
|
if(IsSingleWord(words[i]) || stopWords_.find(words[i]) != stopWords_.end()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
for(size_t j = i + 1, skip = 0; j < i + span + skip && j < words.size(); j++) {
|
||||||
|
if(IsSingleWord(words[j]) || stopWords_.find(words[j]) != stopWords_.end()) {
|
||||||
|
skip++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
graph.addEdge(words[i], words[j], 1);
|
||||||
|
}
|
||||||
|
wordmap[words[i]].offsets.push_back(t);
|
||||||
}
|
}
|
||||||
for(size_t j=i+1,skip=0;j<i+span+skip && j<words.size();j++){
|
if(offset != sentence.size()) {
|
||||||
if (IsSingleWord(words[j]) || stopWords_.find(words[j]) != stopWords_.end()) {
|
XLOG(ERROR) << "words illegal";
|
||||||
skip++;
|
return;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
graph.addEdge(words[i],words[j],1);
|
|
||||||
}
|
}
|
||||||
wordmap[words[i]].offsets.push_back(t);
|
|
||||||
}
|
|
||||||
if (offset != sentence.size()) {
|
|
||||||
XLOG(ERROR) << "words illegal";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
graph.rank(wordmap,rankTime);
|
graph.rank(wordmap, rankTime);
|
||||||
|
|
||||||
keywords.clear();
|
keywords.clear();
|
||||||
keywords.reserve(wordmap.size());
|
keywords.reserve(wordmap.size());
|
||||||
for (WordMap::iterator itr = wordmap.begin(); itr != wordmap.end(); ++itr) {
|
for(WordMap::iterator itr = wordmap.begin(); itr != wordmap.end(); ++itr) {
|
||||||
keywords.push_back(itr->second);
|
keywords.push_back(itr->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
topN = min(topN, keywords.size());
|
topN = min(topN, keywords.size());
|
||||||
partial_sort(keywords.begin(), keywords.begin() + topN, keywords.end(), Compare);
|
partial_sort(keywords.begin(), keywords.begin() + topN, keywords.end(), Compare);
|
||||||
keywords.resize(topN);
|
keywords.resize(topN);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void LoadStopWordDict(const string& filePath) {
|
void LoadStopWordDict(const string& filePath) {
|
||||||
ifstream ifs(filePath.c_str());
|
ifstream ifs(filePath.c_str());
|
||||||
XCHECK(ifs.is_open()) << "open " << filePath << " failed";
|
XCHECK(ifs.is_open()) << "open " << filePath << " failed";
|
||||||
string line ;
|
string line ;
|
||||||
while (getline(ifs, line)) {
|
while(getline(ifs, line)) {
|
||||||
stopWords_.insert(line);
|
stopWords_.insert(line);
|
||||||
}
|
}
|
||||||
assert(stopWords_.size());
|
assert(stopWords_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Compare(const Word &x,const Word &y){
|
static bool Compare(const Word &x, const Word &y) {
|
||||||
return x.weight > y.weight;
|
return x.weight > y.weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
MixSegment segment_;
|
MixSegment segment_;
|
||||||
unordered_set<string> stopWords_;
|
unordered_set<string> stopWords_;
|
||||||
}; // class TextRankExtractor
|
}; // class TextRankExtractor
|
||||||
|
|
||||||
inline ostream& operator << (ostream& os, const TextRankExtractor::Word& word) {
|
inline ostream& operator << (ostream& os, const TextRankExtractor::Word& word) {
|
||||||
return os << "{\"word\": \"" << word.word << "\", \"offset\": " << word.offsets << ", \"weight\": " << word.weight << "}";
|
return os << "{\"word\": \"" << word.word << "\", \"offset\": " << word.offsets << ", \"weight\": " << word.weight << "}";
|
||||||
}
|
}
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,9 +31,9 @@ using namespace std;
|
||||||
const size_t MAX_WORD_LENGTH = 512;
|
const size_t MAX_WORD_LENGTH = 512;
|
||||||
|
|
||||||
struct DictUnit {
|
struct DictUnit {
|
||||||
Unicode word;
|
Unicode word;
|
||||||
double weight;
|
double weight;
|
||||||
string tag;
|
string tag;
|
||||||
}; // struct DictUnit
|
}; // struct DictUnit
|
||||||
|
|
||||||
// for debugging
|
// for debugging
|
||||||
|
@ -44,148 +44,148 @@ struct DictUnit {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct Dag {
|
struct Dag {
|
||||||
RuneStr runestr;
|
RuneStr runestr;
|
||||||
// [offset, nexts.first]
|
// [offset, nexts.first]
|
||||||
limonp::LocalVector<pair<size_t, const DictUnit*> > nexts;
|
limonp::LocalVector<pair<size_t, const DictUnit*> > nexts;
|
||||||
const DictUnit * pInfo;
|
const DictUnit * pInfo;
|
||||||
double weight;
|
double weight;
|
||||||
size_t nextPos; // TODO
|
size_t nextPos; // TODO
|
||||||
Dag():runestr(), pInfo(NULL), weight(0.0), nextPos(0) {
|
Dag(): runestr(), pInfo(NULL), weight(0.0), nextPos(0) {
|
||||||
}
|
}
|
||||||
}; // struct Dag
|
}; // struct Dag
|
||||||
|
|
||||||
typedef Rune TrieKey;
|
typedef Rune TrieKey;
|
||||||
|
|
||||||
class TrieNode {
|
class TrieNode {
|
||||||
public :
|
public :
|
||||||
TrieNode(): next(NULL), ptValue(NULL) {
|
TrieNode(): next(NULL), ptValue(NULL) {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
typedef unordered_map<TrieKey, TrieNode*> NextMap;
|
typedef unordered_map<TrieKey, TrieNode*> NextMap;
|
||||||
NextMap *next;
|
NextMap *next;
|
||||||
const DictUnit *ptValue;
|
const DictUnit *ptValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Trie {
|
class Trie {
|
||||||
public:
|
public:
|
||||||
Trie(const vector<Unicode>& keys, const vector<const DictUnit*>& valuePointers)
|
Trie(const vector<Unicode>& keys, const vector<const DictUnit*>& valuePointers)
|
||||||
: root_(new TrieNode) {
|
: root_(new TrieNode) {
|
||||||
CreateTrie(keys, valuePointers);
|
CreateTrie(keys, valuePointers);
|
||||||
}
|
}
|
||||||
~Trie() {
|
~Trie() {
|
||||||
DeleteNode(root_);
|
DeleteNode(root_);
|
||||||
}
|
|
||||||
|
|
||||||
const DictUnit* Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
|
||||||
if (begin == end) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TrieNode* ptNode = root_;
|
const DictUnit* Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end) const {
|
||||||
TrieNode::NextMap::const_iterator citer;
|
if(begin == end) {
|
||||||
for (RuneStrArray::const_iterator it = begin; it != end; it++) {
|
return NULL;
|
||||||
if (NULL == ptNode->next) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
citer = ptNode->next->find(it->rune);
|
|
||||||
if (ptNode->next->end() == citer) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ptNode = citer->second;
|
|
||||||
}
|
|
||||||
return ptNode->ptValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Find(RuneStrArray::const_iterator begin,
|
|
||||||
RuneStrArray::const_iterator end,
|
|
||||||
vector<struct Dag>&res,
|
|
||||||
size_t max_word_len = MAX_WORD_LENGTH) const {
|
|
||||||
assert(root_ != NULL);
|
|
||||||
res.resize(end - begin);
|
|
||||||
|
|
||||||
const TrieNode *ptNode = NULL;
|
|
||||||
TrieNode::NextMap::const_iterator citer;
|
|
||||||
for (size_t i = 0; i < size_t(end - begin); i++) {
|
|
||||||
res[i].runestr = *(begin + i);
|
|
||||||
|
|
||||||
if (root_->next != NULL && root_->next->end() != (citer = root_->next->find(res[i].runestr.rune))) {
|
|
||||||
ptNode = citer->second;
|
|
||||||
} else {
|
|
||||||
ptNode = NULL;
|
|
||||||
}
|
|
||||||
if (ptNode != NULL) {
|
|
||||||
res[i].nexts.push_back(pair<size_t, const DictUnit*>(i, ptNode->ptValue));
|
|
||||||
} else {
|
|
||||||
res[i].nexts.push_back(pair<size_t, const DictUnit*>(i, static_cast<const DictUnit*>(NULL)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t j = i + 1; j < size_t(end - begin) && (j - i + 1) <= max_word_len; j++) {
|
|
||||||
if (ptNode == NULL || ptNode->next == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
citer = ptNode->next->find((begin + j)->rune);
|
|
||||||
if (ptNode->next->end() == citer) {
|
const TrieNode* ptNode = root_;
|
||||||
break;
|
TrieNode::NextMap::const_iterator citer;
|
||||||
|
for(RuneStrArray::const_iterator it = begin; it != end; it++) {
|
||||||
|
if(NULL == ptNode->next) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
citer = ptNode->next->find(it->rune);
|
||||||
|
if(ptNode->next->end() == citer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ptNode = citer->second;
|
||||||
}
|
}
|
||||||
ptNode = citer->second;
|
return ptNode->ptValue;
|
||||||
if (NULL != ptNode->ptValue) {
|
}
|
||||||
res[i].nexts.push_back(pair<size_t, const DictUnit*>(j, ptNode->ptValue));
|
|
||||||
|
void Find(RuneStrArray::const_iterator begin,
|
||||||
|
RuneStrArray::const_iterator end,
|
||||||
|
vector<struct Dag>&res,
|
||||||
|
size_t max_word_len = MAX_WORD_LENGTH) const {
|
||||||
|
assert(root_ != NULL);
|
||||||
|
res.resize(end - begin);
|
||||||
|
|
||||||
|
const TrieNode *ptNode = NULL;
|
||||||
|
TrieNode::NextMap::const_iterator citer;
|
||||||
|
for(size_t i = 0; i < size_t(end - begin); i++) {
|
||||||
|
res[i].runestr = *(begin + i);
|
||||||
|
|
||||||
|
if(root_->next != NULL && root_->next->end() != (citer = root_->next->find(res[i].runestr.rune))) {
|
||||||
|
ptNode = citer->second;
|
||||||
|
} else {
|
||||||
|
ptNode = NULL;
|
||||||
|
}
|
||||||
|
if(ptNode != NULL) {
|
||||||
|
res[i].nexts.push_back(pair<size_t, const DictUnit*>(i, ptNode->ptValue));
|
||||||
|
} else {
|
||||||
|
res[i].nexts.push_back(pair<size_t, const DictUnit*>(i, static_cast<const DictUnit*>(NULL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t j = i + 1; j < size_t(end - begin) && (j - i + 1) <= max_word_len; j++) {
|
||||||
|
if(ptNode == NULL || ptNode->next == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
citer = ptNode->next->find((begin + j)->rune);
|
||||||
|
if(ptNode->next->end() == citer) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptNode = citer->second;
|
||||||
|
if(NULL != ptNode->ptValue) {
|
||||||
|
res[i].nexts.push_back(pair<size_t, const DictUnit*>(j, ptNode->ptValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsertNode(const Unicode& key, const DictUnit* ptValue) {
|
|
||||||
if (key.begin() == key.end()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TrieNode::NextMap::const_iterator kmIter;
|
void InsertNode(const Unicode& key, const DictUnit* ptValue) {
|
||||||
TrieNode *ptNode = root_;
|
if(key.begin() == key.end()) {
|
||||||
for (Unicode::const_iterator citer = key.begin(); citer != key.end(); ++citer) {
|
return;
|
||||||
if (NULL == ptNode->next) {
|
}
|
||||||
ptNode->next = new TrieNode::NextMap;
|
|
||||||
}
|
|
||||||
kmIter = ptNode->next->find(*citer);
|
|
||||||
if (ptNode->next->end() == kmIter) {
|
|
||||||
TrieNode *nextNode = new TrieNode;
|
|
||||||
|
|
||||||
ptNode->next->insert(make_pair(*citer, nextNode));
|
TrieNode::NextMap::const_iterator kmIter;
|
||||||
ptNode = nextNode;
|
TrieNode *ptNode = root_;
|
||||||
} else {
|
for(Unicode::const_iterator citer = key.begin(); citer != key.end(); ++citer) {
|
||||||
ptNode = kmIter->second;
|
if(NULL == ptNode->next) {
|
||||||
}
|
ptNode->next = new TrieNode::NextMap;
|
||||||
}
|
}
|
||||||
assert(ptNode != NULL);
|
kmIter = ptNode->next->find(*citer);
|
||||||
ptNode->ptValue = ptValue;
|
if(ptNode->next->end() == kmIter) {
|
||||||
}
|
TrieNode *nextNode = new TrieNode;
|
||||||
|
|
||||||
private:
|
ptNode->next->insert(make_pair(*citer, nextNode));
|
||||||
void CreateTrie(const vector<Unicode>& keys, const vector<const DictUnit*>& valuePointers) {
|
ptNode = nextNode;
|
||||||
if (valuePointers.empty() || keys.empty()) {
|
} else {
|
||||||
return;
|
ptNode = kmIter->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(ptNode != NULL);
|
||||||
|
ptNode->ptValue = ptValue;
|
||||||
}
|
}
|
||||||
assert(keys.size() == valuePointers.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i < keys.size(); i++) {
|
private:
|
||||||
InsertNode(keys[i], valuePointers[i]);
|
void CreateTrie(const vector<Unicode>& keys, const vector<const DictUnit*>& valuePointers) {
|
||||||
}
|
if(valuePointers.empty() || keys.empty()) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
assert(keys.size() == valuePointers.size());
|
||||||
|
|
||||||
void DeleteNode(TrieNode* node) {
|
for(size_t i = 0; i < keys.size(); i++) {
|
||||||
if (NULL == node) {
|
InsertNode(keys[i], valuePointers[i]);
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
if (NULL != node->next) {
|
|
||||||
for (TrieNode::NextMap::iterator it = node->next->begin(); it != node->next->end(); ++it) {
|
|
||||||
DeleteNode(it->second);
|
|
||||||
}
|
|
||||||
delete node->next;
|
|
||||||
}
|
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrieNode* root_;
|
void DeleteNode(TrieNode* node) {
|
||||||
|
if(NULL == node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(NULL != node->next) {
|
||||||
|
for(TrieNode::NextMap::iterator it = node->next->begin(); it != node->next->end(); ++it) {
|
||||||
|
DeleteNode(it->second);
|
||||||
|
}
|
||||||
|
delete node->next;
|
||||||
|
}
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrieNode* root_;
|
||||||
}; // class Trie
|
}; // class Trie
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
||||||
|
|
|
@ -34,40 +34,40 @@ using std::vector;
|
||||||
typedef uint32_t Rune;
|
typedef uint32_t Rune;
|
||||||
|
|
||||||
struct Word {
|
struct Word {
|
||||||
string word;
|
string word;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t unicode_offset;
|
uint32_t unicode_offset;
|
||||||
uint32_t unicode_length;
|
uint32_t unicode_length;
|
||||||
Word(const string& w, uint32_t o)
|
Word(const string& w, uint32_t o)
|
||||||
: word(w), offset(o) {
|
: word(w), offset(o) {
|
||||||
}
|
}
|
||||||
Word(const string& w, uint32_t o, uint32_t unicode_offset, uint32_t unicode_length)
|
Word(const string& w, uint32_t o, uint32_t unicode_offset, uint32_t unicode_length)
|
||||||
: word(w), offset(o), unicode_offset(unicode_offset), unicode_length(unicode_length) {
|
: word(w), offset(o), unicode_offset(unicode_offset), unicode_length(unicode_length) {
|
||||||
}
|
}
|
||||||
}; // struct Word
|
}; // struct Word
|
||||||
|
|
||||||
inline std::ostream& operator << (std::ostream& os, const Word& w) {
|
inline std::ostream& operator << (std::ostream& os, const Word& w) {
|
||||||
return os << "{\"word\": \"" << w.word << "\", \"offset\": " << w.offset << "}";
|
return os << "{\"word\": \"" << w.word << "\", \"offset\": " << w.offset << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RuneStr {
|
struct RuneStr {
|
||||||
Rune rune;
|
Rune rune;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t unicode_offset;
|
uint32_t unicode_offset;
|
||||||
uint32_t unicode_length;
|
uint32_t unicode_length;
|
||||||
RuneStr(): rune(0), offset(0), len(0), unicode_offset(0), unicode_length(0) {
|
RuneStr(): rune(0), offset(0), len(0), unicode_offset(0), unicode_length(0) {
|
||||||
}
|
}
|
||||||
RuneStr(Rune r, uint32_t o, uint32_t l)
|
RuneStr(Rune r, uint32_t o, uint32_t l)
|
||||||
: rune(r), offset(o), len(l), unicode_offset(0), unicode_length(0) {
|
: rune(r), offset(o), len(l), unicode_offset(0), unicode_length(0) {
|
||||||
}
|
}
|
||||||
RuneStr(Rune r, uint32_t o, uint32_t l, uint32_t unicode_offset, uint32_t unicode_length)
|
RuneStr(Rune r, uint32_t o, uint32_t l, uint32_t unicode_offset, uint32_t unicode_length)
|
||||||
: rune(r), offset(o), len(l), unicode_offset(unicode_offset), unicode_length(unicode_length) {
|
: rune(r), offset(o), len(l), unicode_offset(unicode_offset), unicode_length(unicode_length) {
|
||||||
}
|
}
|
||||||
}; // struct RuneStr
|
}; // struct RuneStr
|
||||||
|
|
||||||
inline std::ostream& operator << (std::ostream& os, const RuneStr& r) {
|
inline std::ostream& operator << (std::ostream& os, const RuneStr& r) {
|
||||||
return os << "{\"rune\": \"" << r.rune << "\", \"offset\": " << r.offset << ", \"len\": " << r.len << "}";
|
return os << "{\"rune\": \"" << r.rune << "\", \"offset\": " << r.offset << ", \"len\": " << r.len << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef limonp::LocalVector<Rune> Unicode;
|
typedef limonp::LocalVector<Rune> Unicode;
|
||||||
|
@ -75,169 +75,169 @@ typedef limonp::LocalVector<struct RuneStr> RuneStrArray;
|
||||||
|
|
||||||
// [left, right]
|
// [left, right]
|
||||||
struct WordRange {
|
struct WordRange {
|
||||||
RuneStrArray::const_iterator left;
|
RuneStrArray::const_iterator left;
|
||||||
RuneStrArray::const_iterator right;
|
RuneStrArray::const_iterator right;
|
||||||
WordRange(RuneStrArray::const_iterator l, RuneStrArray::const_iterator r)
|
WordRange(RuneStrArray::const_iterator l, RuneStrArray::const_iterator r)
|
||||||
: left(l), right(r) {
|
: left(l), right(r) {
|
||||||
}
|
}
|
||||||
size_t Length() const {
|
size_t Length() const {
|
||||||
return right - left + 1;
|
return right - left + 1;
|
||||||
}
|
}
|
||||||
bool IsAllAscii() const {
|
bool IsAllAscii() const {
|
||||||
for (RuneStrArray::const_iterator iter = left; iter <= right; ++iter) {
|
for(RuneStrArray::const_iterator iter = left; iter <= right; ++iter) {
|
||||||
if (iter->rune >= 0x80) {
|
if(iter->rune >= 0x80) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}; // struct WordRange
|
}; // struct WordRange
|
||||||
|
|
||||||
struct RuneStrLite {
|
struct RuneStrLite {
|
||||||
uint32_t rune;
|
uint32_t rune;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
RuneStrLite(): rune(0), len(0) {
|
RuneStrLite(): rune(0), len(0) {
|
||||||
}
|
}
|
||||||
RuneStrLite(uint32_t r, uint32_t l): rune(r), len(l) {
|
RuneStrLite(uint32_t r, uint32_t l): rune(r), len(l) {
|
||||||
}
|
}
|
||||||
}; // struct RuneStrLite
|
}; // struct RuneStrLite
|
||||||
|
|
||||||
inline RuneStrLite DecodeRuneInString(const char* str, size_t len) {
|
inline RuneStrLite DecodeRuneInString(const char* str, size_t len) {
|
||||||
RuneStrLite rp(0, 0);
|
RuneStrLite rp(0, 0);
|
||||||
if (str == NULL || len == 0) {
|
if(str == NULL || len == 0) {
|
||||||
|
return rp;
|
||||||
|
}
|
||||||
|
if(!(str[0] & 0x80)) { // 0xxxxxxx
|
||||||
|
// 7bit, total 7bit
|
||||||
|
rp.rune = (uint8_t)(str[0]) & 0x7f;
|
||||||
|
rp.len = 1;
|
||||||
|
} else if((uint8_t)str[0] <= 0xdf && 1 < len) {
|
||||||
|
// 110xxxxxx
|
||||||
|
// 5bit, total 5bit
|
||||||
|
rp.rune = (uint8_t)(str[0]) & 0x1f;
|
||||||
|
|
||||||
|
// 6bit, total 11bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
||||||
|
rp.len = 2;
|
||||||
|
} else if((uint8_t)str[0] <= 0xef && 2 < len) { // 1110xxxxxx
|
||||||
|
// 4bit, total 4bit
|
||||||
|
rp.rune = (uint8_t)(str[0]) & 0x0f;
|
||||||
|
|
||||||
|
// 6bit, total 10bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
||||||
|
|
||||||
|
// 6bit, total 16bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[2]) & 0x3f;
|
||||||
|
|
||||||
|
rp.len = 3;
|
||||||
|
} else if((uint8_t)str[0] <= 0xf7 && 3 < len) { // 11110xxxx
|
||||||
|
// 3bit, total 3bit
|
||||||
|
rp.rune = (uint8_t)(str[0]) & 0x07;
|
||||||
|
|
||||||
|
// 6bit, total 9bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
||||||
|
|
||||||
|
// 6bit, total 15bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[2]) & 0x3f;
|
||||||
|
|
||||||
|
// 6bit, total 21bit
|
||||||
|
rp.rune <<= 6;
|
||||||
|
rp.rune |= (uint8_t)(str[3]) & 0x3f;
|
||||||
|
|
||||||
|
rp.len = 4;
|
||||||
|
} else {
|
||||||
|
rp.rune = 0;
|
||||||
|
rp.len = 0;
|
||||||
|
}
|
||||||
return rp;
|
return rp;
|
||||||
}
|
|
||||||
if (!(str[0] & 0x80)) { // 0xxxxxxx
|
|
||||||
// 7bit, total 7bit
|
|
||||||
rp.rune = (uint8_t)(str[0]) & 0x7f;
|
|
||||||
rp.len = 1;
|
|
||||||
} else if ((uint8_t)str[0] <= 0xdf && 1 < len) {
|
|
||||||
// 110xxxxxx
|
|
||||||
// 5bit, total 5bit
|
|
||||||
rp.rune = (uint8_t)(str[0]) & 0x1f;
|
|
||||||
|
|
||||||
// 6bit, total 11bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
|
||||||
rp.len = 2;
|
|
||||||
} else if((uint8_t)str[0] <= 0xef && 2 < len) { // 1110xxxxxx
|
|
||||||
// 4bit, total 4bit
|
|
||||||
rp.rune = (uint8_t)(str[0]) & 0x0f;
|
|
||||||
|
|
||||||
// 6bit, total 10bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
|
||||||
|
|
||||||
// 6bit, total 16bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[2]) & 0x3f;
|
|
||||||
|
|
||||||
rp.len = 3;
|
|
||||||
} else if((uint8_t)str[0] <= 0xf7 && 3 < len) { // 11110xxxx
|
|
||||||
// 3bit, total 3bit
|
|
||||||
rp.rune = (uint8_t)(str[0]) & 0x07;
|
|
||||||
|
|
||||||
// 6bit, total 9bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[1]) & 0x3f;
|
|
||||||
|
|
||||||
// 6bit, total 15bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[2]) & 0x3f;
|
|
||||||
|
|
||||||
// 6bit, total 21bit
|
|
||||||
rp.rune <<= 6;
|
|
||||||
rp.rune |= (uint8_t)(str[3]) & 0x3f;
|
|
||||||
|
|
||||||
rp.len = 4;
|
|
||||||
} else {
|
|
||||||
rp.rune = 0;
|
|
||||||
rp.len = 0;
|
|
||||||
}
|
|
||||||
return rp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DecodeRunesInString(const char* s, size_t len, RuneStrArray& runes) {
|
inline bool DecodeRunesInString(const char* s, size_t len, RuneStrArray& runes) {
|
||||||
runes.clear();
|
runes.clear();
|
||||||
runes.reserve(len / 2);
|
runes.reserve(len / 2);
|
||||||
for (uint32_t i = 0, j = 0; i < len;) {
|
for(uint32_t i = 0, j = 0; i < len;) {
|
||||||
RuneStrLite rp = DecodeRuneInString(s + i, len - i);
|
RuneStrLite rp = DecodeRuneInString(s + i, len - i);
|
||||||
if (rp.len == 0) {
|
if(rp.len == 0) {
|
||||||
runes.clear();
|
runes.clear();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
RuneStr x(rp.rune, i, rp.len, j, 1);
|
||||||
|
runes.push_back(x);
|
||||||
|
i += rp.len;
|
||||||
|
++j;
|
||||||
}
|
}
|
||||||
RuneStr x(rp.rune, i, rp.len, j, 1);
|
return true;
|
||||||
runes.push_back(x);
|
|
||||||
i += rp.len;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DecodeRunesInString(const string& s, RuneStrArray& runes) {
|
inline bool DecodeRunesInString(const string& s, RuneStrArray& runes) {
|
||||||
return DecodeRunesInString(s.c_str(), s.size(), runes);
|
return DecodeRunesInString(s.c_str(), s.size(), runes);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DecodeRunesInString(const char* s, size_t len, Unicode& unicode) {
|
inline bool DecodeRunesInString(const char* s, size_t len, Unicode& unicode) {
|
||||||
unicode.clear();
|
unicode.clear();
|
||||||
RuneStrArray runes;
|
RuneStrArray runes;
|
||||||
if (!DecodeRunesInString(s, len, runes)) {
|
if(!DecodeRunesInString(s, len, runes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unicode.reserve(runes.size());
|
unicode.reserve(runes.size());
|
||||||
for (size_t i = 0; i < runes.size(); i++) {
|
for(size_t i = 0; i < runes.size(); i++) {
|
||||||
unicode.push_back(runes[i].rune);
|
unicode.push_back(runes[i].rune);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsSingleWord(const string& str) {
|
inline bool IsSingleWord(const string& str) {
|
||||||
RuneStrLite rp = DecodeRuneInString(str.c_str(), str.size());
|
RuneStrLite rp = DecodeRuneInString(str.c_str(), str.size());
|
||||||
return rp.len == str.size();
|
return rp.len == str.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool DecodeRunesInString(const string& s, Unicode& unicode) {
|
inline bool DecodeRunesInString(const string& s, Unicode& unicode) {
|
||||||
return DecodeRunesInString(s.c_str(), s.size(), unicode);
|
return DecodeRunesInString(s.c_str(), s.size(), unicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Unicode DecodeRunesInString(const string& s) {
|
inline Unicode DecodeRunesInString(const string& s) {
|
||||||
Unicode result;
|
Unicode result;
|
||||||
DecodeRunesInString(s, result);
|
DecodeRunesInString(s, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// [left, right]
|
// [left, right]
|
||||||
inline Word GetWordFromRunes(const string& s, RuneStrArray::const_iterator left, RuneStrArray::const_iterator right) {
|
inline Word GetWordFromRunes(const string& s, RuneStrArray::const_iterator left, RuneStrArray::const_iterator right) {
|
||||||
assert(right->offset >= left->offset);
|
assert(right->offset >= left->offset);
|
||||||
uint32_t len = right->offset - left->offset + right->len;
|
uint32_t len = right->offset - left->offset + right->len;
|
||||||
uint32_t unicode_length = right->unicode_offset - left->unicode_offset + right->unicode_length;
|
uint32_t unicode_length = right->unicode_offset - left->unicode_offset + right->unicode_length;
|
||||||
return Word(s.substr(left->offset, len), left->offset, left->unicode_offset, unicode_length);
|
return Word(s.substr(left->offset, len), left->offset, left->unicode_offset, unicode_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string GetStringFromRunes(const string& s, RuneStrArray::const_iterator left, RuneStrArray::const_iterator right) {
|
inline string GetStringFromRunes(const string& s, RuneStrArray::const_iterator left, RuneStrArray::const_iterator right) {
|
||||||
assert(right->offset >= left->offset);
|
assert(right->offset >= left->offset);
|
||||||
uint32_t len = right->offset - left->offset + right->len;
|
uint32_t len = right->offset - left->offset + right->len;
|
||||||
return s.substr(left->offset, len);
|
return s.substr(left->offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetWordsFromWordRanges(const string& s, const vector<WordRange>& wrs, vector<Word>& words) {
|
inline void GetWordsFromWordRanges(const string& s, const vector<WordRange>& wrs, vector<Word>& words) {
|
||||||
for (size_t i = 0; i < wrs.size(); i++) {
|
for(size_t i = 0; i < wrs.size(); i++) {
|
||||||
words.push_back(GetWordFromRunes(s, wrs[i].left, wrs[i].right));
|
words.push_back(GetWordFromRunes(s, wrs[i].left, wrs[i].right));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vector<Word> GetWordsFromWordRanges(const string& s, const vector<WordRange>& wrs) {
|
inline vector<Word> GetWordsFromWordRanges(const string& s, const vector<WordRange>& wrs) {
|
||||||
vector<Word> result;
|
vector<Word> result;
|
||||||
GetWordsFromWordRanges(s, wrs, result);
|
GetWordsFromWordRanges(s, wrs, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetStringsFromWords(const vector<Word>& words, vector<string>& strs) {
|
inline void GetStringsFromWords(const vector<Word>& words, vector<string>& strs) {
|
||||||
strs.resize(words.size());
|
strs.resize(words.size());
|
||||||
for (size_t i = 0; i < words.size(); ++i) {
|
for(size_t i = 0; i < words.size(); ++i) {
|
||||||
strs[i] = words[i].word;
|
strs[i] = words[i].word;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace cppjieba
|
} // namespace cppjieba
|
||||||
|
|
|
@ -33,54 +33,54 @@ namespace limonp {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class ArgvContext {
|
class ArgvContext {
|
||||||
public :
|
public :
|
||||||
ArgvContext(int argc, const char* const * argv) {
|
ArgvContext(int argc, const char* const * argv) {
|
||||||
for(int i = 0; i < argc; i++) {
|
for(int i = 0; i < argc; i++) {
|
||||||
if(StartsWith(argv[i], "-")) {
|
if(StartsWith(argv[i], "-")) {
|
||||||
if(i + 1 < argc && !StartsWith(argv[i + 1], "-")) {
|
if(i + 1 < argc && !StartsWith(argv[i + 1], "-")) {
|
||||||
mpss_[argv[i]] = argv[i+1];
|
mpss_[argv[i]] = argv[i + 1];
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
sset_.insert(argv[i]);
|
sset_.insert(argv[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args_.push_back(argv[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
args_.push_back(argv[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
~ArgvContext() {
|
||||||
~ArgvContext() {
|
}
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream& operator << (ostream& os, const ArgvContext& args);
|
friend ostream& operator << (ostream& os, const ArgvContext& args);
|
||||||
string operator [](size_t i) const {
|
string operator [](size_t i) const {
|
||||||
if(i < args_.size()) {
|
if(i < args_.size()) {
|
||||||
return args_[i];
|
return args_[i];
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return "";
|
string operator [](const string& key) const {
|
||||||
}
|
map<string, string>::const_iterator it = mpss_.find(key);
|
||||||
string operator [](const string& key) const {
|
if(it != mpss_.end()) {
|
||||||
map<string, string>::const_iterator it = mpss_.find(key);
|
return it->second;
|
||||||
if(it != mpss_.end()) {
|
}
|
||||||
return it->second;
|
return "";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasKey(const string& key) const {
|
bool HasKey(const string& key) const {
|
||||||
if(mpss_.find(key) != mpss_.end() || sset_.find(key) != sset_.end()) {
|
if(mpss_.find(key) != mpss_.end() || sset_.find(key) != sset_.end()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<string> args_;
|
vector<string> args_;
|
||||||
map<string, string> mpss_;
|
map<string, string> mpss_;
|
||||||
set<string> sset_;
|
set<string> sset_;
|
||||||
}; // class ArgvContext
|
}; // class ArgvContext
|
||||||
|
|
||||||
inline ostream& operator << (ostream& os, const ArgvContext& args) {
|
inline ostream& operator << (ostream& os, const ArgvContext& args) {
|
||||||
return os<<args.args_<<args.mpss_<<args.sset_;
|
return os << args.args_ << args.mpss_ << args.sset_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -25,41 +25,41 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
template<class T>
|
template<class T>
|
||||||
class BlockingQueue: NonCopyable {
|
class BlockingQueue: NonCopyable {
|
||||||
public:
|
public:
|
||||||
BlockingQueue()
|
BlockingQueue()
|
||||||
: mutex_(), notEmpty_(mutex_), queue_() {
|
: mutex_(), notEmpty_(mutex_), queue_() {
|
||||||
}
|
|
||||||
|
|
||||||
void Push(const T& x) {
|
|
||||||
MutexLockGuard lock(mutex_);
|
|
||||||
queue_.push(x);
|
|
||||||
notEmpty_.Notify(); // Wait morphing saves us
|
|
||||||
}
|
|
||||||
|
|
||||||
T Pop() {
|
|
||||||
MutexLockGuard lock(mutex_);
|
|
||||||
// always use a while-loop, due to spurious wakeup
|
|
||||||
while (queue_.empty()) {
|
|
||||||
notEmpty_.Wait();
|
|
||||||
}
|
}
|
||||||
assert(!queue_.empty());
|
|
||||||
T front(queue_.front());
|
|
||||||
queue_.pop();
|
|
||||||
return front;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Size() const {
|
void Push(const T& x) {
|
||||||
MutexLockGuard lock(mutex_);
|
MutexLockGuard lock(mutex_);
|
||||||
return queue_.size();
|
queue_.push(x);
|
||||||
}
|
notEmpty_.Notify(); // Wait morphing saves us
|
||||||
bool Empty() const {
|
}
|
||||||
return Size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
T Pop() {
|
||||||
mutable MutexLock mutex_;
|
MutexLockGuard lock(mutex_);
|
||||||
Condition notEmpty_;
|
// always use a while-loop, due to spurious wakeup
|
||||||
std::queue<T> queue_;
|
while(queue_.empty()) {
|
||||||
|
notEmpty_.Wait();
|
||||||
|
}
|
||||||
|
assert(!queue_.empty());
|
||||||
|
T front(queue_.front());
|
||||||
|
queue_.pop();
|
||||||
|
return front;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Size() const {
|
||||||
|
MutexLockGuard lock(mutex_);
|
||||||
|
return queue_.size();
|
||||||
|
}
|
||||||
|
bool Empty() const {
|
||||||
|
return Size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable MutexLock mutex_;
|
||||||
|
Condition notEmpty_;
|
||||||
|
std::queue<T> queue_;
|
||||||
}; // class BlockingQueue
|
}; // class BlockingQueue
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -25,59 +25,59 @@ namespace limonp {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class BoundedBlockingQueue : NonCopyable {
|
class BoundedBlockingQueue : NonCopyable {
|
||||||
public:
|
public:
|
||||||
explicit BoundedBlockingQueue(size_t maxSize)
|
explicit BoundedBlockingQueue(size_t maxSize)
|
||||||
: mutex_(),
|
: mutex_(),
|
||||||
notEmpty_(mutex_),
|
notEmpty_(mutex_),
|
||||||
notFull_(mutex_),
|
notFull_(mutex_),
|
||||||
queue_(maxSize) {
|
queue_(maxSize) {
|
||||||
}
|
|
||||||
|
|
||||||
void Push(const T& x) {
|
|
||||||
MutexLockGuard lock(mutex_);
|
|
||||||
while (queue_.Full()) {
|
|
||||||
notFull_.Wait();
|
|
||||||
}
|
}
|
||||||
assert(!queue_.Full());
|
|
||||||
queue_.Push(x);
|
|
||||||
notEmpty_.Notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
T Pop() {
|
void Push(const T& x) {
|
||||||
MutexLockGuard lock(mutex_);
|
MutexLockGuard lock(mutex_);
|
||||||
while (queue_.Empty()) {
|
while(queue_.Full()) {
|
||||||
notEmpty_.Wait();
|
notFull_.Wait();
|
||||||
|
}
|
||||||
|
assert(!queue_.Full());
|
||||||
|
queue_.Push(x);
|
||||||
|
notEmpty_.Notify();
|
||||||
}
|
}
|
||||||
assert(!queue_.Empty());
|
|
||||||
T res = queue_.Pop();
|
|
||||||
notFull_.Notify();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Empty() const {
|
T Pop() {
|
||||||
MutexLockGuard lock(mutex_);
|
MutexLockGuard lock(mutex_);
|
||||||
return queue_.Empty();
|
while(queue_.Empty()) {
|
||||||
}
|
notEmpty_.Wait();
|
||||||
|
}
|
||||||
|
assert(!queue_.Empty());
|
||||||
|
T res = queue_.Pop();
|
||||||
|
notFull_.Notify();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool Full() const {
|
bool Empty() const {
|
||||||
MutexLockGuard lock(mutex_);
|
MutexLockGuard lock(mutex_);
|
||||||
return queue_.Full();
|
return queue_.Empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
bool Full() const {
|
||||||
MutexLockGuard lock(mutex_);
|
MutexLockGuard lock(mutex_);
|
||||||
return queue_.size();
|
return queue_.Full();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t capacity() const {
|
size_t size() const {
|
||||||
return queue_.capacity();
|
MutexLockGuard lock(mutex_);
|
||||||
}
|
return queue_.size();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
size_t capacity() const {
|
||||||
mutable MutexLock mutex_;
|
return queue_.capacity();
|
||||||
Condition notEmpty_;
|
}
|
||||||
Condition notFull_;
|
|
||||||
BoundedQueue<T> queue_;
|
private:
|
||||||
|
mutable MutexLock mutex_;
|
||||||
|
Condition notEmpty_;
|
||||||
|
Condition notFull_;
|
||||||
|
BoundedQueue<T> queue_;
|
||||||
}; // class BoundedBlockingQueue
|
}; // class BoundedBlockingQueue
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -27,55 +27,55 @@ namespace limonp {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
template<class T>
|
template<class T>
|
||||||
class BoundedQueue {
|
class BoundedQueue {
|
||||||
public:
|
public:
|
||||||
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular_buffer_(capacity) {
|
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular_buffer_(capacity) {
|
||||||
head_ = 0;
|
head_ = 0;
|
||||||
tail_ = 0;
|
tail_ = 0;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
assert(capacity_);
|
assert(capacity_);
|
||||||
}
|
}
|
||||||
~BoundedQueue() {
|
~BoundedQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
head_ = 0;
|
head_ = 0;
|
||||||
tail_ = 0;
|
tail_ = 0;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
bool Empty() const {
|
bool Empty() const {
|
||||||
return !size_;
|
return !size_;
|
||||||
}
|
}
|
||||||
bool Full() const {
|
bool Full() const {
|
||||||
return capacity_ == size_;
|
return capacity_ == size_;
|
||||||
}
|
}
|
||||||
size_t Size() const {
|
size_t Size() const {
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
size_t Capacity() const {
|
size_t Capacity() const {
|
||||||
return capacity_;
|
return capacity_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Push(const T& t) {
|
void Push(const T& t) {
|
||||||
assert(!Full());
|
assert(!Full());
|
||||||
circular_buffer_[tail_] = t;
|
circular_buffer_[tail_] = t;
|
||||||
tail_ = (tail_ + 1) % capacity_;
|
tail_ = (tail_ + 1) % capacity_;
|
||||||
size_ ++;
|
size_ ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
T Pop() {
|
T Pop() {
|
||||||
assert(!Empty());
|
assert(!Empty());
|
||||||
size_t oldPos = head_;
|
size_t oldPos = head_;
|
||||||
head_ = (head_ + 1) % capacity_;
|
head_ = (head_ + 1) % capacity_;
|
||||||
size_ --;
|
size_ --;
|
||||||
return circular_buffer_[oldPos];
|
return circular_buffer_[oldPos];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t head_;
|
size_t head_;
|
||||||
size_t tail_;
|
size_t tail_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
const size_t capacity_;
|
const size_t capacity_;
|
||||||
vector<T> circular_buffer_;
|
vector<T> circular_buffer_;
|
||||||
|
|
||||||
}; // class BoundedQueue
|
}; // class BoundedQueue
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -22,201 +22,201 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
class ClosureInterface {
|
class ClosureInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~ClosureInterface() {
|
virtual ~ClosureInterface() {
|
||||||
}
|
}
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Funct>
|
template <class Funct>
|
||||||
class Closure0: public ClosureInterface {
|
class Closure0: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
Closure0(Funct fun) {
|
Closure0(Funct fun) {
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
}
|
}
|
||||||
virtual ~Closure0() {
|
virtual ~Closure0() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(*fun_)();
|
(*fun_)();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Funct, class Arg1>
|
template <class Funct, class Arg1>
|
||||||
class Closure1: public ClosureInterface {
|
class Closure1: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
Closure1(Funct fun, Arg1 arg1) {
|
Closure1(Funct fun, Arg1 arg1) {
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
}
|
}
|
||||||
virtual ~Closure1() {
|
virtual ~Closure1() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(*fun_)(arg1_);
|
(*fun_)(arg1_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Funct, class Arg1, class Arg2>
|
template <class Funct, class Arg1, class Arg2>
|
||||||
class Closure2: public ClosureInterface {
|
class Closure2: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
Closure2(Funct fun, Arg1 arg1, Arg2 arg2) {
|
Closure2(Funct fun, Arg1 arg1, Arg2 arg2) {
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
arg2_ = arg2;
|
arg2_ = arg2;
|
||||||
}
|
}
|
||||||
virtual ~Closure2() {
|
virtual ~Closure2() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(*fun_)(arg1_, arg2_);
|
(*fun_)(arg1_, arg2_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
Arg2 arg2_;
|
Arg2 arg2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Funct, class Arg1, class Arg2, class Arg3>
|
template <class Funct, class Arg1, class Arg2, class Arg3>
|
||||||
class Closure3: public ClosureInterface {
|
class Closure3: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
Closure3(Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
Closure3(Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
arg2_ = arg2;
|
arg2_ = arg2;
|
||||||
arg3_ = arg3;
|
arg3_ = arg3;
|
||||||
}
|
}
|
||||||
virtual ~Closure3() {
|
virtual ~Closure3() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(*fun_)(arg1_, arg2_, arg3_);
|
(*fun_)(arg1_, arg2_, arg3_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
Arg2 arg2_;
|
Arg2 arg2_;
|
||||||
Arg3 arg3_;
|
Arg3 arg3_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Obj, class Funct>
|
template <class Obj, class Funct>
|
||||||
class ObjClosure0: public ClosureInterface {
|
class ObjClosure0: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
ObjClosure0(Obj* p, Funct fun) {
|
ObjClosure0(Obj* p, Funct fun) {
|
||||||
p_ = p;
|
p_ = p;
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
}
|
}
|
||||||
virtual ~ObjClosure0() {
|
virtual ~ObjClosure0() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(p_->*fun_)();
|
(p_->*fun_)();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Obj* p_;
|
Obj* p_;
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Obj, class Funct, class Arg1>
|
template <class Obj, class Funct, class Arg1>
|
||||||
class ObjClosure1: public ClosureInterface {
|
class ObjClosure1: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
ObjClosure1(Obj* p, Funct fun, Arg1 arg1) {
|
ObjClosure1(Obj* p, Funct fun, Arg1 arg1) {
|
||||||
p_ = p;
|
p_ = p;
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
}
|
}
|
||||||
virtual ~ObjClosure1() {
|
virtual ~ObjClosure1() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(p_->*fun_)(arg1_);
|
(p_->*fun_)(arg1_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Obj* p_;
|
Obj* p_;
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Obj, class Funct, class Arg1, class Arg2>
|
template <class Obj, class Funct, class Arg1, class Arg2>
|
||||||
class ObjClosure2: public ClosureInterface {
|
class ObjClosure2: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
ObjClosure2(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2) {
|
ObjClosure2(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2) {
|
||||||
p_ = p;
|
p_ = p;
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
arg2_ = arg2;
|
arg2_ = arg2;
|
||||||
}
|
}
|
||||||
virtual ~ObjClosure2() {
|
virtual ~ObjClosure2() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(p_->*fun_)(arg1_, arg2_);
|
(p_->*fun_)(arg1_, arg2_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Obj* p_;
|
Obj* p_;
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
Arg2 arg2_;
|
Arg2 arg2_;
|
||||||
};
|
};
|
||||||
template <class Obj, class Funct, class Arg1, class Arg2, class Arg3>
|
template <class Obj, class Funct, class Arg1, class Arg2, class Arg3>
|
||||||
class ObjClosure3: public ClosureInterface {
|
class ObjClosure3: public ClosureInterface {
|
||||||
public:
|
public:
|
||||||
ObjClosure3(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
ObjClosure3(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||||
p_ = p;
|
p_ = p;
|
||||||
fun_ = fun;
|
fun_ = fun;
|
||||||
arg1_ = arg1;
|
arg1_ = arg1;
|
||||||
arg2_ = arg2;
|
arg2_ = arg2;
|
||||||
arg3_ = arg3;
|
arg3_ = arg3;
|
||||||
}
|
}
|
||||||
virtual ~ObjClosure3() {
|
virtual ~ObjClosure3() {
|
||||||
}
|
}
|
||||||
virtual void Run() {
|
virtual void Run() {
|
||||||
(p_->*fun_)(arg1_, arg2_, arg3_);
|
(p_->*fun_)(arg1_, arg2_, arg3_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Obj* p_;
|
Obj* p_;
|
||||||
Funct fun_;
|
Funct fun_;
|
||||||
Arg1 arg1_;
|
Arg1 arg1_;
|
||||||
Arg2 arg2_;
|
Arg2 arg2_;
|
||||||
Arg3 arg3_;
|
Arg3 arg3_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class R>
|
template<class R>
|
||||||
ClosureInterface* NewClosure(R (*fun)()) {
|
ClosureInterface* NewClosure(R(*fun)()) {
|
||||||
return new Closure0<R (*)()>(fun);
|
return new Closure0<R(*)()>(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Arg1>
|
template<class R, class Arg1>
|
||||||
ClosureInterface* NewClosure(R (*fun)(Arg1), Arg1 arg1) {
|
ClosureInterface* NewClosure(R(*fun)(Arg1), Arg1 arg1) {
|
||||||
return new Closure1<R (*)(Arg1), Arg1>(fun, arg1);
|
return new Closure1<R(*)(Arg1), Arg1>(fun, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Arg1, class Arg2>
|
template<class R, class Arg1, class Arg2>
|
||||||
ClosureInterface* NewClosure(R (*fun)(Arg1, Arg2), Arg1 arg1, Arg2 arg2) {
|
ClosureInterface* NewClosure(R(*fun)(Arg1, Arg2), Arg1 arg1, Arg2 arg2) {
|
||||||
return new Closure2<R (*)(Arg1, Arg2), Arg1, Arg2>(fun, arg1, arg2);
|
return new Closure2<R(*)(Arg1, Arg2), Arg1, Arg2>(fun, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Arg1, class Arg2, class Arg3>
|
template<class R, class Arg1, class Arg2, class Arg3>
|
||||||
ClosureInterface* NewClosure(R (*fun)(Arg1, Arg2, Arg3), Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
ClosureInterface* NewClosure(R(*fun)(Arg1, Arg2, Arg3), Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||||
return new Closure3<R (*)(Arg1, Arg2, Arg3), Arg1, Arg2, Arg3>(fun, arg1, arg2, arg3);
|
return new Closure3<R(*)(Arg1, Arg2, Arg3), Arg1, Arg2, Arg3>(fun, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Obj>
|
template<class R, class Obj>
|
||||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)()) {
|
ClosureInterface* NewClosure(Obj* obj, R(Obj::* fun)()) {
|
||||||
return new ObjClosure0<Obj, R (Obj::* )()>(obj, fun);
|
return new ObjClosure0<Obj, R(Obj::*)()>(obj, fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Obj, class Arg1>
|
template<class R, class Obj, class Arg1>
|
||||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)(Arg1), Arg1 arg1) {
|
ClosureInterface* NewClosure(Obj* obj, R(Obj::* fun)(Arg1), Arg1 arg1) {
|
||||||
return new ObjClosure1<Obj, R (Obj::* )(Arg1), Arg1>(obj, fun, arg1);
|
return new ObjClosure1<Obj, R(Obj::*)(Arg1), Arg1>(obj, fun, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Obj, class Arg1, class Arg2>
|
template<class R, class Obj, class Arg1, class Arg2>
|
||||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)(Arg1, Arg2), Arg1 arg1, Arg2 arg2) {
|
ClosureInterface* NewClosure(Obj* obj, R(Obj::* fun)(Arg1, Arg2), Arg1 arg1, Arg2 arg2) {
|
||||||
return new ObjClosure2<Obj, R (Obj::*)(Arg1, Arg2), Arg1, Arg2>(obj, fun, arg1, arg2);
|
return new ObjClosure2<Obj, R(Obj::*)(Arg1, Arg2), Arg1, Arg2>(obj, fun, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R, class Obj, class Arg1, class Arg2, class Arg3>
|
template<class R, class Obj, class Arg1, class Arg2, class Arg3>
|
||||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)(Arg1, Arg2, Arg3), Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
ClosureInterface* NewClosure(Obj* obj, R(Obj::* fun)(Arg1, Arg2, Arg3), Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||||
return new ObjClosure3<Obj, R (Obj::*)(Arg1, Arg2, Arg3), Arg1, Arg2, Arg3>(obj, fun, arg1, arg2, arg3);
|
return new ObjClosure3<Obj, R(Obj::*)(Arg1, Arg2, Arg3), Arg1, Arg2, Arg3>(obj, fun, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -27,21 +27,21 @@ namespace limonp {
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
enum Color {
|
enum Color {
|
||||||
BLACK = 30,
|
BLACK = 30,
|
||||||
RED,
|
RED,
|
||||||
GREEN,
|
GREEN,
|
||||||
YELLOW,
|
YELLOW,
|
||||||
BLUE,
|
BLUE,
|
||||||
PURPLE
|
PURPLE
|
||||||
}; // enum Color
|
}; // enum Color
|
||||||
|
|
||||||
static void ColorPrintln(enum Color color, const char * fmt, ...) {
|
static void ColorPrintln(enum Color color, const char * fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
printf("\033[0;%dm", color);
|
printf("\033[0;%dm", color);
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vprintf(fmt, ap);
|
vprintf(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
printf("\033[0m\n"); // if not \n , in some situation , the next lines will be set the same color unexpectedly
|
printf("\033[0m\n"); // if not \n , in some situation , the next lines will be set the same color unexpectedly
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -24,31 +24,31 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
class Condition : NonCopyable {
|
class Condition : NonCopyable {
|
||||||
public:
|
public:
|
||||||
explicit Condition(MutexLock& mutex)
|
explicit Condition(MutexLock& mutex)
|
||||||
: mutex_(mutex) {
|
: mutex_(mutex) {
|
||||||
XCHECK(!pthread_cond_init(&pcond_, NULL));
|
XCHECK(!pthread_cond_init(&pcond_, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
~Condition() {
|
~Condition() {
|
||||||
XCHECK(!pthread_cond_destroy(&pcond_));
|
XCHECK(!pthread_cond_destroy(&pcond_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wait() {
|
void Wait() {
|
||||||
XCHECK(!pthread_cond_wait(&pcond_, mutex_.GetPthreadMutex()));
|
XCHECK(!pthread_cond_wait(&pcond_, mutex_.GetPthreadMutex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notify() {
|
void Notify() {
|
||||||
XCHECK(!pthread_cond_signal(&pcond_));
|
XCHECK(!pthread_cond_signal(&pcond_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyAll() {
|
void NotifyAll() {
|
||||||
XCHECK(!pthread_cond_broadcast(&pcond_));
|
XCHECK(!pthread_cond_broadcast(&pcond_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutexLock& mutex_;
|
MutexLock& mutex_;
|
||||||
pthread_cond_t pcond_;
|
pthread_cond_t pcond_;
|
||||||
}; // class Condition
|
}; // class Condition
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -34,86 +34,86 @@ namespace limonp {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
explicit Config(const string& filePath) {
|
explicit Config(const string& filePath) {
|
||||||
LoadFile(filePath);
|
LoadFile(filePath);
|
||||||
}
|
|
||||||
|
|
||||||
operator bool () {
|
|
||||||
return !map_.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
string Get(const string& key, const string& defaultvalue) const {
|
|
||||||
map<string, string>::const_iterator it = map_.find(key);
|
|
||||||
if(map_.end() != it) {
|
|
||||||
return it->second;
|
|
||||||
}
|
}
|
||||||
return defaultvalue;
|
|
||||||
}
|
|
||||||
int Get(const string& key, int defaultvalue) const {
|
|
||||||
string str = Get(key, "");
|
|
||||||
if("" == str) {
|
|
||||||
return defaultvalue;
|
|
||||||
}
|
|
||||||
return atoi(str.c_str());
|
|
||||||
}
|
|
||||||
const char* operator [] (const char* key) const {
|
|
||||||
if(NULL == key) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
map<string, string>::const_iterator it = map_.find(key);
|
|
||||||
if(map_.end() != it) {
|
|
||||||
return it->second.c_str();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
string GetConfigInfo() const {
|
operator bool () {
|
||||||
string res;
|
return !map_.empty();
|
||||||
res << *this;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void LoadFile(const string& filePath) {
|
|
||||||
ifstream ifs(filePath.c_str());
|
|
||||||
assert(ifs);
|
|
||||||
string line;
|
|
||||||
vector<string> vecBuf;
|
|
||||||
size_t lineno = 0;
|
|
||||||
while(getline(ifs, line)) {
|
|
||||||
lineno ++;
|
|
||||||
Trim(line);
|
|
||||||
if(line.empty() || StartsWith(line, "#")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vecBuf.clear();
|
|
||||||
Split(line, vecBuf, "=");
|
|
||||||
if(2 != vecBuf.size()) {
|
|
||||||
fprintf(stderr, "line[%s] illegal.\n", line.c_str());
|
|
||||||
assert(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
string& key = vecBuf[0];
|
|
||||||
string& value = vecBuf[1];
|
|
||||||
Trim(key);
|
|
||||||
Trim(value);
|
|
||||||
if(!map_.insert(make_pair(key, value)).second) {
|
|
||||||
fprintf(stderr, "key[%s] already exits.\n", key.c_str());
|
|
||||||
assert(false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ifs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream& operator << (ostream& os, const Config& config);
|
string Get(const string& key, const string& defaultvalue) const {
|
||||||
|
map<string, string>::const_iterator it = map_.find(key);
|
||||||
|
if(map_.end() != it) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return defaultvalue;
|
||||||
|
}
|
||||||
|
int Get(const string& key, int defaultvalue) const {
|
||||||
|
string str = Get(key, "");
|
||||||
|
if("" == str) {
|
||||||
|
return defaultvalue;
|
||||||
|
}
|
||||||
|
return atoi(str.c_str());
|
||||||
|
}
|
||||||
|
const char* operator [](const char* key) const {
|
||||||
|
if(NULL == key) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
map<string, string>::const_iterator it = map_.find(key);
|
||||||
|
if(map_.end() != it) {
|
||||||
|
return it->second.c_str();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
map<string, string> map_;
|
string GetConfigInfo() const {
|
||||||
|
string res;
|
||||||
|
res << *this;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void LoadFile(const string& filePath) {
|
||||||
|
ifstream ifs(filePath.c_str());
|
||||||
|
assert(ifs);
|
||||||
|
string line;
|
||||||
|
vector<string> vecBuf;
|
||||||
|
size_t lineno = 0;
|
||||||
|
while(getline(ifs, line)) {
|
||||||
|
lineno ++;
|
||||||
|
Trim(line);
|
||||||
|
if(line.empty() || StartsWith(line, "#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vecBuf.clear();
|
||||||
|
Split(line, vecBuf, "=");
|
||||||
|
if(2 != vecBuf.size()) {
|
||||||
|
fprintf(stderr, "line[%s] illegal.\n", line.c_str());
|
||||||
|
assert(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
string& key = vecBuf[0];
|
||||||
|
string& value = vecBuf[1];
|
||||||
|
Trim(key);
|
||||||
|
Trim(value);
|
||||||
|
if(!map_.insert(make_pair(key, value)).second) {
|
||||||
|
fprintf(stderr, "key[%s] already exits.\n", key.c_str());
|
||||||
|
assert(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ifs.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend ostream& operator << (ostream& os, const Config& config);
|
||||||
|
|
||||||
|
map<string, string> map_;
|
||||||
}; // class Config
|
}; // class Config
|
||||||
|
|
||||||
inline ostream& operator << (ostream& os, const Config& config) {
|
inline ostream& operator << (ostream& os, const Config& config) {
|
||||||
return os << config.map_;
|
return os << config.map_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -33,58 +33,58 @@ namespace limonp {
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
class FileLock {
|
class FileLock {
|
||||||
public:
|
public:
|
||||||
FileLock() : fd_(-1), ok_(true) {
|
FileLock() : fd_(-1), ok_(true) {
|
||||||
}
|
|
||||||
~FileLock() {
|
|
||||||
if(fd_ > 0) {
|
|
||||||
Close();
|
|
||||||
}
|
}
|
||||||
}
|
~FileLock() {
|
||||||
void Open(const string& fname) {
|
if(fd_ > 0) {
|
||||||
assert(fd_ == -1);
|
Close();
|
||||||
fd_ = open(fname.c_str(), O_RDWR | O_CREAT, 0644);
|
}
|
||||||
if(fd_ < 0) {
|
|
||||||
ok_ = false;
|
|
||||||
err_ = strerror(errno);
|
|
||||||
}
|
}
|
||||||
}
|
void Open(const string& fname) {
|
||||||
void Close() {
|
assert(fd_ == -1);
|
||||||
::close(fd_);
|
fd_ = open(fname.c_str(), O_RDWR | O_CREAT, 0644);
|
||||||
}
|
if(fd_ < 0) {
|
||||||
void Lock() {
|
ok_ = false;
|
||||||
if(LockOrUnlock(fd_, true) < 0) {
|
err_ = strerror(errno);
|
||||||
ok_ = false;
|
}
|
||||||
err_ = strerror(errno);
|
|
||||||
}
|
}
|
||||||
}
|
void Close() {
|
||||||
void UnLock() {
|
::close(fd_);
|
||||||
if(LockOrUnlock(fd_, false) < 0) {
|
}
|
||||||
ok_ = false;
|
void Lock() {
|
||||||
err_ = strerror(errno);
|
if(LockOrUnlock(fd_, true) < 0) {
|
||||||
|
ok_ = false;
|
||||||
|
err_ = strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void UnLock() {
|
||||||
|
if(LockOrUnlock(fd_, false) < 0) {
|
||||||
|
ok_ = false;
|
||||||
|
err_ = strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool Ok() const {
|
||||||
|
return ok_;
|
||||||
|
}
|
||||||
|
string Error() const {
|
||||||
|
return err_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static int LockOrUnlock(int fd, bool lock) {
|
||||||
|
errno = 0;
|
||||||
|
struct flock f;
|
||||||
|
memset(&f, 0, sizeof(f));
|
||||||
|
f.l_type = (lock ? F_WRLCK : F_UNLCK);
|
||||||
|
f.l_whence = SEEK_SET;
|
||||||
|
f.l_start = 0;
|
||||||
|
f.l_len = 0; // Lock/unlock entire file
|
||||||
|
return fcntl(fd, F_SETLK, &f);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
bool Ok() const {
|
|
||||||
return ok_;
|
|
||||||
}
|
|
||||||
string Error() const {
|
|
||||||
return err_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
static int LockOrUnlock(int fd, bool lock) {
|
|
||||||
errno = 0;
|
|
||||||
struct flock f;
|
|
||||||
memset(&f, 0, sizeof(f));
|
|
||||||
f.l_type = (lock ? F_WRLCK : F_UNLCK);
|
|
||||||
f.l_whence = SEEK_SET;
|
|
||||||
f.l_start = 0;
|
|
||||||
f.l_len = 0; // Lock/unlock entire file
|
|
||||||
return fcntl(fd, F_SETLK, &f);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd_;
|
int fd_;
|
||||||
bool ok_;
|
bool ok_;
|
||||||
string err_;
|
string err_;
|
||||||
}; // class FileLock
|
}; // class FileLock
|
||||||
|
|
||||||
}// namespace limonp
|
}// namespace limonp
|
||||||
|
|
|
@ -33,123 +33,123 @@ using namespace std;
|
||||||
const size_t LOCAL_VECTOR_BUFFER_SIZE = 16;
|
const size_t LOCAL_VECTOR_BUFFER_SIZE = 16;
|
||||||
template <class T>
|
template <class T>
|
||||||
class LocalVector {
|
class LocalVector {
|
||||||
public:
|
public:
|
||||||
typedef const T* const_iterator ;
|
typedef const T* const_iterator ;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
private:
|
private:
|
||||||
T buffer_[LOCAL_VECTOR_BUFFER_SIZE];
|
T buffer_[LOCAL_VECTOR_BUFFER_SIZE];
|
||||||
T * ptr_;
|
T * ptr_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
size_t capacity_;
|
size_t capacity_;
|
||||||
public:
|
public:
|
||||||
LocalVector() {
|
LocalVector() {
|
||||||
init_();
|
init_();
|
||||||
};
|
};
|
||||||
LocalVector(const LocalVector<T>& vec) {
|
LocalVector(const LocalVector<T>& vec) {
|
||||||
init_();
|
init_();
|
||||||
*this = vec;
|
*this = vec;
|
||||||
}
|
|
||||||
LocalVector(const_iterator begin, const_iterator end) { // TODO: make it faster
|
|
||||||
init_();
|
|
||||||
while(begin != end) {
|
|
||||||
push_back(*begin++);
|
|
||||||
}
|
}
|
||||||
}
|
LocalVector(const_iterator begin, const_iterator end) { // TODO: make it faster
|
||||||
LocalVector(size_t size, const T& t) { // TODO: make it faster
|
init_();
|
||||||
init_();
|
while(begin != end) {
|
||||||
while(size--) {
|
push_back(*begin++);
|
||||||
push_back(t);
|
}
|
||||||
}
|
}
|
||||||
}
|
LocalVector(size_t size, const T& t) { // TODO: make it faster
|
||||||
~LocalVector() {
|
init_();
|
||||||
if(ptr_ != buffer_) {
|
while(size--) {
|
||||||
free(ptr_);
|
push_back(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
~LocalVector() {
|
||||||
public:
|
if(ptr_ != buffer_) {
|
||||||
LocalVector<T>& operator = (const LocalVector<T>& vec) {
|
free(ptr_);
|
||||||
clear();
|
}
|
||||||
size_ = vec.size();
|
};
|
||||||
capacity_ = vec.capacity();
|
public:
|
||||||
if(vec.buffer_ == vec.ptr_) {
|
LocalVector<T>& operator = (const LocalVector<T>& vec) {
|
||||||
memcpy(buffer_, vec.buffer_, sizeof(T) * size_);
|
clear();
|
||||||
ptr_ = buffer_;
|
size_ = vec.size();
|
||||||
} else {
|
capacity_ = vec.capacity();
|
||||||
ptr_ = (T*) malloc(vec.capacity() * sizeof(T));
|
if(vec.buffer_ == vec.ptr_) {
|
||||||
assert(ptr_);
|
memcpy(buffer_, vec.buffer_, sizeof(T) * size_);
|
||||||
memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T));
|
ptr_ = buffer_;
|
||||||
|
} else {
|
||||||
|
ptr_ = (T*) malloc(vec.capacity() * sizeof(T));
|
||||||
|
assert(ptr_);
|
||||||
|
memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
return *this;
|
private:
|
||||||
}
|
void init_() {
|
||||||
private:
|
ptr_ = buffer_;
|
||||||
void init_() {
|
size_ = 0;
|
||||||
ptr_ = buffer_;
|
capacity_ = LOCAL_VECTOR_BUFFER_SIZE;
|
||||||
size_ = 0;
|
|
||||||
capacity_ = LOCAL_VECTOR_BUFFER_SIZE;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
T& operator [] (size_t i) {
|
|
||||||
return ptr_[i];
|
|
||||||
}
|
|
||||||
const T& operator [] (size_t i) const {
|
|
||||||
return ptr_[i];
|
|
||||||
}
|
|
||||||
void push_back(const T& t) {
|
|
||||||
if(size_ == capacity_) {
|
|
||||||
assert(capacity_);
|
|
||||||
reserve(capacity_ * 2);
|
|
||||||
}
|
}
|
||||||
ptr_[size_ ++ ] = t;
|
public:
|
||||||
}
|
T& operator [](size_t i) {
|
||||||
void reserve(size_t size) {
|
return ptr_[i];
|
||||||
if(size <= capacity_) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
T * next = (T*)malloc(sizeof(T) * size);
|
const T& operator [](size_t i) const {
|
||||||
assert(next);
|
return ptr_[i];
|
||||||
T * old = ptr_;
|
|
||||||
ptr_ = next;
|
|
||||||
memcpy(ptr_, old, sizeof(T) * capacity_);
|
|
||||||
capacity_ = size;
|
|
||||||
if(old != buffer_) {
|
|
||||||
free(old);
|
|
||||||
}
|
}
|
||||||
}
|
void push_back(const T& t) {
|
||||||
bool empty() const {
|
if(size_ == capacity_) {
|
||||||
return 0 == size();
|
assert(capacity_);
|
||||||
}
|
reserve(capacity_ * 2);
|
||||||
size_t size() const {
|
}
|
||||||
return size_;
|
ptr_[size_ ++ ] = t;
|
||||||
}
|
}
|
||||||
size_t capacity() const {
|
void reserve(size_t size) {
|
||||||
return capacity_;
|
if(size <= capacity_) {
|
||||||
}
|
return;
|
||||||
const_iterator begin() const {
|
}
|
||||||
return ptr_;
|
T * next = (T*)malloc(sizeof(T) * size);
|
||||||
}
|
assert(next);
|
||||||
const_iterator end() const {
|
T * old = ptr_;
|
||||||
return ptr_ + size_;
|
ptr_ = next;
|
||||||
}
|
memcpy(ptr_, old, sizeof(T) * capacity_);
|
||||||
void clear() {
|
capacity_ = size;
|
||||||
if(ptr_ != buffer_) {
|
if(old != buffer_) {
|
||||||
free(ptr_);
|
free(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool empty() const {
|
||||||
|
return 0 == size();
|
||||||
|
}
|
||||||
|
size_t size() const {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
size_t capacity() const {
|
||||||
|
return capacity_;
|
||||||
|
}
|
||||||
|
const_iterator begin() const {
|
||||||
|
return ptr_;
|
||||||
|
}
|
||||||
|
const_iterator end() const {
|
||||||
|
return ptr_ + size_;
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
if(ptr_ != buffer_) {
|
||||||
|
free(ptr_);
|
||||||
|
}
|
||||||
|
init_();
|
||||||
}
|
}
|
||||||
init_();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
ostream & operator << (ostream& os, const LocalVector<T>& vec) {
|
ostream & operator << (ostream& os, const LocalVector<T>& vec) {
|
||||||
if(vec.empty()) {
|
if(vec.empty()) {
|
||||||
return os << "[]";
|
return os << "[]";
|
||||||
}
|
}
|
||||||
os<<"[\""<<vec[0];
|
os << "[\"" << vec[0];
|
||||||
for(size_t i = 1; i < vec.size(); i++) {
|
for(size_t i = 1; i < vec.size(); i++) {
|
||||||
os<<"\", \""<<vec[i];
|
os << "\", \"" << vec[i];
|
||||||
}
|
}
|
||||||
os<<"\"]";
|
os << "\"]";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,61 +32,61 @@
|
||||||
#error "XCHECK has been defined already"
|
#error "XCHECK has been defined already"
|
||||||
#endif // XCHECK
|
#endif // XCHECK
|
||||||
|
|
||||||
#define XLOG(level) limonp::Logger(limonp::LL_##level, __FILE__, __LINE__).Stream()
|
#define XLOG(level) limonp::Logger(limonp::LL_##level, __FILE__, __LINE__).Stream()
|
||||||
#define XCHECK(exp) if(!(exp)) XLOG(FATAL) << "exp: ["#exp << "] false. "
|
#define XCHECK(exp) if(!(exp)) XLOG(FATAL) << "exp: ["#exp << "] false. "
|
||||||
|
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LL_DEBUG = 0,
|
LL_DEBUG = 0,
|
||||||
LL_INFO = 1,
|
LL_INFO = 1,
|
||||||
LL_WARNING = 2,
|
LL_WARNING = 2,
|
||||||
LL_ERROR = 3,
|
LL_ERROR = 3,
|
||||||
LL_FATAL = 4,
|
LL_FATAL = 4,
|
||||||
}; // enum
|
}; // enum
|
||||||
|
|
||||||
static const char * LOG_LEVEL_ARRAY[] = {"DEBUG","INFO","WARN","ERROR","FATAL"};
|
static const char * LOG_LEVEL_ARRAY[] = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
|
||||||
static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
|
static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
Logger(size_t level, const char* filename, int lineno)
|
Logger(size_t level, const char* filename, int lineno)
|
||||||
: level_(level) {
|
: level_(level) {
|
||||||
#ifdef LOGGING_LEVEL
|
#ifdef LOGGING_LEVEL
|
||||||
if (level_ < LOGGING_LEVEL) {
|
if(level_ < LOGGING_LEVEL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
assert(level_ <= sizeof(LOG_LEVEL_ARRAY)/sizeof(*LOG_LEVEL_ARRAY));
|
assert(level_ <= sizeof(LOG_LEVEL_ARRAY) / sizeof(*LOG_LEVEL_ARRAY));
|
||||||
char buf[32];
|
char buf[32];
|
||||||
time_t now;
|
time_t now;
|
||||||
time(&now);
|
time(&now);
|
||||||
strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&now));
|
strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&now));
|
||||||
stream_ << buf
|
stream_ << buf
|
||||||
<< " " << filename
|
<< " " << filename
|
||||||
<< ":" << lineno
|
<< ":" << lineno
|
||||||
<< " " << LOG_LEVEL_ARRAY[level_]
|
<< " " << LOG_LEVEL_ARRAY[level_]
|
||||||
<< " ";
|
<< " ";
|
||||||
}
|
}
|
||||||
~Logger() {
|
~Logger() {
|
||||||
#ifdef LOGGING_LEVEL
|
#ifdef LOGGING_LEVEL
|
||||||
if (level_ < LOGGING_LEVEL) {
|
if(level_ < LOGGING_LEVEL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
std::cerr << stream_.str() << std::endl;
|
std::cerr << stream_.str() << std::endl;
|
||||||
if (level_ == LL_FATAL) {
|
if(level_ == LL_FATAL) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& Stream() {
|
std::ostream& Stream() {
|
||||||
return stream_;
|
return stream_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostringstream stream_;
|
std::ostringstream stream_;
|
||||||
size_t level_;
|
size_t level_;
|
||||||
}; // class Logger
|
}; // class Logger
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -103,313 +103,313 @@ typedef unsigned short int UINT2;
|
||||||
typedef unsigned int UINT4;
|
typedef unsigned int UINT4;
|
||||||
|
|
||||||
static unsigned char PADDING[64] = {
|
static unsigned char PADDING[64] = {
|
||||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
// convenient object that wraps
|
// convenient object that wraps
|
||||||
// the C-functions for use in C++ only
|
// the C-functions for use in C++ only
|
||||||
class MD5 {
|
class MD5 {
|
||||||
private:
|
private:
|
||||||
struct __context_t {
|
struct __context_t {
|
||||||
UINT4 state[4]; /* state (ABCD) */
|
UINT4 state[4]; /* state (ABCD) */
|
||||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||||
unsigned char buffer[64]; /* input buffer */
|
unsigned char buffer[64]; /* input buffer */
|
||||||
} context ;
|
} context ;
|
||||||
|
|
||||||
//#pragma region static helper functions
|
//#pragma region static helper functions
|
||||||
// The core of the MD5 algorithm is here.
|
// The core of the MD5 algorithm is here.
|
||||||
// MD5 basic transformation. Transforms state based on block.
|
// MD5 basic transformation. Transforms state based on block.
|
||||||
static void MD5Transform( UINT4 state[4], unsigned char block[64] ) {
|
static void MD5Transform(UINT4 state[4], unsigned char block[64]) {
|
||||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
Decode (x, block, 64);
|
Decode(x, block, 64);
|
||||||
|
|
||||||
/* Round 1 */
|
/* Round 1 */
|
||||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
/* Round 2 */
|
/* Round 2 */
|
||||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
/* Round 3 */
|
/* Round 3 */
|
||||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
/* Round 4 */
|
/* Round 4 */
|
||||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||||
|
|
||||||
state[0] += a;
|
state[0] += a;
|
||||||
state[1] += b;
|
state[1] += b;
|
||||||
state[2] += c;
|
state[2] += c;
|
||||||
state[3] += d;
|
state[3] += d;
|
||||||
|
|
||||||
// Zeroize sensitive information.
|
// Zeroize sensitive information.
|
||||||
memset((POINTER)x, 0, sizeof (x));
|
memset((POINTER)x, 0, sizeof(x));
|
||||||
}
|
|
||||||
|
|
||||||
// Encodes input (UINT4) into output (unsigned char). Assumes len is
|
|
||||||
// a multiple of 4.
|
|
||||||
static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
|
||||||
output[j] = (unsigned char)(input[i] & 0xff);
|
|
||||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
|
||||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
|
||||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Decodes input (unsigned char) into output (UINT4). Assumes len is
|
// Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||||
// a multiple of 4.
|
// a multiple of 4.
|
||||||
static void Decode( UINT4 *output, unsigned char *input, unsigned int len ) {
|
static void Encode(unsigned char *output, UINT4 *input, unsigned int len) {
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
for(i = 0, j = 0; j < len; i++, j += 4) {
|
||||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
output[j + 1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
}
|
output[j + 2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
//#pragma endregion
|
output[j + 3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
// MAIN FUNCTIONS
|
|
||||||
MD5() {
|
|
||||||
Init() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MD5 initialization. Begins an MD5 operation, writing a new context.
|
|
||||||
void Init() {
|
|
||||||
context.count[0] = context.count[1] = 0;
|
|
||||||
|
|
||||||
// Load magic initialization constants.
|
|
||||||
context.state[0] = 0x67452301;
|
|
||||||
context.state[1] = 0xefcdab89;
|
|
||||||
context.state[2] = 0x98badcfe;
|
|
||||||
context.state[3] = 0x10325476;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MD5 block update operation. Continues an MD5 message-digest
|
|
||||||
// operation, processing another message block, and updating the
|
|
||||||
// context.
|
|
||||||
void Update(
|
|
||||||
unsigned char *input, // input block
|
|
||||||
unsigned int inputLen ) { // length of input block
|
|
||||||
unsigned int i, index, partLen;
|
|
||||||
|
|
||||||
// Compute number of bytes mod 64
|
|
||||||
index = (unsigned int)((context.count[0] >> 3) & 0x3F);
|
|
||||||
|
|
||||||
// Update number of bits
|
|
||||||
if ((context.count[0] += ((UINT4)inputLen << 3))
|
|
||||||
< ((UINT4)inputLen << 3))
|
|
||||||
context.count[1]++;
|
|
||||||
context.count[1] += ((UINT4)inputLen >> 29);
|
|
||||||
|
|
||||||
partLen = 64 - index;
|
|
||||||
|
|
||||||
// Transform as many times as possible.
|
|
||||||
if (inputLen >= partLen) {
|
|
||||||
memcpy((POINTER)&context.buffer[index], (POINTER)input, partLen);
|
|
||||||
MD5Transform (context.state, context.buffer);
|
|
||||||
|
|
||||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
|
||||||
MD5Transform (context.state, &input[i]);
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
} else
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
/* Buffer remaining input */
|
|
||||||
memcpy((POINTER)&context.buffer[index], (POINTER)&input[i], inputLen-i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
|
||||||
// the message digest and zeroizing the context.
|
|
||||||
// Writes to digestRaw
|
|
||||||
void Final() {
|
|
||||||
unsigned char bits[8];
|
|
||||||
unsigned int index, padLen;
|
|
||||||
|
|
||||||
// Save number of bits
|
|
||||||
Encode( bits, context.count, 8 );
|
|
||||||
|
|
||||||
// Pad out to 56 mod 64.
|
|
||||||
index = (unsigned int)((context.count[0] >> 3) & 0x3f);
|
|
||||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
|
||||||
Update( PADDING, padLen );
|
|
||||||
|
|
||||||
// Append length (before padding)
|
|
||||||
Update( bits, 8 );
|
|
||||||
|
|
||||||
// Store state in digest
|
|
||||||
Encode( digestRaw, context.state, 16);
|
|
||||||
|
|
||||||
// Zeroize sensitive information.
|
|
||||||
memset((POINTER)&context, 0, sizeof (context));
|
|
||||||
|
|
||||||
writeToString() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Buffer must be 32+1 (nul) = 33 chars long at least
|
|
||||||
void writeToString() {
|
|
||||||
int pos ;
|
|
||||||
|
|
||||||
for( pos = 0 ; pos < 16 ; pos++ )
|
|
||||||
sprintf( digestChars+(pos*2), "%02x", digestRaw[pos] ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
// an MD5 digest is a 16-byte number (32 hex digits)
|
|
||||||
BYTE digestRaw[ 16 ] ;
|
|
||||||
|
|
||||||
// This version of the digest is actually
|
|
||||||
// a "printf'd" version of the digest.
|
|
||||||
char digestChars[ 33 ] ;
|
|
||||||
|
|
||||||
/// Load a file from disk and digest it
|
|
||||||
// Digests a file and returns the result.
|
|
||||||
const char* digestFile( const char *filename ) {
|
|
||||||
if (NULL == filename || strcmp(filename, "") == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Init() ;
|
|
||||||
|
|
||||||
FILE *file;
|
|
||||||
|
|
||||||
unsigned char buffer[1024] ;
|
|
||||||
|
|
||||||
if((file = fopen (filename, "rb")) == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
int len;
|
|
||||||
while( (len = fread( buffer, 1, 1024, file )) )
|
|
||||||
Update( buffer, len ) ;
|
|
||||||
Final();
|
|
||||||
|
|
||||||
fclose( file );
|
// Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||||
|
// a multiple of 4.
|
||||||
|
static void Decode(UINT4 *output, unsigned char *input, unsigned int len) {
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
return digestChars ;
|
for(i = 0, j = 0; j < len; i++, j += 4)
|
||||||
}
|
output[i] = ((UINT4)input[j]) | (((UINT4)input[j + 1]) << 8) |
|
||||||
|
(((UINT4)input[j + 2]) << 16) | (((UINT4)input[j + 3]) << 24);
|
||||||
|
}
|
||||||
|
//#pragma endregion
|
||||||
|
|
||||||
/// Digests a byte-array already in memory
|
|
||||||
const char* digestMemory( BYTE *memchunk, int len ) {
|
|
||||||
if (NULL == memchunk)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Init() ;
|
public:
|
||||||
Update( memchunk, len ) ;
|
// MAIN FUNCTIONS
|
||||||
Final() ;
|
MD5() {
|
||||||
|
Init() ;
|
||||||
|
}
|
||||||
|
|
||||||
return digestChars ;
|
// MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||||
}
|
void Init() {
|
||||||
|
context.count[0] = context.count[1] = 0;
|
||||||
|
|
||||||
// Digests a string and prints the result.
|
// Load magic initialization constants.
|
||||||
const char* digestString(const char *string ) {
|
context.state[0] = 0x67452301;
|
||||||
if (string == NULL)
|
context.state[1] = 0xefcdab89;
|
||||||
return NULL;
|
context.state[2] = 0x98badcfe;
|
||||||
|
context.state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
Init() ;
|
// MD5 block update operation. Continues an MD5 message-digest
|
||||||
Update( (unsigned char*)string, strlen(string) ) ;
|
// operation, processing another message block, and updating the
|
||||||
Final() ;
|
// context.
|
||||||
|
void Update(
|
||||||
|
unsigned char *input, // input block
|
||||||
|
unsigned int inputLen) { // length of input block
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
return digestChars ;
|
// Compute number of bytes mod 64
|
||||||
}
|
index = (unsigned int)((context.count[0] >> 3) & 0x3F);
|
||||||
|
|
||||||
|
// Update number of bits
|
||||||
|
if((context.count[0] += ((UINT4)inputLen << 3))
|
||||||
|
< ((UINT4)inputLen << 3))
|
||||||
|
context.count[1]++;
|
||||||
|
context.count[1] += ((UINT4)inputLen >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
// Transform as many times as possible.
|
||||||
|
if(inputLen >= partLen) {
|
||||||
|
memcpy((POINTER)&context.buffer[index], (POINTER)input, partLen);
|
||||||
|
MD5Transform(context.state, context.buffer);
|
||||||
|
|
||||||
|
for(i = partLen; i + 63 < inputLen; i += 64)
|
||||||
|
MD5Transform(context.state, &input[i]);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
} else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
memcpy((POINTER)&context.buffer[index], (POINTER)&input[i], inputLen - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||||
|
// the message digest and zeroizing the context.
|
||||||
|
// Writes to digestRaw
|
||||||
|
void Final() {
|
||||||
|
unsigned char bits[8];
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
// Save number of bits
|
||||||
|
Encode(bits, context.count, 8);
|
||||||
|
|
||||||
|
// Pad out to 56 mod 64.
|
||||||
|
index = (unsigned int)((context.count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
Update(PADDING, padLen);
|
||||||
|
|
||||||
|
// Append length (before padding)
|
||||||
|
Update(bits, 8);
|
||||||
|
|
||||||
|
// Store state in digest
|
||||||
|
Encode(digestRaw, context.state, 16);
|
||||||
|
|
||||||
|
// Zeroize sensitive information.
|
||||||
|
memset((POINTER)&context, 0, sizeof(context));
|
||||||
|
|
||||||
|
writeToString() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Buffer must be 32+1 (nul) = 33 chars long at least
|
||||||
|
void writeToString() {
|
||||||
|
int pos ;
|
||||||
|
|
||||||
|
for(pos = 0 ; pos < 16 ; pos++)
|
||||||
|
sprintf(digestChars + (pos * 2), "%02x", digestRaw[pos]) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// an MD5 digest is a 16-byte number (32 hex digits)
|
||||||
|
BYTE digestRaw[ 16 ] ;
|
||||||
|
|
||||||
|
// This version of the digest is actually
|
||||||
|
// a "printf'd" version of the digest.
|
||||||
|
char digestChars[ 33 ] ;
|
||||||
|
|
||||||
|
/// Load a file from disk and digest it
|
||||||
|
// Digests a file and returns the result.
|
||||||
|
const char* digestFile(const char *filename) {
|
||||||
|
if(NULL == filename || strcmp(filename, "") == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Init() ;
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
unsigned char buffer[1024] ;
|
||||||
|
|
||||||
|
if((file = fopen(filename, "rb")) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int len;
|
||||||
|
while((len = fread(buffer, 1, 1024, file)))
|
||||||
|
Update(buffer, len) ;
|
||||||
|
Final();
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return digestChars ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Digests a byte-array already in memory
|
||||||
|
const char* digestMemory(BYTE *memchunk, int len) {
|
||||||
|
if(NULL == memchunk)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Init() ;
|
||||||
|
Update(memchunk, len) ;
|
||||||
|
Final() ;
|
||||||
|
|
||||||
|
return digestChars ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Digests a string and prints the result.
|
||||||
|
const char* digestString(const char *string) {
|
||||||
|
if(string == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Init() ;
|
||||||
|
Update((unsigned char*)string, strlen(string)) ;
|
||||||
|
Final() ;
|
||||||
|
|
||||||
|
return digestChars ;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool md5String(const char* str, std::string& res) {
|
inline bool md5String(const char* str, std::string& res) {
|
||||||
if (NULL == str) {
|
if(NULL == str) {
|
||||||
res = "";
|
res = "";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5 md5;
|
MD5 md5;
|
||||||
const char *pRes = md5.digestString(str);
|
const char *pRes = md5.digestString(str);
|
||||||
if (NULL == pRes) {
|
if(NULL == pRes) {
|
||||||
res = "";
|
res = "";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = pRes;
|
res = pRes;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool md5File(const char* filepath, std::string& res) {
|
inline bool md5File(const char* filepath, std::string& res) {
|
||||||
if (NULL == filepath || strcmp(filepath, "") == 0) {
|
if(NULL == filepath || strcmp(filepath, "") == 0) {
|
||||||
res = "";
|
res = "";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5 md5;
|
MD5 md5;
|
||||||
const char *pRes = md5.digestFile(filepath);
|
const char *pRes = md5.digestFile(filepath);
|
||||||
|
|
||||||
if (NULL == pRes) {
|
if(NULL == pRes) {
|
||||||
res = "";
|
res = "";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = pRes;
|
res = pRes;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,40 +26,40 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
class MutexLock: NonCopyable {
|
class MutexLock: NonCopyable {
|
||||||
public:
|
public:
|
||||||
MutexLock() {
|
MutexLock() {
|
||||||
XCHECK(!pthread_mutex_init(&mutex_, NULL));
|
XCHECK(!pthread_mutex_init(&mutex_, NULL));
|
||||||
}
|
}
|
||||||
~MutexLock() {
|
~MutexLock() {
|
||||||
XCHECK(!pthread_mutex_destroy(&mutex_));
|
XCHECK(!pthread_mutex_destroy(&mutex_));
|
||||||
}
|
}
|
||||||
pthread_mutex_t* GetPthreadMutex() {
|
pthread_mutex_t* GetPthreadMutex() {
|
||||||
return &mutex_;
|
return &mutex_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Lock() {
|
void Lock() {
|
||||||
XCHECK(!pthread_mutex_lock(&mutex_));
|
XCHECK(!pthread_mutex_lock(&mutex_));
|
||||||
}
|
}
|
||||||
void Unlock() {
|
void Unlock() {
|
||||||
XCHECK(!pthread_mutex_unlock(&mutex_));
|
XCHECK(!pthread_mutex_unlock(&mutex_));
|
||||||
}
|
}
|
||||||
friend class MutexLockGuard;
|
friend class MutexLockGuard;
|
||||||
|
|
||||||
pthread_mutex_t mutex_;
|
pthread_mutex_t mutex_;
|
||||||
}; // class MutexLock
|
}; // class MutexLock
|
||||||
|
|
||||||
class MutexLockGuard: NonCopyable {
|
class MutexLockGuard: NonCopyable {
|
||||||
public:
|
public:
|
||||||
explicit MutexLockGuard(MutexLock & mutex)
|
explicit MutexLockGuard(MutexLock & mutex)
|
||||||
: mutex_(mutex) {
|
: mutex_(mutex) {
|
||||||
mutex_.Lock();
|
mutex_.Lock();
|
||||||
}
|
}
|
||||||
~MutexLockGuard() {
|
~MutexLockGuard() {
|
||||||
mutex_.Unlock();
|
mutex_.Unlock();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
MutexLock & mutex_;
|
MutexLock & mutex_;
|
||||||
}; // class MutexLockGuard
|
}; // class MutexLockGuard
|
||||||
|
|
||||||
#define MutexLockGuard(x) XCHECK(false);
|
#define MutexLockGuard(x) XCHECK(false);
|
||||||
|
|
|
@ -22,14 +22,14 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
class NonCopyable {
|
class NonCopyable {
|
||||||
protected:
|
protected:
|
||||||
NonCopyable() {
|
NonCopyable() {
|
||||||
}
|
}
|
||||||
~NonCopyable() {
|
~NonCopyable() {
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
NonCopyable(const NonCopyable& );
|
NonCopyable(const NonCopyable&);
|
||||||
const NonCopyable& operator=(const NonCopyable& );
|
const NonCopyable& operator=(const NonCopyable&);
|
||||||
}; // class NonCopyable
|
}; // class NonCopyable
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -51,123 +51,123 @@ namespace std {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ostream& operator << (ostream& os, const vector<T>& v) {
|
ostream& operator << (ostream& os, const vector<T>& v) {
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
return os << "[]";
|
return os << "[]";
|
||||||
}
|
}
|
||||||
os<<"["<<v[0];
|
os << "[" << v[0];
|
||||||
for(size_t i = 1; i < v.size(); i++) {
|
for(size_t i = 1; i < v.size(); i++) {
|
||||||
os<<", "<<v[i];
|
os << ", " << v[i];
|
||||||
}
|
}
|
||||||
os<<"]";
|
os << "]";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline ostream& operator << (ostream& os, const vector<string>& v) {
|
inline ostream& operator << (ostream& os, const vector<string>& v) {
|
||||||
if(v.empty()) {
|
if(v.empty()) {
|
||||||
return os << "[]";
|
return os << "[]";
|
||||||
}
|
}
|
||||||
os<<"[\""<<v[0];
|
os << "[\"" << v[0];
|
||||||
for(size_t i = 1; i < v.size(); i++) {
|
for(size_t i = 1; i < v.size(); i++) {
|
||||||
os<<"\", \""<<v[i];
|
os << "\", \"" << v[i];
|
||||||
}
|
}
|
||||||
os<<"\"]";
|
os << "\"]";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ostream& operator << (ostream& os, const deque<T>& dq) {
|
ostream& operator << (ostream& os, const deque<T>& dq) {
|
||||||
if(dq.empty()) {
|
if(dq.empty()) {
|
||||||
return os << "[]";
|
return os << "[]";
|
||||||
}
|
}
|
||||||
os<<"[\""<<dq[0];
|
os << "[\"" << dq[0];
|
||||||
for(size_t i = 1; i < dq.size(); i++) {
|
for(size_t i = 1; i < dq.size(); i++) {
|
||||||
os<<"\", \""<<dq[i];
|
os << "\", \"" << dq[i];
|
||||||
}
|
}
|
||||||
os<<"\"]";
|
os << "\"]";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
ostream& operator << (ostream& os, const pair<T1, T2>& pr) {
|
ostream& operator << (ostream& os, const pair<T1, T2>& pr) {
|
||||||
os << pr.first << ":" << pr.second ;
|
os << pr.first << ":" << pr.second ;
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
string& operator << (string& str, const T& obj) {
|
string& operator << (string& str, const T& obj) {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << obj; // call ostream& operator << (ostream& os,
|
ss << obj; // call ostream& operator << (ostream& os,
|
||||||
return str = ss.str();
|
return str = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
ostream& operator << (ostream& os, const map<T1, T2>& mp) {
|
ostream& operator << (ostream& os, const map<T1, T2>& mp) {
|
||||||
if(mp.empty()) {
|
if(mp.empty()) {
|
||||||
os<<"{}";
|
os << "{}";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
os<<'{';
|
os << '{';
|
||||||
typename map<T1, T2>::const_iterator it = mp.begin();
|
typename map<T1, T2>::const_iterator it = mp.begin();
|
||||||
os<<*it;
|
os << *it;
|
||||||
it++;
|
|
||||||
while(it != mp.end()) {
|
|
||||||
os<<", "<<*it;
|
|
||||||
it++;
|
it++;
|
||||||
}
|
while(it != mp.end()) {
|
||||||
os<<'}';
|
os << ", " << *it;
|
||||||
return os;
|
it++;
|
||||||
|
}
|
||||||
|
os << '}';
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
ostream& operator << (ostream& os, const std::unordered_map<T1, T2>& mp) {
|
ostream& operator << (ostream& os, const std::unordered_map<T1, T2>& mp) {
|
||||||
if(mp.empty()) {
|
if(mp.empty()) {
|
||||||
return os << "{}";
|
return os << "{}";
|
||||||
}
|
}
|
||||||
os<<'{';
|
os << '{';
|
||||||
typename std::unordered_map<T1, T2>::const_iterator it = mp.begin();
|
typename std::unordered_map<T1, T2>::const_iterator it = mp.begin();
|
||||||
os<<*it;
|
os << *it;
|
||||||
it++;
|
it++;
|
||||||
while(it != mp.end()) {
|
while(it != mp.end()) {
|
||||||
os<<", "<<*it++;
|
os << ", " << *it++;
|
||||||
}
|
}
|
||||||
return os<<'}';
|
return os << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
ostream& operator << (ostream& os, const set<T>& st) {
|
ostream& operator << (ostream& os, const set<T>& st) {
|
||||||
if(st.empty()) {
|
if(st.empty()) {
|
||||||
os << "{}";
|
os << "{}";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
os<<'{';
|
os << '{';
|
||||||
typename set<T>::const_iterator it = st.begin();
|
typename set<T>::const_iterator it = st.begin();
|
||||||
os<<*it;
|
os << *it;
|
||||||
it++;
|
|
||||||
while(it != st.end()) {
|
|
||||||
os<<", "<<*it;
|
|
||||||
it++;
|
it++;
|
||||||
}
|
while(it != st.end()) {
|
||||||
os<<'}';
|
os << ", " << *it;
|
||||||
return os;
|
it++;
|
||||||
|
}
|
||||||
|
os << '}';
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class KeyType, class ContainType>
|
template<class KeyType, class ContainType>
|
||||||
bool IsIn(const ContainType& contain, const KeyType& key) {
|
bool IsIn(const ContainType& contain, const KeyType& key) {
|
||||||
return contain.end() != contain.find(key);
|
return contain.end() != contain.find(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
basic_string<T> & operator << (basic_string<T> & s, ifstream & ifs) {
|
basic_string<T> & operator << (basic_string<T> & s, ifstream & ifs) {
|
||||||
return s.assign((istreambuf_iterator<T>(ifs)), istreambuf_iterator<T>());
|
return s.assign((istreambuf_iterator<T>(ifs)), istreambuf_iterator<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
ofstream & operator << (ofstream & ofs, const basic_string<T>& s) {
|
ofstream & operator << (ofstream & ofs, const basic_string<T>& s) {
|
||||||
ostreambuf_iterator<T> itr (ofs);
|
ostreambuf_iterator<T> itr(ofs);
|
||||||
copy(s.begin(), s.end(), itr);
|
copy(s.begin(), s.end(), itr);
|
||||||
return ofs;
|
return ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
|
@ -44,339 +44,339 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
inline string StringFormat(const char* fmt, ...) {
|
inline string StringFormat(const char* fmt, ...) {
|
||||||
int size = 256;
|
int size = 256;
|
||||||
std::string str;
|
std::string str;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
while (1) {
|
while(1) {
|
||||||
str.resize(size);
|
str.resize(size);
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
int n = vsnprintf((char *)str.c_str(), size, fmt, ap);
|
int n = vsnprintf((char *)str.c_str(), size, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (n > -1 && n < size) {
|
if(n > -1 && n < size) {
|
||||||
str.resize(n);
|
str.resize(n);
|
||||||
return str;
|
return str;
|
||||||
|
}
|
||||||
|
if(n > -1)
|
||||||
|
size = n + 1;
|
||||||
|
else
|
||||||
|
size *= 2;
|
||||||
}
|
}
|
||||||
if (n > -1)
|
return str;
|
||||||
size = n + 1;
|
|
||||||
else
|
|
||||||
size *= 2;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Join(T begin, T end, string& res, const string& connector) {
|
void Join(T begin, T end, string& res, const string& connector) {
|
||||||
if(begin == end) {
|
if(begin == end) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss<<*begin;
|
ss << *begin;
|
||||||
begin++;
|
begin++;
|
||||||
while(begin != end) {
|
while(begin != end) {
|
||||||
ss << connector << *begin;
|
ss << connector << *begin;
|
||||||
begin ++;
|
begin ++;
|
||||||
}
|
}
|
||||||
res = ss.str();
|
res = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
string Join(T begin, T end, const string& connector) {
|
string Join(T begin, T end, const string& connector) {
|
||||||
string res;
|
string res;
|
||||||
Join(begin ,end, res, connector);
|
Join(begin, end, res, connector);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string& Upper(string& str) {
|
inline string& Upper(string& str) {
|
||||||
transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);
|
transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string& Lower(string& str) {
|
inline string& Lower(string& str) {
|
||||||
transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower);
|
transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsSpace(unsigned c) {
|
inline bool IsSpace(unsigned c) {
|
||||||
// when passing large int as the argument of isspace, it core dump, so here need a type cast.
|
// when passing large int as the argument of isspace, it core dump, so here need a type cast.
|
||||||
return c > 0xff ? false : std::isspace(c & 0xff) != 0;
|
return c > 0xff ? false : std::isspace(c & 0xff) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& LTrim(std::string &s) {
|
inline std::string& LTrim(std::string &s) {
|
||||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<unsigned, bool>(IsSpace))));
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<unsigned, bool>(IsSpace))));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& RTrim(std::string &s) {
|
inline std::string& RTrim(std::string &s) {
|
||||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<unsigned, bool>(IsSpace))).base(), s.end());
|
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<unsigned, bool>(IsSpace))).base(), s.end());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& Trim(std::string &s) {
|
inline std::string& Trim(std::string &s) {
|
||||||
return LTrim(RTrim(s));
|
return LTrim(RTrim(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& LTrim(std::string & s, char x) {
|
inline std::string& LTrim(std::string & s, char x) {
|
||||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::bind2nd(std::equal_to<char>(), x))));
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::bind2nd(std::equal_to<char>(), x))));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& RTrim(std::string & s, char x) {
|
inline std::string& RTrim(std::string & s, char x) {
|
||||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::bind2nd(std::equal_to<char>(), x))).base(), s.end());
|
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::bind2nd(std::equal_to<char>(), x))).base(), s.end());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string& Trim(std::string &s, char x) {
|
inline std::string& Trim(std::string &s, char x) {
|
||||||
return LTrim(RTrim(s, x), x);
|
return LTrim(RTrim(s, x), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Split(const string& src, vector<string>& res, const string& pattern, size_t maxsplit = string::npos) {
|
inline void Split(const string& src, vector<string>& res, const string& pattern, size_t maxsplit = string::npos) {
|
||||||
res.clear();
|
res.clear();
|
||||||
size_t Start = 0;
|
size_t Start = 0;
|
||||||
size_t end = 0;
|
size_t end = 0;
|
||||||
string sub;
|
string sub;
|
||||||
while(Start < src.size()) {
|
while(Start < src.size()) {
|
||||||
end = src.find_first_of(pattern, Start);
|
end = src.find_first_of(pattern, Start);
|
||||||
if(string::npos == end || res.size() >= maxsplit) {
|
if(string::npos == end || res.size() >= maxsplit) {
|
||||||
sub = src.substr(Start);
|
sub = src.substr(Start);
|
||||||
res.push_back(sub);
|
res.push_back(sub);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
sub = src.substr(Start, end - Start);
|
||||||
|
res.push_back(sub);
|
||||||
|
Start = end + 1;
|
||||||
}
|
}
|
||||||
sub = src.substr(Start, end - Start);
|
return;
|
||||||
res.push_back(sub);
|
|
||||||
Start = end + 1;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vector<string> Split(const string& src, const string& pattern, size_t maxsplit = string::npos) {
|
inline vector<string> Split(const string& src, const string& pattern, size_t maxsplit = string::npos) {
|
||||||
vector<string> res;
|
vector<string> res;
|
||||||
Split(src, res, pattern, maxsplit);
|
Split(src, res, pattern, maxsplit);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool StartsWith(const string& str, const string& prefix) {
|
inline bool StartsWith(const string& str, const string& prefix) {
|
||||||
if(prefix.length() > str.length()) {
|
if(prefix.length() > str.length()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return 0 == str.compare(0, prefix.length(), prefix);
|
return 0 == str.compare(0, prefix.length(), prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool EndsWith(const string& str, const string& suffix) {
|
inline bool EndsWith(const string& str, const string& suffix) {
|
||||||
if(suffix.length() > str.length()) {
|
if(suffix.length() > str.length()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix);
|
return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsInStr(const string& str, char ch) {
|
inline bool IsInStr(const string& str, char ch) {
|
||||||
return str.find(ch) != string::npos;
|
return str.find(ch) != string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t TwocharToUint16(char high, char low) {
|
inline uint16_t TwocharToUint16(char high, char low) {
|
||||||
return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff));
|
return (((uint16_t(high) & 0x00ff) << 8) | (uint16_t(low) & 0x00ff));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint16Container>
|
template <class Uint16Container>
|
||||||
bool Utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) {
|
bool Utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) {
|
||||||
if(!str) {
|
if(!str) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
char ch1, ch2;
|
|
||||||
uint16_t tmp;
|
|
||||||
vec.clear();
|
|
||||||
for(size_t i = 0; i < len;) {
|
|
||||||
if(!(str[i] & 0x80)) { // 0xxxxxxx
|
|
||||||
vec.push_back(str[i]);
|
|
||||||
i++;
|
|
||||||
} else if ((uint8_t)str[i] <= 0xdf && i + 1 < len) { // 110xxxxxx
|
|
||||||
ch1 = (str[i] >> 2) & 0x07;
|
|
||||||
ch2 = (str[i+1] & 0x3f) | ((str[i] & 0x03) << 6 );
|
|
||||||
tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff));
|
|
||||||
vec.push_back(tmp);
|
|
||||||
i += 2;
|
|
||||||
} else if((uint8_t)str[i] <= 0xef && i + 2 < len) {
|
|
||||||
ch1 = ((uint8_t)str[i] << 4) | ((str[i+1] >> 2) & 0x0f );
|
|
||||||
ch2 = (((uint8_t)str[i+1]<<6) & 0xc0) | (str[i+2] & 0x3f);
|
|
||||||
tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff));
|
|
||||||
vec.push_back(tmp);
|
|
||||||
i += 3;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
char ch1, ch2;
|
||||||
return true;
|
uint16_t tmp;
|
||||||
|
vec.clear();
|
||||||
|
for(size_t i = 0; i < len;) {
|
||||||
|
if(!(str[i] & 0x80)) { // 0xxxxxxx
|
||||||
|
vec.push_back(str[i]);
|
||||||
|
i++;
|
||||||
|
} else if((uint8_t)str[i] <= 0xdf && i + 1 < len) { // 110xxxxxx
|
||||||
|
ch1 = (str[i] >> 2) & 0x07;
|
||||||
|
ch2 = (str[i + 1] & 0x3f) | ((str[i] & 0x03) << 6);
|
||||||
|
tmp = (((uint16_t(ch1) & 0x00ff) << 8) | (uint16_t(ch2) & 0x00ff));
|
||||||
|
vec.push_back(tmp);
|
||||||
|
i += 2;
|
||||||
|
} else if((uint8_t)str[i] <= 0xef && i + 2 < len) {
|
||||||
|
ch1 = ((uint8_t)str[i] << 4) | ((str[i + 1] >> 2) & 0x0f);
|
||||||
|
ch2 = (((uint8_t)str[i + 1] << 6) & 0xc0) | (str[i + 2] & 0x3f);
|
||||||
|
tmp = (((uint16_t(ch1) & 0x00ff) << 8) | (uint16_t(ch2) & 0x00ff));
|
||||||
|
vec.push_back(tmp);
|
||||||
|
i += 3;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint16Container>
|
template <class Uint16Container>
|
||||||
bool Utf8ToUnicode(const string& str, Uint16Container& vec) {
|
bool Utf8ToUnicode(const string& str, Uint16Container& vec) {
|
||||||
return Utf8ToUnicode(str.c_str(), str.size(), vec);
|
return Utf8ToUnicode(str.c_str(), str.size(), vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint32Container>
|
template <class Uint32Container>
|
||||||
bool Utf8ToUnicode32(const string& str, Uint32Container& vec) {
|
bool Utf8ToUnicode32(const string& str, Uint32Container& vec) {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
vec.clear();
|
vec.clear();
|
||||||
for(size_t i = 0; i < str.size();) {
|
for(size_t i = 0; i < str.size();) {
|
||||||
if(!(str[i] & 0x80)) { // 0xxxxxxx
|
if(!(str[i] & 0x80)) { // 0xxxxxxx
|
||||||
// 7bit, total 7bit
|
// 7bit, total 7bit
|
||||||
tmp = (uint8_t)(str[i]) & 0x7f;
|
tmp = (uint8_t)(str[i]) & 0x7f;
|
||||||
i++;
|
i++;
|
||||||
} else if ((uint8_t)str[i] <= 0xdf && i + 1 < str.size()) { // 110xxxxxx
|
} else if((uint8_t)str[i] <= 0xdf && i + 1 < str.size()) { // 110xxxxxx
|
||||||
// 5bit, total 5bit
|
// 5bit, total 5bit
|
||||||
tmp = (uint8_t)(str[i]) & 0x1f;
|
tmp = (uint8_t)(str[i]) & 0x1f;
|
||||||
|
|
||||||
// 6bit, total 11bit
|
// 6bit, total 11bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 1]) & 0x3f;
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if((uint8_t)str[i] <= 0xef && i + 2 < str.size()) { // 1110xxxxxx
|
} else if((uint8_t)str[i] <= 0xef && i + 2 < str.size()) { // 1110xxxxxx
|
||||||
// 4bit, total 4bit
|
// 4bit, total 4bit
|
||||||
tmp = (uint8_t)(str[i]) & 0x0f;
|
tmp = (uint8_t)(str[i]) & 0x0f;
|
||||||
|
|
||||||
// 6bit, total 10bit
|
// 6bit, total 10bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 1]) & 0x3f;
|
||||||
|
|
||||||
// 6bit, total 16bit
|
// 6bit, total 16bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+2]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 2]) & 0x3f;
|
||||||
|
|
||||||
i += 3;
|
i += 3;
|
||||||
} else if((uint8_t)str[i] <= 0xf7 && i + 3 < str.size()) { // 11110xxxx
|
} else if((uint8_t)str[i] <= 0xf7 && i + 3 < str.size()) { // 11110xxxx
|
||||||
// 3bit, total 3bit
|
// 3bit, total 3bit
|
||||||
tmp = (uint8_t)(str[i]) & 0x07;
|
tmp = (uint8_t)(str[i]) & 0x07;
|
||||||
|
|
||||||
// 6bit, total 9bit
|
// 6bit, total 9bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 1]) & 0x3f;
|
||||||
|
|
||||||
// 6bit, total 15bit
|
// 6bit, total 15bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+2]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 2]) & 0x3f;
|
||||||
|
|
||||||
// 6bit, total 21bit
|
// 6bit, total 21bit
|
||||||
tmp <<= 6;
|
tmp <<= 6;
|
||||||
tmp |= (uint8_t)(str[i+3]) & 0x3f;
|
tmp |= (uint8_t)(str[i + 3]) & 0x3f;
|
||||||
|
|
||||||
i += 4;
|
i += 4;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
vec.push_back(tmp);
|
||||||
}
|
}
|
||||||
vec.push_back(tmp);
|
return true;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint32ContainerConIter>
|
template <class Uint32ContainerConIter>
|
||||||
void Unicode32ToUtf8(Uint32ContainerConIter begin, Uint32ContainerConIter end, string& res) {
|
void Unicode32ToUtf8(Uint32ContainerConIter begin, Uint32ContainerConIter end, string& res) {
|
||||||
res.clear();
|
res.clear();
|
||||||
uint32_t ui;
|
uint32_t ui;
|
||||||
while(begin != end) {
|
while(begin != end) {
|
||||||
ui = *begin;
|
ui = *begin;
|
||||||
if(ui <= 0x7f) {
|
if(ui <= 0x7f) {
|
||||||
res += char(ui);
|
res += char(ui);
|
||||||
} else if(ui <= 0x7ff) {
|
} else if(ui <= 0x7ff) {
|
||||||
res += char(((ui >> 6) & 0x1f) | 0xc0);
|
res += char(((ui >> 6) & 0x1f) | 0xc0);
|
||||||
res += char((ui & 0x3f) | 0x80);
|
res += char((ui & 0x3f) | 0x80);
|
||||||
} else if(ui <= 0xffff) {
|
} else if(ui <= 0xffff) {
|
||||||
res += char(((ui >> 12) & 0x0f) | 0xe0);
|
res += char(((ui >> 12) & 0x0f) | 0xe0);
|
||||||
res += char(((ui >> 6) & 0x3f) | 0x80);
|
res += char(((ui >> 6) & 0x3f) | 0x80);
|
||||||
res += char((ui & 0x3f) | 0x80);
|
res += char((ui & 0x3f) | 0x80);
|
||||||
} else {
|
} else {
|
||||||
res += char(((ui >> 18) & 0x03) | 0xf0);
|
res += char(((ui >> 18) & 0x03) | 0xf0);
|
||||||
res += char(((ui >> 12) & 0x3f) | 0x80);
|
res += char(((ui >> 12) & 0x3f) | 0x80);
|
||||||
res += char(((ui >> 6) & 0x3f) | 0x80);
|
res += char(((ui >> 6) & 0x3f) | 0x80);
|
||||||
res += char((ui & 0x3f) | 0x80);
|
res += char((ui & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
begin ++;
|
||||||
}
|
}
|
||||||
begin ++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint16ContainerConIter>
|
template <class Uint16ContainerConIter>
|
||||||
void UnicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
void UnicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
||||||
res.clear();
|
res.clear();
|
||||||
uint16_t ui;
|
uint16_t ui;
|
||||||
while(begin != end) {
|
while(begin != end) {
|
||||||
ui = *begin;
|
ui = *begin;
|
||||||
if(ui <= 0x7f) {
|
if(ui <= 0x7f) {
|
||||||
res += char(ui);
|
res += char(ui);
|
||||||
} else if(ui <= 0x7ff) {
|
} else if(ui <= 0x7ff) {
|
||||||
res += char(((ui>>6) & 0x1f) | 0xc0);
|
res += char(((ui >> 6) & 0x1f) | 0xc0);
|
||||||
res += char((ui & 0x3f) | 0x80);
|
res += char((ui & 0x3f) | 0x80);
|
||||||
} else {
|
} else {
|
||||||
res += char(((ui >> 12) & 0x0f )| 0xe0);
|
res += char(((ui >> 12) & 0x0f) | 0xe0);
|
||||||
res += char(((ui>>6) & 0x3f )| 0x80 );
|
res += char(((ui >> 6) & 0x3f) | 0x80);
|
||||||
res += char((ui & 0x3f) | 0x80);
|
res += char((ui & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
begin ++;
|
||||||
}
|
}
|
||||||
begin ++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Uint16Container>
|
template <class Uint16Container>
|
||||||
bool GBKTrans(const char* const str, size_t len, Uint16Container& vec) {
|
bool GBKTrans(const char* const str, size_t len, Uint16Container& vec) {
|
||||||
vec.clear();
|
vec.clear();
|
||||||
if(!str) {
|
if(!str) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
size_t i = 0;
|
|
||||||
while(i < len) {
|
|
||||||
if(0 == (str[i] & 0x80)) {
|
|
||||||
vec.push_back(uint16_t(str[i]));
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
if(i + 1 < len) { //&& (str[i+1] & 0x80))
|
|
||||||
uint16_t tmp = (((uint16_t(str[i]) & 0x00ff ) << 8) | (uint16_t(str[i+1]) & 0x00ff));
|
|
||||||
vec.push_back(tmp);
|
|
||||||
i += 2;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
size_t i = 0;
|
||||||
return true;
|
while(i < len) {
|
||||||
|
if(0 == (str[i] & 0x80)) {
|
||||||
|
vec.push_back(uint16_t(str[i]));
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
if(i + 1 < len) { //&& (str[i+1] & 0x80))
|
||||||
|
uint16_t tmp = (((uint16_t(str[i]) & 0x00ff) << 8) | (uint16_t(str[i + 1]) & 0x00ff));
|
||||||
|
vec.push_back(tmp);
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint16Container>
|
template <class Uint16Container>
|
||||||
bool GBKTrans(const string& str, Uint16Container& vec) {
|
bool GBKTrans(const string& str, Uint16Container& vec) {
|
||||||
return GBKTrans(str.c_str(), str.size(), vec);
|
return GBKTrans(str.c_str(), str.size(), vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Uint16ContainerConIter>
|
template <class Uint16ContainerConIter>
|
||||||
void GBKTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
void GBKTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
||||||
res.clear();
|
res.clear();
|
||||||
//pair<char, char> pa;
|
//pair<char, char> pa;
|
||||||
char first, second;
|
char first, second;
|
||||||
while(begin != end) {
|
while(begin != end) {
|
||||||
//pa = uint16ToChar2(*begin);
|
//pa = uint16ToChar2(*begin);
|
||||||
first = ((*begin)>>8) & 0x00ff;
|
first = ((*begin) >> 8) & 0x00ff;
|
||||||
second = (*begin) & 0x00ff;
|
second = (*begin) & 0x00ff;
|
||||||
if(first & 0x80) {
|
if(first & 0x80) {
|
||||||
res += first;
|
res += first;
|
||||||
res += second;
|
res += second;
|
||||||
} else {
|
} else {
|
||||||
res += second;
|
res += second;
|
||||||
|
}
|
||||||
|
begin++;
|
||||||
}
|
}
|
||||||
begin++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* format example: "%Y-%m-%d %H:%M:%S"
|
* format example: "%Y-%m-%d %H:%M:%S"
|
||||||
*/
|
*/
|
||||||
inline void GetTime(const string& format, string& timeStr) {
|
inline void GetTime(const string& format, string& timeStr) {
|
||||||
time_t timeNow;
|
time_t timeNow;
|
||||||
time(&timeNow);
|
time(&timeNow);
|
||||||
timeStr.resize(64);
|
timeStr.resize(64);
|
||||||
size_t len = strftime((char*)timeStr.c_str(), timeStr.size(), format.c_str(), localtime(&timeNow));
|
size_t len = strftime((char*)timeStr.c_str(), timeStr.size(), format.c_str(), localtime(&timeNow));
|
||||||
timeStr.resize(len);
|
timeStr.resize(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string PathJoin(const string& path1, const string& path2) {
|
inline string PathJoin(const string& path1, const string& path2) {
|
||||||
if(EndsWith(path1, "/")) {
|
if(EndsWith(path1, "/")) {
|
||||||
return path1 + path2;
|
return path1 + path2;
|
||||||
}
|
}
|
||||||
return path1 + "/" + path2;
|
return path1 + "/" + path2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,36 +25,36 @@
|
||||||
namespace limonp {
|
namespace limonp {
|
||||||
|
|
||||||
class IThread: NonCopyable {
|
class IThread: NonCopyable {
|
||||||
public:
|
public:
|
||||||
IThread(): isStarted(false), isJoined(false) {
|
IThread(): isStarted(false), isJoined(false) {
|
||||||
}
|
|
||||||
virtual ~IThread() {
|
|
||||||
if(isStarted && !isJoined) {
|
|
||||||
XCHECK(!pthread_detach(thread_));
|
|
||||||
}
|
}
|
||||||
};
|
virtual ~IThread() {
|
||||||
|
if(isStarted && !isJoined) {
|
||||||
|
XCHECK(!pthread_detach(thread_));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
void Start() {
|
void Start() {
|
||||||
XCHECK(!isStarted);
|
XCHECK(!isStarted);
|
||||||
XCHECK(!pthread_create(&thread_, NULL, Worker, this));
|
XCHECK(!pthread_create(&thread_, NULL, Worker, this));
|
||||||
isStarted = true;
|
isStarted = true;
|
||||||
}
|
}
|
||||||
void Join() {
|
void Join() {
|
||||||
XCHECK(!isJoined);
|
XCHECK(!isJoined);
|
||||||
XCHECK(!pthread_join(thread_, NULL));
|
XCHECK(!pthread_join(thread_, NULL));
|
||||||
isJoined = true;
|
isJoined = true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static void * Worker(void * data) {
|
static void * Worker(void * data) {
|
||||||
IThread * ptr = (IThread* ) data;
|
IThread * ptr = (IThread*) data;
|
||||||
ptr->Run();
|
ptr->Run();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_t thread_;
|
pthread_t thread_;
|
||||||
bool isStarted;
|
bool isStarted;
|
||||||
bool isJoined;
|
bool isJoined;
|
||||||
}; // class IThread
|
}; // class IThread
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -30,73 +30,73 @@ using namespace std;
|
||||||
|
|
||||||
//class ThreadPool;
|
//class ThreadPool;
|
||||||
class ThreadPool: NonCopyable {
|
class ThreadPool: NonCopyable {
|
||||||
public:
|
public:
|
||||||
class Worker: public IThread {
|
class Worker: public IThread {
|
||||||
public:
|
public:
|
||||||
Worker(ThreadPool* pool): ptThreadPool_(pool) {
|
Worker(ThreadPool* pool): ptThreadPool_(pool) {
|
||||||
assert(ptThreadPool_);
|
assert(ptThreadPool_);
|
||||||
}
|
|
||||||
virtual ~Worker() {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Run() {
|
|
||||||
while (true) {
|
|
||||||
ClosureInterface* closure = ptThreadPool_->queue_.Pop();
|
|
||||||
if (closure == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
try {
|
virtual ~Worker() {
|
||||||
closure->Run();
|
|
||||||
} catch(std::exception& e) {
|
|
||||||
XLOG(ERROR) << e.what();
|
|
||||||
} catch(...) {
|
|
||||||
XLOG(ERROR) << " unknown exception.";
|
|
||||||
}
|
}
|
||||||
delete closure;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ThreadPool * ptThreadPool_;
|
|
||||||
}; // class Worker
|
|
||||||
|
|
||||||
ThreadPool(size_t thread_num)
|
virtual void Run() {
|
||||||
: threads_(thread_num),
|
while(true) {
|
||||||
queue_(thread_num) {
|
ClosureInterface* closure = ptThreadPool_->queue_.Pop();
|
||||||
assert(thread_num);
|
if(closure == NULL) {
|
||||||
for(size_t i = 0; i < threads_.size(); i ++) {
|
break;
|
||||||
threads_[i] = new Worker(this);
|
}
|
||||||
}
|
try {
|
||||||
}
|
closure->Run();
|
||||||
~ThreadPool() {
|
} catch(std::exception& e) {
|
||||||
Stop();
|
XLOG(ERROR) << e.what();
|
||||||
}
|
} catch(...) {
|
||||||
|
XLOG(ERROR) << " unknown exception.";
|
||||||
|
}
|
||||||
|
delete closure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ThreadPool * ptThreadPool_;
|
||||||
|
}; // class Worker
|
||||||
|
|
||||||
void Start() {
|
ThreadPool(size_t thread_num)
|
||||||
for(size_t i = 0; i < threads_.size(); i++) {
|
: threads_(thread_num),
|
||||||
threads_[i]->Start();
|
queue_(thread_num) {
|
||||||
|
assert(thread_num);
|
||||||
|
for(size_t i = 0; i < threads_.size(); i ++) {
|
||||||
|
threads_[i] = new Worker(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
~ThreadPool() {
|
||||||
void Stop() {
|
Stop();
|
||||||
for(size_t i = 0; i < threads_.size(); i ++) {
|
|
||||||
queue_.Push(NULL);
|
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < threads_.size(); i ++) {
|
|
||||||
threads_[i]->Join();
|
void Start() {
|
||||||
delete threads_[i];
|
for(size_t i = 0; i < threads_.size(); i++) {
|
||||||
|
threads_[i]->Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Stop() {
|
||||||
|
for(size_t i = 0; i < threads_.size(); i ++) {
|
||||||
|
queue_.Push(NULL);
|
||||||
|
}
|
||||||
|
for(size_t i = 0; i < threads_.size(); i ++) {
|
||||||
|
threads_[i]->Join();
|
||||||
|
delete threads_[i];
|
||||||
|
}
|
||||||
|
threads_.clear();
|
||||||
}
|
}
|
||||||
threads_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Add(ClosureInterface* task) {
|
void Add(ClosureInterface* task) {
|
||||||
assert(task);
|
assert(task);
|
||||||
queue_.Push(task);
|
queue_.Push(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Worker;
|
friend class Worker;
|
||||||
|
|
||||||
vector<IThread*> threads_;
|
vector<IThread*> threads_;
|
||||||
BoundedBlockingQueue<ClosureInterface*> queue_;
|
BoundedBlockingQueue<ClosureInterface*> queue_;
|
||||||
}; // class ThreadPool
|
}; // class ThreadPool
|
||||||
|
|
||||||
} // namespace limonp
|
} // namespace limonp
|
||||||
|
|
|
@ -30,19 +30,18 @@ break;
|
||||||
println("+---------------------------------------------------------------+");
|
println("+---------------------------------------------------------------+");
|
||||||
|
|
||||||
//read a line from a command line.
|
//read a line from a command line.
|
||||||
static fstring getLine( FILE *fp, fstring __dst )
|
static fstring getLine(FILE *fp, fstring __dst) {
|
||||||
{
|
|
||||||
register int c;
|
register int c;
|
||||||
register fstring cs;
|
register fstring cs;
|
||||||
|
|
||||||
cs = __dst;
|
cs = __dst;
|
||||||
while ( ( c = getc( fp ) ) != EOF ) {
|
while((c = getc(fp)) != EOF) {
|
||||||
if ( c == '\n' ) break;
|
if(c == '\n') break;
|
||||||
*cs++ = c;
|
*cs++ = c;
|
||||||
}
|
}
|
||||||
*cs = '\0';
|
*cs = '\0';
|
||||||
|
|
||||||
return ( c == EOF && cs == __dst ) ? NULL : __dst;
|
return (c == EOF && cs == __dst) ? NULL : __dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static void printcode( fstring str ) {
|
/*static void printcode( fstring str ) {
|
||||||
|
@ -56,8 +55,7 @@ static fstring getLine( FILE *fp, fstring __dst )
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
//int friso_test(int argc, char **argv)
|
//int friso_test(int argc, char **argv)
|
||||||
int friso_test()
|
int friso_test() {
|
||||||
{
|
|
||||||
|
|
||||||
clock_t s_time, e_time;
|
clock_t s_time, e_time;
|
||||||
char line[__INPUT_LENGTH__] = {0};
|
char line[__INPUT_LENGTH__] = {0};
|
||||||
|
@ -76,7 +74,7 @@ int friso_test()
|
||||||
// }
|
// }
|
||||||
__path__ = "/usr/share/ukui-search/res/friso.ini";
|
__path__ = "/usr/share/ukui-search/res/friso.ini";
|
||||||
|
|
||||||
if ( __path__ == NULL ) {
|
if(__path__ == NULL) {
|
||||||
println("Usage: friso -init lexicon path");
|
println("Usage: friso -init lexicon path");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -90,12 +88,12 @@ int friso_test()
|
||||||
friso_dic_load_from_ifile( dic, __path__, __LENGTH__ );
|
friso_dic_load_from_ifile( dic, __path__, __LENGTH__ );
|
||||||
friso_set_dic( friso, dic );
|
friso_set_dic( friso, dic );
|
||||||
friso_set_mode( friso, __FRISO_COMPLEX_MODE__ );*/
|
friso_set_mode( friso, __FRISO_COMPLEX_MODE__ );*/
|
||||||
if ( friso_init_from_ifile(friso, config, __path__) != 1 ) {
|
if(friso_init_from_ifile(friso, config, __path__) != 1) {
|
||||||
printf("fail to initialize friso and config.\n");
|
printf("fail to initialize friso and config.\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( config->mode ) {
|
switch(config->mode) {
|
||||||
case __FRISO_SIMPLE_MODE__:
|
case __FRISO_SIMPLE_MODE__:
|
||||||
mode = "Simple";
|
mode = "Simple";
|
||||||
break;
|
break;
|
||||||
|
@ -114,29 +112,29 @@ int friso_test()
|
||||||
|
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
|
|
||||||
printf("Initialized in %fsec\n", (double) ( e_time - s_time ) / CLOCKS_PER_SEC );
|
printf("Initialized in %fsec\n", (double)(e_time - s_time) / CLOCKS_PER_SEC);
|
||||||
printf("Mode: %s\n", mode);
|
printf("Mode: %s\n", mode);
|
||||||
printf("+-Version: %s (%s)\n", friso_version(), friso->charset == FRISO_UTF8 ? "UTF-8" : "GBK" );
|
printf("+-Version: %s (%s)\n", friso_version(), friso->charset == FRISO_UTF8 ? "UTF-8" : "GBK");
|
||||||
___ABOUT___;
|
___ABOUT___;
|
||||||
|
|
||||||
//set the task.
|
//set the task.
|
||||||
task = friso_new_task();
|
task = friso_new_task();
|
||||||
|
|
||||||
while ( 1 ) {
|
while(1) {
|
||||||
print("friso>> ");
|
print("friso>> ");
|
||||||
getLine( stdin, line );
|
getLine(stdin, line);
|
||||||
//exit the programe
|
//exit the programe
|
||||||
if (strcasecmp( line, "quit") == 0) {
|
if(strcasecmp(line, "quit") == 0) {
|
||||||
___EXIT_INFO___
|
___EXIT_INFO___
|
||||||
}
|
}
|
||||||
|
|
||||||
//for ( i = 0; i < 1000000; i++ ) {
|
//for ( i = 0; i < 1000000; i++ ) {
|
||||||
//set the task text.
|
//set the task text.
|
||||||
friso_set_text( task, line );
|
friso_set_text(task, line);
|
||||||
println("分词结果:");
|
println("分词结果:");
|
||||||
|
|
||||||
s_time = clock();
|
s_time = clock();
|
||||||
while ( ( config->next_token( friso, config, task ) ) != NULL ) {
|
while((config->next_token(friso, config, task)) != NULL) {
|
||||||
printf(
|
printf(
|
||||||
"%s[%d, %d, %d] ",
|
"%s[%d, %d, %d] ",
|
||||||
task->token->word,
|
task->token->word,
|
||||||
|
@ -148,7 +146,7 @@ int friso_test()
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
printf("\nDone, cost < %fsec\n", ( (double)(e_time - s_time) ) / CLOCKS_PER_SEC );
|
printf("\nDone, cost < %fsec\n", ((double)(e_time - s_time)) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* main interface file for friso tokenizer.
|
* main interface file for friso tokenizer.
|
||||||
* you could modify it and re-release and free for commercial use.
|
* you could modify it and re-release and free for commercial use.
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
/*
|
/*
|
||||||
* Type: friso_lex_t
|
* Type: friso_lex_t
|
||||||
* -----------
|
* -----------
|
||||||
* This type used to represent the type of the lexicon.
|
* This type used to represent the type of the lexicon.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
__LEX_CJK_WORDS__ = 0,
|
__LEX_CJK_WORDS__ = 0,
|
||||||
|
@ -47,7 +47,7 @@ typedef enum {
|
||||||
} friso_lex_t;
|
} friso_lex_t;
|
||||||
|
|
||||||
typedef friso_hash_t * friso_dic_t;
|
typedef friso_hash_t * friso_dic_t;
|
||||||
#define __FRISO_LEXICON_LENGTH__ 12
|
#define __FRISO_LEXICON_LENGTH__ 12
|
||||||
|
|
||||||
|
|
||||||
//charset that Friso now support.
|
//charset that Friso now support.
|
||||||
|
@ -59,7 +59,7 @@ typedef enum {
|
||||||
/*
|
/*
|
||||||
* Type: friso_mode_t
|
* Type: friso_mode_t
|
||||||
* ------------------
|
* ------------------
|
||||||
* use to identidy the mode that the friso use.
|
* use to identidy the mode that the friso use.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
__FRISO_SIMPLE_MODE__ = 1,
|
__FRISO_SIMPLE_MODE__ = 1,
|
||||||
|
@ -79,7 +79,7 @@ typedef friso_entry * friso_t;
|
||||||
/*
|
/*
|
||||||
* Type: lex_entry_cdt
|
* Type: lex_entry_cdt
|
||||||
* -------------------
|
* -------------------
|
||||||
* This type used to represent the lexicon entry struct.
|
* This type used to represent the lexicon entry struct.
|
||||||
*/
|
*/
|
||||||
#define _LEX_APPENSYN_MASK (1 << 0) //append synoyums words.
|
#define _LEX_APPENSYN_MASK (1 << 0) //append synoyums words.
|
||||||
#define lex_appensyn_open(e) e->ctrlMask |= _LEX_APPENSYN_MASK
|
#define lex_appensyn_open(e) e->ctrlMask |= _LEX_APPENSYN_MASK
|
||||||
|
@ -123,7 +123,7 @@ typedef friso_token_entry * friso_token_t;
|
||||||
/*
|
/*
|
||||||
* Type: friso_task_entry
|
* Type: friso_task_entry
|
||||||
* This type used to represent the current segmentation content.
|
* This type used to represent the current segmentation content.
|
||||||
* like the text to split, and the current index, token buffer eg....
|
* like the text to split, and the current index, token buffer eg....
|
||||||
*/
|
*/
|
||||||
//action control mask for #FRISO_TASK_T#.
|
//action control mask for #FRISO_TASK_T#.
|
||||||
#define _TASK_CHECK_CF_MASK (1 << 0) //Wether to check the chinese fraction.
|
#define _TASK_CHECK_CF_MASK (1 << 0) //Wether to check the chinese fraction.
|
||||||
|
@ -166,9 +166,9 @@ struct friso_config_struct {
|
||||||
friso_mode_t mode; //Complex mode or simple mode
|
friso_mode_t mode; //Complex mode or simple mode
|
||||||
|
|
||||||
//pointer to the function to get the next token
|
//pointer to the function to get the next token
|
||||||
friso_token_t (*next_token) (friso_t, struct friso_config_struct *, friso_task_t);
|
friso_token_t (*next_token)(friso_t, struct friso_config_struct *, friso_task_t);
|
||||||
//pointer to the function to get the next cjk lex_entry_t
|
//pointer to the function to get the next cjk lex_entry_t
|
||||||
lex_entry_t (*next_cjk ) (friso_t, struct friso_config_struct *, friso_task_t);
|
lex_entry_t (*next_cjk)(friso_t, struct friso_config_struct *, friso_task_t);
|
||||||
|
|
||||||
char kpuncs[_FRISO_KEEP_PUNC_LEN]; //keep punctuations buffer.
|
char kpuncs[_FRISO_KEEP_PUNC_LEN]; //keep punctuations buffer.
|
||||||
};
|
};
|
||||||
|
@ -181,28 +181,28 @@ typedef friso_config_entry * friso_config_t;
|
||||||
* Function: friso_new;
|
* Function: friso_new;
|
||||||
* Usage: vars = friso_new( void );
|
* Usage: vars = friso_new( void );
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
* This function used to create a new empty friso friso_t;
|
* This function used to create a new empty friso friso_t;
|
||||||
* with default value.
|
* with default value.
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_t friso_new( void );
|
FRISO_API friso_t friso_new(void);
|
||||||
|
|
||||||
//creat a friso entry with a default value from a configuratile file.
|
//creat a friso entry with a default value from a configuratile file.
|
||||||
//@return 1 for successfully and 0 for failed.
|
//@return 1 for successfully and 0 for failed.
|
||||||
FRISO_API int friso_init_from_ifile( friso_t, friso_config_t, fstring );
|
FRISO_API int friso_init_from_ifile(friso_t, friso_config_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_free_vars;
|
* Function: friso_free_vars;
|
||||||
* Usage: friso_free( vars );
|
* Usage: friso_free( vars );
|
||||||
* --------------------------
|
* --------------------------
|
||||||
* This function is used to free the allocation of the given vars.
|
* This function is used to free the allocation of the given vars.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_free( friso_t );
|
FRISO_API void friso_free(friso_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_set_dic
|
* Function: friso_set_dic
|
||||||
* Usage: dic = friso_set_dic( vars, dic );
|
* Usage: dic = friso_set_dic( vars, dic );
|
||||||
* ----------------------------------------
|
* ----------------------------------------
|
||||||
* This function is used to set the dictionary for friso.
|
* This function is used to set the dictionary for friso.
|
||||||
* and firso_dic_t is the pointer of a hash table array.
|
* and firso_dic_t is the pointer of a hash table array.
|
||||||
*/
|
*/
|
||||||
//FRISO_API void friso_set_dic( friso_t, friso_dic_t );
|
//FRISO_API void friso_set_dic( friso_t, friso_dic_t );
|
||||||
|
@ -217,14 +217,14 @@ do {\
|
||||||
* ------------------------------------
|
* ------------------------------------
|
||||||
* This function is used to set the mode(complex or simple) that you want to friso to use.
|
* This function is used to set the mode(complex or simple) that you want to friso to use.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_set_mode( friso_config_t, friso_mode_t );
|
FRISO_API void friso_set_mode(friso_config_t, friso_mode_t);
|
||||||
|
|
||||||
/*create a new friso configuration entry and initialize
|
/*create a new friso configuration entry and initialize
|
||||||
it with the default value.*/
|
it with the default value.*/
|
||||||
FRISO_API friso_config_t friso_new_config( void );
|
FRISO_API friso_config_t friso_new_config(void);
|
||||||
|
|
||||||
//initialize the specified friso config entry with default value.
|
//initialize the specified friso config entry with default value.
|
||||||
FRISO_API void friso_init_config( friso_config_t );
|
FRISO_API void friso_init_config(friso_config_t);
|
||||||
|
|
||||||
//free the specified friso configuration entry.
|
//free the specified friso configuration entry.
|
||||||
//FRISO_API void friso_free_config( friso_config_t );
|
//FRISO_API void friso_free_config( friso_config_t );
|
||||||
|
@ -234,20 +234,20 @@ FRISO_API void friso_init_config( friso_config_t );
|
||||||
* Function: friso_new_task;
|
* Function: friso_new_task;
|
||||||
* Usage: segment = friso_new_task( void );
|
* Usage: segment = friso_new_task( void );
|
||||||
* ----------------------------------------
|
* ----------------------------------------
|
||||||
* This function is used to create a new friso segment type;
|
* This function is used to create a new friso segment type;
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_task_t friso_new_task( void );
|
FRISO_API friso_task_t friso_new_task(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_free_task;
|
* Function: friso_free_task;
|
||||||
* Usage: friso_free_task( task );
|
* Usage: friso_free_task( task );
|
||||||
* -------------------------------
|
* -------------------------------
|
||||||
* This function is used to free the allocation of function friso_new_segment();
|
* This function is used to free the allocation of function friso_new_segment();
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_free_task( friso_task_t );
|
FRISO_API void friso_free_task(friso_task_t);
|
||||||
|
|
||||||
//create a new friso token
|
//create a new friso token
|
||||||
FRISO_API friso_token_t friso_new_token( void );
|
FRISO_API friso_token_t friso_new_token(void);
|
||||||
|
|
||||||
//free the given friso token
|
//free the given friso token
|
||||||
//FRISO_API void friso_free_token( friso_token_t );
|
//FRISO_API void friso_free_token( friso_token_t );
|
||||||
|
@ -257,16 +257,16 @@ FRISO_API friso_token_t friso_new_token( void );
|
||||||
* Function: friso_set_text
|
* Function: friso_set_text
|
||||||
* Usage: friso_set_text( task, text );
|
* Usage: friso_set_text( task, text );
|
||||||
* ------------------------------------
|
* ------------------------------------
|
||||||
* This function is used to set the text that is going to segment.
|
* This function is used to set the text that is going to segment.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_set_text( friso_task_t, fstring );
|
FRISO_API void friso_set_text(friso_task_t, fstring);
|
||||||
|
|
||||||
|
|
||||||
//get the next cjk word with mmseg simple mode
|
//get the next cjk word with mmseg simple mode
|
||||||
FRISO_API lex_entry_t next_simple_cjk( friso_t, friso_config_t, friso_task_t );
|
FRISO_API lex_entry_t next_simple_cjk(friso_t, friso_config_t, friso_task_t);
|
||||||
|
|
||||||
//get the next cjk word with mmseg complex mode(mmseg core algorithm)
|
//get the next cjk word with mmseg complex mode(mmseg core algorithm)
|
||||||
FRISO_API lex_entry_t next_complex_cjk( friso_t, friso_config_t, friso_task_t );
|
FRISO_API lex_entry_t next_complex_cjk(friso_t, friso_config_t, friso_task_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: next_mmseg_token
|
* Function: next_mmseg_token
|
||||||
|
@ -275,10 +275,10 @@ FRISO_API lex_entry_t next_complex_cjk( friso_t, friso_config_t, friso_task_t );
|
||||||
* This function is used to get next word that friso segmented
|
* This function is used to get next word that friso segmented
|
||||||
* with a split mode of __FRISO_SIMPLE_MODE__ or __FRISO_COMPLEX_MODE__
|
* with a split mode of __FRISO_SIMPLE_MODE__ or __FRISO_COMPLEX_MODE__
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_token_t next_mmseg_token( friso_t, friso_config_t, friso_task_t );
|
FRISO_API friso_token_t next_mmseg_token(friso_t, friso_config_t, friso_task_t);
|
||||||
|
|
||||||
//__FRISO_DETECT_MODE__
|
//__FRISO_DETECT_MODE__
|
||||||
FRISO_API friso_token_t next_detect_token( friso_t, friso_config_t, friso_task_t );
|
FRISO_API friso_token_t next_detect_token(friso_t, friso_config_t, friso_task_t);
|
||||||
/* }}} friso main interface define :: end*/
|
/* }}} friso main interface define :: end*/
|
||||||
|
|
||||||
/* {{{ lexicon interface define :: start*/
|
/* {{{ lexicon interface define :: start*/
|
||||||
|
@ -289,42 +289,42 @@ FRISO_API friso_token_t next_detect_token( friso_t, friso_config_t, friso_task_t
|
||||||
* -----------------------------
|
* -----------------------------
|
||||||
* This function used to create a new dictionary.(memory allocation).
|
* This function used to create a new dictionary.(memory allocation).
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_dic_t friso_dic_new( void );
|
FRISO_API friso_dic_t friso_dic_new(void);
|
||||||
|
|
||||||
FRISO_API fstring file_get_line( fstring, FILE * );
|
FRISO_API fstring file_get_line(fstring, FILE *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_free
|
* Function: friso_dic_free
|
||||||
* Usage: friso_dic_free( void );
|
* Usage: friso_dic_free( void );
|
||||||
* ------------------------------
|
* ------------------------------
|
||||||
* This function is used to free all the allocation of friso_dic_new.
|
* This function is used to free all the allocation of friso_dic_new.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_free( friso_dic_t );
|
FRISO_API void friso_dic_free(friso_dic_t);
|
||||||
|
|
||||||
//create a new lexicon entry.
|
//create a new lexicon entry.
|
||||||
FRISO_API lex_entry_t new_lex_entry( fstring, friso_array_t, uint_t, uint_t, uint_t );
|
FRISO_API lex_entry_t new_lex_entry(fstring, friso_array_t, uint_t, uint_t, uint_t);
|
||||||
|
|
||||||
//free the given lexicon entry.
|
//free the given lexicon entry.
|
||||||
//free all the allocations that its synonyms word's items pointed to
|
//free all the allocations that its synonyms word's items pointed to
|
||||||
//when the second arguments is 1
|
//when the second arguments is 1
|
||||||
FRISO_API void free_lex_entry_full( lex_entry_t );
|
FRISO_API void free_lex_entry_full(lex_entry_t);
|
||||||
FRISO_API void free_lex_entry( lex_entry_t );
|
FRISO_API void free_lex_entry(lex_entry_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_load
|
* Function: friso_dic_load
|
||||||
* Usage: friso_dic_load( friso, friso_lex_t, path, length );
|
* Usage: friso_dic_load( friso, friso_lex_t, path, length );
|
||||||
* --------------------------------------------------
|
* --------------------------------------------------
|
||||||
* This function is used to load dictionary from a given path.
|
* This function is used to load dictionary from a given path.
|
||||||
* no length limit when length less than 0.
|
* no length limit when length less than 0.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_load( friso_t, friso_config_t,
|
FRISO_API void friso_dic_load(friso_t, friso_config_t,
|
||||||
friso_lex_t, fstring, uint_t );
|
friso_lex_t, fstring, uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* load the lexicon configuration file.
|
* load the lexicon configuration file.
|
||||||
* and load all the valid lexicon from the conf file.
|
* and load all the valid lexicon from the conf file.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_load_from_ifile( friso_t, friso_config_t, fstring, uint_t );
|
FRISO_API void friso_dic_load_from_ifile(friso_t, friso_config_t, fstring, uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_match
|
* Function: friso_dic_match
|
||||||
|
@ -332,7 +332,7 @@ FRISO_API void friso_dic_load_from_ifile( friso_t, friso_config_t, fstring, uint
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
* This function used to put new word into the dictionary.
|
* This function used to put new word into the dictionary.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_add( friso_dic_t, friso_lex_t, fstring, friso_array_t );
|
FRISO_API void friso_dic_add(friso_dic_t, friso_lex_t, fstring, friso_array_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_add_with_fre
|
* Function: friso_dic_add_with_fre
|
||||||
|
@ -340,15 +340,15 @@ FRISO_API void friso_dic_add( friso_dic_t, friso_lex_t, fstring, friso_array_t )
|
||||||
* -------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
* This function used to put new word width frequency into the dictionary.
|
* This function used to put new word width frequency into the dictionary.
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_add_with_fre( friso_dic_t, friso_lex_t, fstring, friso_array_t, uint_t );
|
FRISO_API void friso_dic_add_with_fre(friso_dic_t, friso_lex_t, fstring, friso_array_t, uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_match
|
* Function: friso_dic_match
|
||||||
* Usage: result = friso_dic_match( dic, friso_lex_t, word );
|
* Usage: result = friso_dic_match( dic, friso_lex_t, word );
|
||||||
* ----------------------------------------------------
|
* ----------------------------------------------------
|
||||||
* This function is used to check the given word is in the dictionary or not.
|
* This function is used to check the given word is in the dictionary or not.
|
||||||
*/
|
*/
|
||||||
FRISO_API int friso_dic_match( friso_dic_t, friso_lex_t, fstring );
|
FRISO_API int friso_dic_match(friso_dic_t, friso_lex_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_dic_get
|
* Function: friso_dic_get
|
||||||
|
@ -356,15 +356,15 @@ FRISO_API int friso_dic_match( friso_dic_t, friso_lex_t, fstring );
|
||||||
* -----------------------------------------
|
* -----------------------------------------
|
||||||
* This function is used to search the specified lex_entry_t.
|
* This function is used to search the specified lex_entry_t.
|
||||||
*/
|
*/
|
||||||
FRISO_API lex_entry_t friso_dic_get( friso_dic_t, friso_lex_t, fstring );
|
FRISO_API lex_entry_t friso_dic_get(friso_dic_t, friso_lex_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: friso_spec_dic_size
|
* Function: friso_spec_dic_size
|
||||||
* Usage: friso_spec_dic_size( dic, friso_lex_t )
|
* Usage: friso_spec_dic_size( dic, friso_lex_t )
|
||||||
* This function is used to get the size of the dictionary with a specified type.
|
* This function is used to get the size of the dictionary with a specified type.
|
||||||
*/
|
*/
|
||||||
FRISO_API uint_t friso_spec_dic_size( friso_dic_t, friso_lex_t );
|
FRISO_API uint_t friso_spec_dic_size(friso_dic_t, friso_lex_t);
|
||||||
FRISO_API uint_t friso_all_dic_size( friso_dic_t );
|
FRISO_API uint_t friso_all_dic_size(friso_dic_t);
|
||||||
/* }}} lexicon interface define :: end*/
|
/* }}} lexicon interface define :: end*/
|
||||||
|
|
||||||
#endif /*end ifndef*/
|
#endif /*end ifndef*/
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* 2. hashmap interface.
|
* 2. hashmap interface.
|
||||||
* 3. dynamaic array interface.
|
* 3. dynamaic array interface.
|
||||||
* 4. double link list interface.
|
* 4. double link list interface.
|
||||||
*
|
*
|
||||||
* @author chenxin <chenxin619315@gmail.com>
|
* @author chenxin <chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -68,45 +68,45 @@ typedef string_buffer_entry * string_buffer_t;
|
||||||
//FRISO_API string_buffer_t new_string_buffer( void );
|
//FRISO_API string_buffer_t new_string_buffer( void );
|
||||||
#define new_string_buffer() \
|
#define new_string_buffer() \
|
||||||
new_string_buffer_with_opacity( __DEFAULT_ARRAY_LIST_OPACITY__ );
|
new_string_buffer_with_opacity( __DEFAULT_ARRAY_LIST_OPACITY__ );
|
||||||
FRISO_API string_buffer_t new_string_buffer_with_opacity( uint_t );
|
FRISO_API string_buffer_t new_string_buffer_with_opacity(uint_t);
|
||||||
FRISO_API string_buffer_t new_string_buffer_with_string( fstring str );
|
FRISO_API string_buffer_t new_string_buffer_with_string(fstring str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this function will copy the chars that the fstring pointed.
|
* this function will copy the chars that the fstring pointed.
|
||||||
* to the buffer.
|
* to the buffer.
|
||||||
* this may cause the resize action of the buffer.
|
* this may cause the resize action of the buffer.
|
||||||
*/
|
*/
|
||||||
FRISO_API void string_buffer_append( string_buffer_t, fstring );
|
FRISO_API void string_buffer_append(string_buffer_t, fstring);
|
||||||
FRISO_API void string_buffer_append_char( string_buffer_t, char );
|
FRISO_API void string_buffer_append_char(string_buffer_t, char);
|
||||||
|
|
||||||
//insert the given fstring from the specified position.
|
//insert the given fstring from the specified position.
|
||||||
FRISO_API void string_buffer_insert( string_buffer_t, uint_t idx, fstring );
|
FRISO_API void string_buffer_insert(string_buffer_t, uint_t idx, fstring);
|
||||||
|
|
||||||
//remove the char in the specified position.
|
//remove the char in the specified position.
|
||||||
FRISO_API fstring string_buffer_remove( string_buffer_t, uint_t idx, uint_t );
|
FRISO_API fstring string_buffer_remove(string_buffer_t, uint_t idx, uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* turn the string_buffer to a string.
|
* turn the string_buffer to a string.
|
||||||
* or return the buffer of the string_buffer.
|
* or return the buffer of the string_buffer.
|
||||||
*/
|
*/
|
||||||
FRISO_API string_buffer_t string_buffer_trim( string_buffer_t );
|
FRISO_API string_buffer_t string_buffer_trim(string_buffer_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free the given fstring buffer.
|
* free the given fstring buffer.
|
||||||
* and this function will not free the allocations of the
|
* and this function will not free the allocations of the
|
||||||
* the string_buffer_t->buffer, we return it to you, if there is
|
* the string_buffer_t->buffer, we return it to you, if there is
|
||||||
* a necessary you could free it youself by calling free();
|
* a necessary you could free it youself by calling free();
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring string_buffer_devote( string_buffer_t );
|
FRISO_API fstring string_buffer_devote(string_buffer_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clear the given fstring buffer.
|
* clear the given fstring buffer.
|
||||||
* reset its buffer with 0 and reset its length to 0.
|
* reset its buffer with 0 and reset its length to 0.
|
||||||
*/
|
*/
|
||||||
FRISO_API void string_buffer_clear( string_buffer_t );
|
FRISO_API void string_buffer_clear(string_buffer_t);
|
||||||
|
|
||||||
//free the fstring buffer include the buffer.
|
//free the fstring buffer include the buffer.
|
||||||
FRISO_API void free_string_buffer( string_buffer_t );
|
FRISO_API void free_string_buffer(string_buffer_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fstring specified chars tokenizer functions
|
* fstring specified chars tokenizer functions
|
||||||
|
@ -126,28 +126,28 @@ typedef string_split_entry * string_split_t;
|
||||||
* create a new string_split_entry.
|
* create a new string_split_entry.
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* @return string_split_t;
|
* @return string_split_t;
|
||||||
*/
|
*/
|
||||||
FRISO_API string_split_t new_string_split( fstring, fstring );
|
FRISO_API string_split_t new_string_split(fstring, fstring);
|
||||||
|
|
||||||
FRISO_API void string_split_reset( string_split_t, fstring, fstring );
|
FRISO_API void string_split_reset(string_split_t, fstring, fstring);
|
||||||
|
|
||||||
FRISO_API void string_split_set_source( string_split_t, fstring );
|
FRISO_API void string_split_set_source(string_split_t, fstring);
|
||||||
|
|
||||||
FRISO_API void string_split_set_delimiter( string_split_t, fstring );
|
FRISO_API void string_split_set_delimiter(string_split_t, fstring);
|
||||||
|
|
||||||
FRISO_API void free_string_split( string_split_t );
|
FRISO_API void free_string_split(string_split_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the next split fstring, and copy the
|
* get the next split fstring, and copy the
|
||||||
* splited fstring into the __dst buffer .
|
* splited fstring into the __dst buffer .
|
||||||
*
|
*
|
||||||
* @param string_split_t
|
* @param string_split_t
|
||||||
* @param __dst
|
* @param __dst
|
||||||
* @return fstring (NULL if reach the end of the source
|
* @return fstring (NULL if reach the end of the source
|
||||||
* or there is no more segmentation)
|
* or there is no more segmentation)
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring string_split_next( string_split_t, fstring );
|
FRISO_API fstring string_split_next(string_split_t, fstring);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,37 +170,37 @@ typedef friso_array_entry * friso_array_t;
|
||||||
#define new_array_list() new_array_list_with_opacity(__DEFAULT_ARRAY_LIST_OPACITY__)
|
#define new_array_list() new_array_list_with_opacity(__DEFAULT_ARRAY_LIST_OPACITY__)
|
||||||
|
|
||||||
//create a new friso dynamic array with the given opacity
|
//create a new friso dynamic array with the given opacity
|
||||||
FRISO_API friso_array_t new_array_list_with_opacity( uint_t );
|
FRISO_API friso_array_t new_array_list_with_opacity(uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free the given friso array.
|
* free the given friso array.
|
||||||
* and its items, but never where the items's item to pointed to .
|
* and its items, but never where the items's item to pointed to .
|
||||||
*/
|
*/
|
||||||
FRISO_API void free_array_list( friso_array_t );
|
FRISO_API void free_array_list(friso_array_t);
|
||||||
|
|
||||||
//add a new item to the array.
|
//add a new item to the array.
|
||||||
FRISO_API void array_list_add( friso_array_t, void * );
|
FRISO_API void array_list_add(friso_array_t, void *);
|
||||||
|
|
||||||
//insert a new item at a specifed position.
|
//insert a new item at a specifed position.
|
||||||
FRISO_API void array_list_insert( friso_array_t, uint_t, void * );
|
FRISO_API void array_list_insert(friso_array_t, uint_t, void *);
|
||||||
|
|
||||||
//get a item at a specified position.
|
//get a item at a specified position.
|
||||||
FRISO_API void *array_list_get( friso_array_t, uint_t );
|
FRISO_API void *array_list_get(friso_array_t, uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set the item at a specified position.
|
* set the item at a specified position.
|
||||||
* this will return the old value.
|
* this will return the old value.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *array_list_set( friso_array_t, uint_t, void * );
|
FRISO_API void *array_list_set(friso_array_t, uint_t, void *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove the given item at a specified position.
|
* remove the given item at a specified position.
|
||||||
* this will return the value of the removed item.
|
* this will return the value of the removed item.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *array_list_remove( friso_array_t, uint_t );
|
FRISO_API void *array_list_remove(friso_array_t, uint_t);
|
||||||
|
|
||||||
/*trim the array list for final use.*/
|
/*trim the array list for final use.*/
|
||||||
FRISO_API friso_array_t array_list_trim( friso_array_t );
|
FRISO_API friso_array_t array_list_trim(friso_array_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clear the array list.
|
* clear the array list.
|
||||||
|
@ -208,7 +208,7 @@ FRISO_API friso_array_t array_list_trim( friso_array_t );
|
||||||
* but will not free the point array allocations,
|
* but will not free the point array allocations,
|
||||||
* and will reset the length of it.
|
* and will reset the length of it.
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_array_t array_list_clear( friso_array_t );
|
FRISO_API friso_array_t array_list_clear(friso_array_t);
|
||||||
|
|
||||||
//return the size of the array.
|
//return the size of the array.
|
||||||
//FRISO_API uint_t array_list_size( friso_array_t );
|
//FRISO_API uint_t array_list_size( friso_array_t );
|
||||||
|
@ -247,10 +247,10 @@ typedef struct {
|
||||||
typedef friso_link_entry * friso_link_t;
|
typedef friso_link_entry * friso_link_t;
|
||||||
|
|
||||||
//create a new link list
|
//create a new link list
|
||||||
FRISO_API friso_link_t new_link_list( void );
|
FRISO_API friso_link_t new_link_list(void);
|
||||||
|
|
||||||
//free the specified link list
|
//free the specified link list
|
||||||
FRISO_API void free_link_list( friso_link_t );
|
FRISO_API void free_link_list(friso_link_t);
|
||||||
|
|
||||||
//return the size of the current link list.
|
//return the size of the current link list.
|
||||||
//FRISO_API uint_t link_list_size( friso_link_t );
|
//FRISO_API uint_t link_list_size( friso_link_t );
|
||||||
|
@ -261,37 +261,37 @@ FRISO_API void free_link_list( friso_link_t );
|
||||||
#define link_list_empty( link ) (link->size == 0)
|
#define link_list_empty( link ) (link->size == 0)
|
||||||
|
|
||||||
//clear all the nodes in the link list( except the head and the tail ).
|
//clear all the nodes in the link list( except the head and the tail ).
|
||||||
FRISO_API friso_link_t link_list_clear( friso_link_t link );
|
FRISO_API friso_link_t link_list_clear(friso_link_t link);
|
||||||
|
|
||||||
//add a new node to the link list.(append from the tail)
|
//add a new node to the link list.(append from the tail)
|
||||||
FRISO_API void link_list_add( friso_link_t, void * );
|
FRISO_API void link_list_add(friso_link_t, void *);
|
||||||
|
|
||||||
//add a new node before the specified node
|
//add a new node before the specified node
|
||||||
FRISO_API void link_list_insert_before( friso_link_t, uint_t, void * );
|
FRISO_API void link_list_insert_before(friso_link_t, uint_t, void *);
|
||||||
|
|
||||||
//get the node in the current index.
|
//get the node in the current index.
|
||||||
FRISO_API void *link_list_get( friso_link_t, uint_t );
|
FRISO_API void *link_list_get(friso_link_t, uint_t);
|
||||||
|
|
||||||
//modify the node in the current index.
|
//modify the node in the current index.
|
||||||
FRISO_API void *link_list_set( friso_link_t, uint_t, void * );
|
FRISO_API void *link_list_set(friso_link_t, uint_t, void *);
|
||||||
|
|
||||||
//remove the specified link node
|
//remove the specified link node
|
||||||
FRISO_API void *link_list_remove( friso_link_t, uint_t );
|
FRISO_API void *link_list_remove(friso_link_t, uint_t);
|
||||||
|
|
||||||
//remove the given node
|
//remove the given node
|
||||||
FRISO_API void *link_list_remove_node( friso_link_t, link_node_t );
|
FRISO_API void *link_list_remove_node(friso_link_t, link_node_t);
|
||||||
|
|
||||||
//remove the node from the frist.
|
//remove the node from the frist.
|
||||||
FRISO_API void *link_list_remove_first( friso_link_t );
|
FRISO_API void *link_list_remove_first(friso_link_t);
|
||||||
|
|
||||||
//remove the last node from the link list
|
//remove the last node from the link list
|
||||||
FRISO_API void *link_list_remove_last( friso_link_t );
|
FRISO_API void *link_list_remove_last(friso_link_t);
|
||||||
|
|
||||||
//append a node from the end.
|
//append a node from the end.
|
||||||
FRISO_API void link_list_add_last( friso_link_t, void * );
|
FRISO_API void link_list_add_last(friso_link_t, void *);
|
||||||
|
|
||||||
//add a node at the begining of the link list.
|
//add a node at the begining of the link list.
|
||||||
FRISO_API void link_list_add_first( friso_link_t, void * );
|
FRISO_API void link_list_add_first(friso_link_t, void *);
|
||||||
/* }}} link list interface define::end*/
|
/* }}} link list interface define::end*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ struct hash_entry {
|
||||||
};
|
};
|
||||||
typedef struct hash_entry friso_hash_entry;
|
typedef struct hash_entry friso_hash_entry;
|
||||||
typedef friso_hash_entry * hash_entry_t;
|
typedef friso_hash_entry * hash_entry_t;
|
||||||
typedef void (*fhash_callback_fn_t)( hash_entry_t );
|
typedef void (*fhash_callback_fn_t)(hash_entry_t);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint_t length;
|
uint_t length;
|
||||||
|
@ -324,10 +324,10 @@ typedef friso_hash_cdt * friso_hash_t;
|
||||||
/*
|
/*
|
||||||
* Function: new_hash_table
|
* Function: new_hash_table
|
||||||
* Usage: table = new_hash_table();
|
* Usage: table = new_hash_table();
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
* this function allocates a new symbol table with no entries.
|
* this function allocates a new symbol table with no entries.
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_hash_t new_hash_table( void );
|
FRISO_API friso_hash_t new_hash_table(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: free_hash_table
|
* Function: free_hash_table
|
||||||
|
@ -335,7 +335,7 @@ FRISO_API friso_hash_t new_hash_table( void );
|
||||||
* --------------------------------------
|
* --------------------------------------
|
||||||
* this function will free all the allocation for memory.
|
* this function will free all the allocation for memory.
|
||||||
*/
|
*/
|
||||||
FRISO_API void free_hash_table( friso_hash_t, fhash_callback_fn_t );
|
FRISO_API void free_hash_table(friso_hash_t, fhash_callback_fn_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: put_new_mapping
|
* Function: put_new_mapping
|
||||||
|
@ -343,7 +343,7 @@ FRISO_API void free_hash_table( friso_hash_t, fhash_callback_fn_t );
|
||||||
* ----------------------------------------
|
* ----------------------------------------
|
||||||
* the function associates the specified key with the given value.
|
* the function associates the specified key with the given value.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *hash_put_mapping( friso_hash_t, fstring, void * );
|
FRISO_API void *hash_put_mapping(friso_hash_t, fstring, void *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: is_mapping_exists
|
* Function: is_mapping_exists
|
||||||
|
@ -351,7 +351,7 @@ FRISO_API void *hash_put_mapping( friso_hash_t, fstring, void * );
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
* this function check the given key mapping is exists or not.
|
* this function check the given key mapping is exists or not.
|
||||||
*/
|
*/
|
||||||
FRISO_API int hash_exist_mapping( friso_hash_t, fstring );
|
FRISO_API int hash_exist_mapping(friso_hash_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: get_mapping_value
|
* Function: get_mapping_value
|
||||||
|
@ -360,7 +360,7 @@ FRISO_API int hash_exist_mapping( friso_hash_t, fstring );
|
||||||
* this function return the value associated with the given key.
|
* this function return the value associated with the given key.
|
||||||
* UNDEFINED will be return if the mapping is not exists.
|
* UNDEFINED will be return if the mapping is not exists.
|
||||||
*/
|
*/
|
||||||
FRISO_API void * hash_get_value( friso_hash_t, fstring );
|
FRISO_API void * hash_get_value(friso_hash_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: remove_mapping
|
* Function: remove_mapping
|
||||||
|
@ -368,13 +368,13 @@ FRISO_API void * hash_get_value( friso_hash_t, fstring );
|
||||||
* ------------------------------------
|
* ------------------------------------
|
||||||
* This function is used to remove the mapping associated with the given key.
|
* This function is used to remove the mapping associated with the given key.
|
||||||
*/
|
*/
|
||||||
FRISO_API hash_entry_t hash_remove_mapping( friso_hash_t, fstring );
|
FRISO_API hash_entry_t hash_remove_mapping(friso_hash_t, fstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: get_table_size
|
* Function: get_table_size
|
||||||
* Usage: size = get_table_size( table );
|
* Usage: size = get_table_size( table );
|
||||||
* --------------------------------------
|
* --------------------------------------
|
||||||
* This function is used to count the size of the specified table.
|
* This function is used to count the size of the specified table.
|
||||||
*/
|
*/
|
||||||
//FRISO_API uint_t hash_get_size( friso_hash_t );
|
//FRISO_API uint_t hash_get_size( friso_hash_t );
|
||||||
#define hash_get_size( hash ) hash->size
|
#define hash_get_size( hash ) hash->size
|
||||||
|
|
|
@ -15,16 +15,15 @@
|
||||||
*
|
*
|
||||||
* @return int the bytes of the current readed word.
|
* @return int the bytes of the current readed word.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_next_word(
|
FRISO_API int gbk_next_word(
|
||||||
friso_task_t task,
|
friso_task_t task,
|
||||||
uint_t *idx,
|
uint_t *idx,
|
||||||
fstring __word )
|
fstring __word) {
|
||||||
{
|
|
||||||
int c;
|
int c;
|
||||||
if ( *idx >= task->length ) return 0;
|
if(*idx >= task->length) return 0;
|
||||||
|
|
||||||
c = (uchar_t)task->text[*idx];
|
c = (uchar_t)task->text[*idx];
|
||||||
if ( c <= 0x80 ) {
|
if(c <= 0x80) {
|
||||||
task->bytes = 1;
|
task->bytes = 1;
|
||||||
} else {
|
} else {
|
||||||
task->bytes = 2;
|
task->bytes = 2;
|
||||||
|
@ -46,29 +45,27 @@ FRISO_API int gbk_next_word(
|
||||||
|
|
||||||
//check if the given buffer is a gbk word (ANSII string).
|
//check if the given buffer is a gbk word (ANSII string).
|
||||||
// included the simplified and traditional words.
|
// included the simplified and traditional words.
|
||||||
FRISO_API int gbk_cn_string(char *str)
|
FRISO_API int gbk_cn_string(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
//GBK/2: gb2312 chinese word.
|
//GBK/2: gb2312 chinese word.
|
||||||
return ( ((c1 >= 0xb0 && c1 <= 0xf7)
|
return (((c1 >= 0xb0 && c1 <= 0xf7)
|
||||||
&& (c2 >= 0xa1 && c2 <= 0xfe))
|
&& (c2 >= 0xa1 && c2 <= 0xfe))
|
||||||
//GBK/3: extend chinese words.
|
//GBK/3: extend chinese words.
|
||||||
|| ((c1 >= 0x81 && c1 <= 0xa0)
|
|| ((c1 >= 0x81 && c1 <= 0xa0)
|
||||||
&& ( (c2 >= 0x40 && c2 <= 0x7e)
|
&& ((c2 >= 0x40 && c2 <= 0x7e)
|
||||||
|| (c2 >= 0x80 && c2 <= 0xfe) ))
|
|| (c2 >= 0x80 && c2 <= 0xfe)))
|
||||||
//GBK/4: extend chinese words.
|
//GBK/4: extend chinese words.
|
||||||
|| ((c1 >= 0xaa && c1 <= 0xfe)
|
|| ((c1 >= 0xaa && c1 <= 0xfe)
|
||||||
&& ( (c2 >= 0x40 && c2 <= 0xfe)
|
&& ((c2 >= 0x40 && c2 <= 0xfe)
|
||||||
|| (c2 >= 0x80 && c2 <= 0xa0) )) );
|
|| (c2 >= 0x80 && c2 <= 0xa0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*check if the given char is a ASCII letter
|
/*check if the given char is a ASCII letter
|
||||||
* include all the arabic number, letters and english puntuations.*/
|
* include all the arabic number, letters and english puntuations.*/
|
||||||
FRISO_API int gbk_halfwidth_en_char( char c )
|
FRISO_API int gbk_halfwidth_en_char(char c) {
|
||||||
{
|
|
||||||
int u = (uchar_t) c;
|
int u = (uchar_t) c;
|
||||||
return ( u >= 32 && u <= 126 );
|
return (u >= 32 && u <= 126);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -76,52 +73,48 @@ FRISO_API int gbk_halfwidth_en_char( char c )
|
||||||
* include the full-width arabic numeber, letters.
|
* include the full-width arabic numeber, letters.
|
||||||
* but not the full-width puntuations.
|
* but not the full-width puntuations.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_fullwidth_en_char( char *str )
|
FRISO_API int gbk_fullwidth_en_char(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
return ( (c1 == 0xA3)
|
return ((c1 == 0xA3)
|
||||||
&& ( (c2 >= 0xB0 && c2 <= 0xB9) //arabic numbers.
|
&& ((c2 >= 0xB0 && c2 <= 0xB9) //arabic numbers.
|
||||||
|| ( c2 >= 0xC1 && c2 <= 0xDA ) //uppercase letters.
|
|| (c2 >= 0xC1 && c2 <= 0xDA) //uppercase letters.
|
||||||
|| ( c2 >= 0xE1 && c2 <= 0xFA) ) ); //lowercase letters.
|
|| (c2 >= 0xE1 && c2 <= 0xFA))); //lowercase letters.
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the given char is a upper case english letter.
|
//check if the given char is a upper case english letter.
|
||||||
// included the full-width and half-width letters.
|
// included the full-width and half-width letters.
|
||||||
FRISO_API int gbk_uppercase_letter( char *str )
|
FRISO_API int gbk_uppercase_letter(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
if ( c1 <= 0x80 ) { //half-width
|
if(c1 <= 0x80) { //half-width
|
||||||
return ( c1 >= 65 && c1 <= 90 );
|
return (c1 >= 65 && c1 <= 90);
|
||||||
} else { //full-width
|
} else { //full-width
|
||||||
return ( c1 == 0xa3 && ( c2 >= 0xc1 && c2 <= 0xda ) );
|
return (c1 == 0xa3 && (c2 >= 0xc1 && c2 <= 0xda));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the given char is a lower case char.
|
//check if the given char is a lower case char.
|
||||||
// included the full-width and half-width letters.
|
// included the full-width and half-width letters.
|
||||||
FRISO_API int gbk_lowercase_letter( char *str )
|
FRISO_API int gbk_lowercase_letter(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
if ( c1 <= 0x80 ) { //half-width
|
if(c1 <= 0x80) { //half-width
|
||||||
return ( c1 >= 97 && c1 <= 122 );
|
return (c1 >= 97 && c1 <= 122);
|
||||||
} else { //full-width
|
} else { //full-width
|
||||||
return ( c1 == 0xa3 && ( c2 >= 0xe1 && c2 <= 0xfa ) );
|
return (c1 == 0xa3 && (c2 >= 0xe1 && c2 <= 0xfa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the given char is a arabic numeric.
|
//check if the given char is a arabic numeric.
|
||||||
// included the full-width and half-width arabic numeric.
|
// included the full-width and half-width arabic numeric.
|
||||||
FRISO_API int gbk_numeric_letter( char *str )
|
FRISO_API int gbk_numeric_letter(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
if ( c1 <= 0x80 ) { //half-width
|
if(c1 <= 0x80) { //half-width
|
||||||
return ( c1 >= 48 && c1 <= 57 );
|
return (c1 >= 48 && c1 <= 57);
|
||||||
} else { //full-width
|
} else { //full-width
|
||||||
return ( ( c1 == 0xa3 ) && ( c2 >= 0xb0 && c2 <= 0xb9 ) );
|
return ((c1 == 0xa3) && (c2 >= 0xb0 && c2 <= 0xb9));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,49 +122,47 @@ FRISO_API int gbk_numeric_letter( char *str )
|
||||||
* check if the given fstring is make up with numeric chars.
|
* check if the given fstring is make up with numeric chars.
|
||||||
* both full-width,half-width numeric is ok.
|
* both full-width,half-width numeric is ok.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_numeric_string( char *str )
|
FRISO_API int gbk_numeric_string(char *str) {
|
||||||
{
|
|
||||||
char *s = str;
|
char *s = str;
|
||||||
int c1 = 0;
|
int c1 = 0;
|
||||||
int c2 = 0;
|
int c2 = 0;
|
||||||
|
|
||||||
while ( *s != '\0' ) {
|
while(*s != '\0') {
|
||||||
c1 = (uchar_t) (*s++);
|
c1 = (uchar_t)(*s++);
|
||||||
if ( c1 <= 0x80 ) { //half-width
|
if(c1 <= 0x80) { //half-width
|
||||||
if ( c1 < 48 || c2 > 57 ) return 0;
|
if(c1 < 48 || c2 > 57) return 0;
|
||||||
} else { //full-width
|
} else { //full-width
|
||||||
if ( c1 != 0xa3 ) return 0;
|
if(c1 != 0xa3) return 0;
|
||||||
c2 = (uchar_t) (*s++);
|
c2 = (uchar_t)(*s++);
|
||||||
if ( c2 < 0xb0 || c2 > 0xb9 ) return 0;
|
if(c2 < 0xb0 || c2 > 0xb9) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API int gbk_decimal_string( char *str )
|
FRISO_API int gbk_decimal_string(char *str) {
|
||||||
{
|
|
||||||
int c1 = 0;
|
int c1 = 0;
|
||||||
int c2 = 0;
|
int c2 = 0;
|
||||||
int len = strlen(str), i, p = 0;
|
int len = strlen(str), i, p = 0;
|
||||||
|
|
||||||
//point header check.
|
//point header check.
|
||||||
if ( str[0] == '.' || str[len - 1] == '.' ) return 0;
|
if(str[0] == '.' || str[len - 1] == '.') return 0;
|
||||||
|
|
||||||
for ( i = 0; i < len; ) {
|
for(i = 0; i < len;) {
|
||||||
c1 = (uchar_t) str[i++];
|
c1 = (uchar_t) str[i++];
|
||||||
//count the number of the points.
|
//count the number of the points.
|
||||||
if ( c1 == 46 ) {
|
if(c1 == 46) {
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( c1 <= 0x80 ) { //half-width
|
if(c1 <= 0x80) { //half-width
|
||||||
if ( c1 < 48 || c1 > 57 ) return 0;
|
if(c1 < 48 || c1 > 57) return 0;
|
||||||
} else { //full-width
|
} else { //full-width
|
||||||
if ( c1 != 0xa3 ) return 0;
|
if(c1 != 0xa3) return 0;
|
||||||
c2 = (uchar_t) str[i++];
|
c2 = (uchar_t) str[i++];
|
||||||
if ( c2 < 0xb0 || c2 > 0xb9 ) return 0;
|
if(c2 < 0xb0 || c2 > 0xb9) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,17 +171,16 @@ FRISO_API int gbk_decimal_string( char *str )
|
||||||
|
|
||||||
//check if the given char is a english(ASCII) letter.
|
//check if the given char is a english(ASCII) letter.
|
||||||
// (full-width and half-width), not the punctuation/arabic of course.
|
// (full-width and half-width), not the punctuation/arabic of course.
|
||||||
FRISO_API int gbk_en_letter( char *str )
|
FRISO_API int gbk_en_letter(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
if ( c1 <= 0x80 ) {
|
if(c1 <= 0x80) {
|
||||||
return ( (c1 >= 65 && c1 <= 90) //lowercase
|
return ((c1 >= 65 && c1 <= 90) //lowercase
|
||||||
|| (c1 >= 97 && c1 <= 122)); //uppercase
|
|| (c1 >= 97 && c1 <= 122)); //uppercase
|
||||||
} else {
|
} else {
|
||||||
return ( (c1 == 0xa3)
|
return ((c1 == 0xa3)
|
||||||
&& ( ( c2 >= 0xc1 && c2 <= 0xda ) //lowercase
|
&& ((c2 >= 0xc1 && c2 <= 0xda) //lowercase
|
||||||
|| ( c2 >= 0xe1 && c2 <= 0xfa ) ) ); //uppercase
|
|| (c2 >= 0xe1 && c2 <= 0xfa))); //uppercase
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -198,65 +188,60 @@ FRISO_API int gbk_en_letter( char *str )
|
||||||
|
|
||||||
//check the given char is a whitespace or not.
|
//check the given char is a whitespace or not.
|
||||||
// included full-width and half-width whitespace.
|
// included full-width and half-width whitespace.
|
||||||
FRISO_API int gbk_whitespace( char *str )
|
FRISO_API int gbk_whitespace(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
if ( c1 <= 0x80 ) {
|
if(c1 <= 0x80) {
|
||||||
return (c1 == 32);
|
return (c1 == 32);
|
||||||
} else {
|
} else {
|
||||||
return ( c1 == 0xa3 && c2 == 0xa0 );
|
return (c1 == 0xa3 && c2 == 0xa0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the given char is a letter number like 'ⅠⅡ'
|
/* check if the given char is a letter number like 'ⅠⅡ'
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_letter_number( char *str )
|
FRISO_API int gbk_letter_number(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
return ( (c1 == 0xa2)
|
return ((c1 == 0xa2)
|
||||||
&& ( ( c2 >= 0xa1 && c2 <= 0xb0 ) //lowercase
|
&& ((c2 >= 0xa1 && c2 <= 0xb0) //lowercase
|
||||||
|| ( c2 >= 0xf0 && c2 <= 0xfe ) ) ); //uppercase
|
|| (c2 >= 0xf0 && c2 <= 0xfe))); //uppercase
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given char is a other number like '①⑩⑽㈩'
|
* check if the given char is a other number like '①⑩⑽㈩'
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_other_number( char *str )
|
FRISO_API int gbk_other_number(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
return ( ( c1 == 0xa2 ) && ( c2 >= 0xc5 && c2 <= 0xee ) );
|
return ((c1 == 0xa2) && (c2 >= 0xc5 && c2 <= 0xee));
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the given char is a english punctuation.
|
//check if the given char is a english punctuation.
|
||||||
FRISO_API int gbk_en_punctuation( char c )
|
FRISO_API int gbk_en_punctuation(char c) {
|
||||||
{
|
|
||||||
int u = (uchar_t) c;
|
int u = (uchar_t) c;
|
||||||
return ( (u > 32 && u < 48)
|
return ((u > 32 && u < 48)
|
||||||
|| ( u > 57 && u < 65 )
|
|| (u > 57 && u < 65)
|
||||||
|| ( u > 90 && u < 97 )
|
|| (u > 90 && u < 97)
|
||||||
|| ( u > 122 && u < 127 ) );
|
|| (u > 122 && u < 127));
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the given char is a chinese punctuation.
|
//check the given char is a chinese punctuation.
|
||||||
FRISO_API int gbk_cn_punctuation( char *str )
|
FRISO_API int gbk_cn_punctuation(char *str) {
|
||||||
{
|
|
||||||
int c1 = (uchar_t) str[0];
|
int c1 = (uchar_t) str[0];
|
||||||
int c2 = (uchar_t) str[1];
|
int c2 = (uchar_t) str[1];
|
||||||
//full-width en punctuation.
|
//full-width en punctuation.
|
||||||
return ( (c1 == 0xa3 && (( c2 >= 0xa1 && c2 <= 0xaf )
|
return ((c1 == 0xa3 && ((c2 >= 0xa1 && c2 <= 0xaf)
|
||||||
|| ( c2 >= 0xba && c2 <= 0xc0 )
|
|| (c2 >= 0xba && c2 <= 0xc0)
|
||||||
|| ( c2 >= 0xdb && c2 <= 0xe0 )
|
|| (c2 >= 0xdb && c2 <= 0xe0)
|
||||||
|| ( c2 >= 0xfb && c2 <= 0xfe ) ))
|
|| (c2 >= 0xfb && c2 <= 0xfe)))
|
||||||
//chinese punctuation.
|
//chinese punctuation.
|
||||||
|| (c1 == 0xa1 && ( (c2 >= 0xa1 && c2 <= 0xae)
|
|| (c1 == 0xa1 && ((c2 >= 0xa1 && c2 <= 0xae)
|
||||||
|| ( c2 >= 0xb0 && c2 <= 0xbf ) ))
|
|| (c2 >= 0xb0 && c2 <= 0xbf)))
|
||||||
//A6 area special punctuations:" "
|
//A6 area special punctuations:" "
|
||||||
|| (c1 == 0xa6 && (c2 >= 0xf9 && c2 <= 0xfe))
|
|| (c1 == 0xa6 && (c2 >= 0xf9 && c2 <= 0xfe))
|
||||||
//A8 area special punctuations: " ˊˋ˙–―‥‵℅ "
|
//A8 area special punctuations: " ˊˋ˙–―‥‵℅ "
|
||||||
|| (c1 == 0xa8 && (c2 >= 0x40 && c2 <= 0x47)) );
|
|| (c1 == 0xa8 && (c2 >= 0x40 && c2 <= 0x47)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* {{{
|
/* {{{
|
||||||
|
@ -292,7 +277,7 @@ FRISO_API int gbk_cn_punctuation( char *str )
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
//check if the given english char is a full-width char or not.
|
//check if the given english char is a full-width char or not.
|
||||||
//FRISO_API int gbk_fullwidth_char( char *str )
|
//FRISO_API int gbk_fullwidth_char( char *str )
|
||||||
//{
|
//{
|
||||||
// return 1;
|
// return 1;
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -15,15 +15,14 @@
|
||||||
*
|
*
|
||||||
* @return int the bytes of the current readed word.
|
* @return int the bytes of the current readed word.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_next_word(
|
FRISO_API int utf8_next_word(
|
||||||
friso_task_t task,
|
friso_task_t task,
|
||||||
uint_t *idx,
|
uint_t *idx,
|
||||||
fstring __word )
|
fstring __word) {
|
||||||
{
|
if(*idx >= task->length) return 0;
|
||||||
if ( *idx >= task->length ) return 0;
|
|
||||||
|
|
||||||
//register uint_t t;
|
//register uint_t t;
|
||||||
task->bytes = get_utf8_bytes( task->text[ *idx ] );
|
task->bytes = get_utf8_bytes(task->text[ *idx ]);
|
||||||
|
|
||||||
//for ( t = 0; t < task->bytes; t++ ) {
|
//for ( t = 0; t < task->bytes; t++ ) {
|
||||||
// __word[t] = task->text[ (*idx)++ ];
|
// __word[t] = task->text[ (*idx)++ ];
|
||||||
|
@ -37,7 +36,7 @@ FRISO_API int utf8_next_word(
|
||||||
__word[task->bytes] = '\0';
|
__word[task->bytes] = '\0';
|
||||||
|
|
||||||
//the unicode counter was moved here from version 1.6.0
|
//the unicode counter was moved here from version 1.6.0
|
||||||
task->unicode = get_utf8_unicode( __word );
|
task->unicode = get_utf8_unicode(__word);
|
||||||
|
|
||||||
return task->bytes;
|
return task->bytes;
|
||||||
}
|
}
|
||||||
|
@ -47,12 +46,11 @@ FRISO_API int utf8_next_word(
|
||||||
*
|
*
|
||||||
* @param int
|
* @param int
|
||||||
*/
|
*/
|
||||||
FRISO_API void print_char_binary( char value )
|
FRISO_API void print_char_binary(char value) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
|
|
||||||
for ( t = 0; t < __CHAR_BYTES__; t++ ) {
|
for(t = 0; t < __CHAR_BYTES__; t++) {
|
||||||
if ( ( value & 0x80 ) == 0x80 ) {
|
if((value & 0x80) == 0x80) {
|
||||||
printf("1");
|
printf("1");
|
||||||
} else {
|
} else {
|
||||||
printf("0");
|
printf("0");
|
||||||
|
@ -66,15 +64,14 @@ FRISO_API void print_char_binary( char value )
|
||||||
* between 1 - 6.
|
* between 1 - 6.
|
||||||
*
|
*
|
||||||
* @param __char
|
* @param __char
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int get_utf8_bytes( char value )
|
FRISO_API int get_utf8_bytes(char value) {
|
||||||
{
|
|
||||||
register uint_t t = 0;
|
register uint_t t = 0;
|
||||||
|
|
||||||
//one byte ascii char.
|
//one byte ascii char.
|
||||||
if ( ( value & 0x80 ) == 0 ) return 1;
|
if((value & 0x80) == 0) return 1;
|
||||||
for ( ; ( value & 0x80 ) != 0; value <<= 1 ) {
|
for(; (value & 0x80) != 0; value <<= 1) {
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,17 +80,16 @@ FRISO_API int get_utf8_bytes( char value )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the unicode serial of a utf-8 char.
|
* get the unicode serial of a utf-8 char.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int.
|
* @return int.
|
||||||
*/
|
*/
|
||||||
FRISO_API int get_utf8_unicode( const fstring ch )
|
FRISO_API int get_utf8_unicode(const fstring ch) {
|
||||||
{
|
int code = 0, bytes = get_utf8_bytes(*ch);
|
||||||
int code = 0, bytes = get_utf8_bytes( *ch );
|
register uchar_t *bit = (uchar_t *) &code;
|
||||||
register uchar_t *bit = ( uchar_t * ) &code;
|
register char b1, b2, b3;
|
||||||
register char b1,b2,b3;
|
|
||||||
|
|
||||||
switch ( bytes ) {
|
switch(bytes) {
|
||||||
case 1:
|
case 1:
|
||||||
*bit = *ch;
|
*bit = *ch;
|
||||||
break;
|
break;
|
||||||
|
@ -102,7 +98,7 @@ FRISO_API int get_utf8_unicode( const fstring ch )
|
||||||
b2 = *(ch + 1);
|
b2 = *(ch + 1);
|
||||||
|
|
||||||
*bit = (b1 << 6) + (b2 & 0x3F);
|
*bit = (b1 << 6) + (b2 & 0x3F);
|
||||||
*(bit+1) = (b1 >> 2) & 0x07;
|
*(bit + 1) = (b1 >> 2) & 0x07;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
b1 = *ch;
|
b1 = *ch;
|
||||||
|
@ -110,7 +106,7 @@ FRISO_API int get_utf8_unicode( const fstring ch )
|
||||||
b3 = *(ch + 2);
|
b3 = *(ch + 2);
|
||||||
|
|
||||||
*bit = (b2 << 6) + (b3 & 0x3F);
|
*bit = (b2 << 6) + (b3 & 0x3F);
|
||||||
*(bit+1) = (b1 << 4) + ((b2 >> 2) & 0x0F);
|
*(bit + 1) = (b1 << 4) + ((b2 >> 2) & 0x0F);
|
||||||
break;
|
break;
|
||||||
//ignore the ones that are larger than 3 bytes;
|
//ignore the ones that are larger than 3 bytes;
|
||||||
}
|
}
|
||||||
|
@ -119,51 +115,50 @@ FRISO_API int get_utf8_unicode( const fstring ch )
|
||||||
}
|
}
|
||||||
|
|
||||||
//turn the unicode serial to a utf-8 string.
|
//turn the unicode serial to a utf-8 string.
|
||||||
FRISO_API int unicode_to_utf8( uint_t u, fstring __word )
|
FRISO_API int unicode_to_utf8(uint_t u, fstring __word) {
|
||||||
{
|
if(u <= 0x0000007F) {
|
||||||
if ( u <= 0x0000007F ) {
|
|
||||||
//U-00000000 - U-0000007F
|
//U-00000000 - U-0000007F
|
||||||
//0xxxxxxx
|
//0xxxxxxx
|
||||||
*__word = ( u & 0x7F );
|
*__word = (u & 0x7F);
|
||||||
return 1;
|
return 1;
|
||||||
} else if ( u >= 0x00000080 && u <= 0x000007FF ) {
|
} else if(u >= 0x00000080 && u <= 0x000007FF) {
|
||||||
//U-00000080 - U-000007FF
|
//U-00000080 - U-000007FF
|
||||||
//110xxxxx 10xxxxxx
|
//110xxxxx 10xxxxxx
|
||||||
*( __word + 1 ) = ( u & 0x3F) | 0x80;
|
*(__word + 1) = (u & 0x3F) | 0x80;
|
||||||
*__word = ((u >> 6) & 0x1F) | 0xC0;
|
*__word = ((u >> 6) & 0x1F) | 0xC0;
|
||||||
return 2;
|
return 2;
|
||||||
} else if ( u >= 0x00000800 && u <= 0x0000FFFF ) {
|
} else if(u >= 0x00000800 && u <= 0x0000FFFF) {
|
||||||
//U-00000800 - U-0000FFFF
|
//U-00000800 - U-0000FFFF
|
||||||
//1110xxxx 10xxxxxx 10xxxxxx
|
//1110xxxx 10xxxxxx 10xxxxxx
|
||||||
*( __word + 2 ) = ( u & 0x3F) | 0x80;
|
*(__word + 2) = (u & 0x3F) | 0x80;
|
||||||
*( __word + 1 ) = ((u >> 6) & 0x3F) | 0x80;
|
*(__word + 1) = ((u >> 6) & 0x3F) | 0x80;
|
||||||
*__word = ((u >> 12) & 0x0F) | 0xE0;
|
*__word = ((u >> 12) & 0x0F) | 0xE0;
|
||||||
return 3;
|
return 3;
|
||||||
} else if ( u >= 0x00010000 && u <= 0x001FFFFF ) {
|
} else if(u >= 0x00010000 && u <= 0x001FFFFF) {
|
||||||
//U-00010000 - U-001FFFFF
|
//U-00010000 - U-001FFFFF
|
||||||
//11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
//11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
*( __word + 3 ) = ( u & 0x3F) | 0x80;
|
*(__word + 3) = (u & 0x3F) | 0x80;
|
||||||
*( __word + 2 ) = ((u >> 6) & 0x3F) | 0x80;
|
*(__word + 2) = ((u >> 6) & 0x3F) | 0x80;
|
||||||
*( __word + 1 ) = ((u >> 12) & 0x3F) | 0x80;
|
*(__word + 1) = ((u >> 12) & 0x3F) | 0x80;
|
||||||
*__word = ((u >> 18) & 0x07) | 0xF0;
|
*__word = ((u >> 18) & 0x07) | 0xF0;
|
||||||
return 4;
|
return 4;
|
||||||
} else if ( u >= 0x00200000 && u <= 0x03FFFFFF ) {
|
} else if(u >= 0x00200000 && u <= 0x03FFFFFF) {
|
||||||
//U-00200000 - U-03FFFFFF
|
//U-00200000 - U-03FFFFFF
|
||||||
//111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
//111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
*( __word + 4 ) = ( u & 0x3F) | 0x80;
|
*(__word + 4) = (u & 0x3F) | 0x80;
|
||||||
*( __word + 3 ) = ((u >> 6) & 0x3F) | 0x80;
|
*(__word + 3) = ((u >> 6) & 0x3F) | 0x80;
|
||||||
*( __word + 2 ) = ((u >> 12) & 0x3F) | 0x80;
|
*(__word + 2) = ((u >> 12) & 0x3F) | 0x80;
|
||||||
*( __word + 1 ) = ((u >> 18) & 0x3F) | 0x80;
|
*(__word + 1) = ((u >> 18) & 0x3F) | 0x80;
|
||||||
*__word = ((u >> 24) & 0x03) | 0xF8;
|
*__word = ((u >> 24) & 0x03) | 0xF8;
|
||||||
return 5;
|
return 5;
|
||||||
} else if ( u >= 0x04000000 && u <= 0x7FFFFFFF ) {
|
} else if(u >= 0x04000000 && u <= 0x7FFFFFFF) {
|
||||||
//U-04000000 - U-7FFFFFFF
|
//U-04000000 - U-7FFFFFFF
|
||||||
//1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
//1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
*( __word + 5 ) = ( u & 0x3F) | 0x80;
|
*(__word + 5) = (u & 0x3F) | 0x80;
|
||||||
*( __word + 4 ) = ((u >> 6) & 0x3F) | 0x80;
|
*(__word + 4) = ((u >> 6) & 0x3F) | 0x80;
|
||||||
*( __word + 3 ) = ((u >> 12) & 0x3F) | 0x80;
|
*(__word + 3) = ((u >> 12) & 0x3F) | 0x80;
|
||||||
*( __word + 2 ) = ((u >> 18) & 0x3F) | 0x80;
|
*(__word + 2) = ((u >> 18) & 0x3F) | 0x80;
|
||||||
*( __word + 1 ) = ((u >> 24) & 0x3F) | 0x80;
|
*(__word + 1) = ((u >> 24) & 0x3F) | 0x80;
|
||||||
*__word = ((u >> 30) & 0x01) | 0xFC;
|
*__word = ((u >> 30) & 0x01) | 0xFC;
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
@ -173,17 +168,17 @@ FRISO_API int unicode_to_utf8( uint_t u, fstring __word )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given char is a CJK char or not.
|
* check the given char is a CJK char or not.
|
||||||
* 2E80-2EFF CJK 部首补充
|
* 2E80-2EFF CJK 部首补充
|
||||||
* 2F00-2FDF 康熙字典部首
|
* 2F00-2FDF 康熙字典部首
|
||||||
* 3000-303F CJK 符号和标点 --ignore
|
* 3000-303F CJK 符号和标点 --ignore
|
||||||
* 31C0-31EF CJK 笔画
|
* 31C0-31EF CJK 笔画
|
||||||
* 3200-32FF 封闭式 CJK 文字和月份 --ignore.
|
* 3200-32FF 封闭式 CJK 文字和月份 --ignore.
|
||||||
* 3300-33FF CJK 兼容
|
* 3300-33FF CJK 兼容
|
||||||
* 3400-4DBF CJK 统一表意符号扩展 A
|
* 3400-4DBF CJK 统一表意符号扩展 A
|
||||||
* 4DC0-4DFF 易经六十四卦符号
|
* 4DC0-4DFF 易经六十四卦符号
|
||||||
* 4E00-9FBF CJK 统一表意符号
|
* 4E00-9FBF CJK 统一表意符号
|
||||||
* F900-FAFF CJK 兼容象形文字
|
* F900-FAFF CJK 兼容象形文字
|
||||||
* FE30-FE4F CJK 兼容形式
|
* FE30-FE4F CJK 兼容形式
|
||||||
* FF00-FFEF 全角ASCII、全角标点 --ignore (as basic latin)
|
* FF00-FFEF 全角ASCII、全角标点 --ignore (as basic latin)
|
||||||
*
|
*
|
||||||
* Japanese:
|
* Japanese:
|
||||||
|
@ -195,9 +190,9 @@ FRISO_API int unicode_to_utf8( uint_t u, fstring __word )
|
||||||
* AC00-D7AF 韩文拼音
|
* AC00-D7AF 韩文拼音
|
||||||
* 1100-11FF 韩文字母
|
* 1100-11FF 韩文字母
|
||||||
* 3130-318F 韩文兼容字母
|
* 3130-318F 韩文兼容字母
|
||||||
*
|
*
|
||||||
* @param ch :pointer to the char
|
* @param ch :pointer to the char
|
||||||
* @return int : 1 for yes and 0 for not.
|
* @return int : 1 for yes and 0 for not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Comment one of the following macro define
|
//Comment one of the following macro define
|
||||||
|
@ -205,44 +200,42 @@ FRISO_API int unicode_to_utf8( uint_t u, fstring __word )
|
||||||
#define FRISO_CJK_CHK_C
|
#define FRISO_CJK_CHK_C
|
||||||
//#define FRISO_CJK_CHK_J
|
//#define FRISO_CJK_CHK_J
|
||||||
//#define FRISO_CJK_CHK_K
|
//#define FRISO_CJK_CHK_K
|
||||||
FRISO_API int utf8_cjk_string( uint_t u )
|
FRISO_API int utf8_cjk_string(uint_t u) {
|
||||||
{
|
|
||||||
int c = 0, j = 0, k = 0;
|
int c = 0, j = 0, k = 0;
|
||||||
//Chinese.
|
//Chinese.
|
||||||
#ifdef FRISO_CJK_CHK_C
|
#ifdef FRISO_CJK_CHK_C
|
||||||
c = ( ( u >= 0x4E00 && u <= 0x9FBF )
|
c = ((u >= 0x4E00 && u <= 0x9FBF)
|
||||||
|| ( u >= 0x2E80 && u <= 0x2EFF ) || ( u >= 0x2F00 && u <= 0x2FDF )
|
|| (u >= 0x2E80 && u <= 0x2EFF) || (u >= 0x2F00 && u <= 0x2FDF)
|
||||||
|| ( u >= 0x31C0 && u <= 0x31EF ) //|| ( u >= 0x3200 && u <= 0x32FF )
|
|| (u >= 0x31C0 && u <= 0x31EF) //|| ( u >= 0x3200 && u <= 0x32FF )
|
||||||
|| ( u >= 0x3300 && u <= 0x33FF ) //|| ( u >= 0x3400 && u <= 0x4DBF )
|
|| (u >= 0x3300 && u <= 0x33FF) //|| ( u >= 0x3400 && u <= 0x4DBF )
|
||||||
|| ( u >= 0x4DC0 && u <= 0x4DFF ) || ( u >= 0xF900 && u <= 0xFAFF )
|
|| (u >= 0x4DC0 && u <= 0x4DFF) || (u >= 0xF900 && u <= 0xFAFF)
|
||||||
|| ( u >= 0xFE30 && u <= 0xFE4F ) );
|
|| (u >= 0xFE30 && u <= 0xFE4F));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Japanese.
|
//Japanese.
|
||||||
#ifdef FRISO_CJK_CHK_J
|
#ifdef FRISO_CJK_CHK_J
|
||||||
j = ( ( u >= 0x3040 && u <= 0x309F )
|
j = ((u >= 0x3040 && u <= 0x309F)
|
||||||
|| ( u >= 0x30A0 && u <= 0x30FF ) || ( u >= 0x31F0 && u <= 0x31FF ) );
|
|| (u >= 0x30A0 && u <= 0x30FF) || (u >= 0x31F0 && u <= 0x31FF));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Korean
|
//Korean
|
||||||
#ifdef FRISO_CJK_CHK_K
|
#ifdef FRISO_CJK_CHK_K
|
||||||
k = ( ( u >= 0xAC00 && u <= 0xD7AF )
|
k = ((u >= 0xAC00 && u <= 0xD7AF)
|
||||||
|| ( u >= 0x1100 && u <= 0x11FF ) || ( u >= 0x3130 && u <= 0x318F ) );
|
|| (u >= 0x1100 && u <= 0x11FF) || (u >= 0x3130 && u <= 0x318F));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ( c || j || k );
|
return (c || j || k);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given char is a Basic Latin letter or not.
|
* check the given char is a Basic Latin letter or not.
|
||||||
* include all the letters and english punctuations.
|
* include all the letters and english punctuations.
|
||||||
*
|
*
|
||||||
* @param c
|
* @param c
|
||||||
* @return int 1 for yes and 0 for not.
|
* @return int 1 for yes and 0 for not.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_halfwidth_en_char( uint_t u )
|
FRISO_API int utf8_halfwidth_en_char(uint_t u) {
|
||||||
{
|
return (u >= 32 && u <= 126);
|
||||||
return ( u >= 32 && u <= 126 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -253,44 +246,39 @@ FRISO_API int utf8_halfwidth_en_char( uint_t u )
|
||||||
* @param c
|
* @param c
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_fullwidth_en_char( uint_t u )
|
FRISO_API int utf8_fullwidth_en_char(uint_t u) {
|
||||||
{
|
return ((u >= 65296 && u <= 65305) //arabic number
|
||||||
return ( (u >= 65296 && u <= 65305 ) //arabic number
|
|| (u >= 65313 && u <= 65338) //upper case letters
|
||||||
|| ( u >= 65313 && u <= 65338 ) //upper case letters
|
|| (u >= 65345 && u <= 65370)); //lower case letters
|
||||||
|| ( u >= 65345 && u <= 65370 ) ); //lower case letters
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the given char is a upper case letters or not.
|
//check the given char is a upper case letters or not.
|
||||||
// included the full-width and half-width letters.
|
// included the full-width and half-width letters.
|
||||||
FRISO_API int utf8_uppercase_letter( uint_t u )
|
FRISO_API int utf8_uppercase_letter(uint_t u) {
|
||||||
{
|
if(u > 65280) u -= 65248;
|
||||||
if ( u > 65280 ) u -= 65248;
|
return (u >= 65 && u <= 90);
|
||||||
return ( u >= 65 && u <= 90 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the given char is a upper case letters or not.
|
//check the given char is a upper case letters or not.
|
||||||
// included the full-width and half-width letters.
|
// included the full-width and half-width letters.
|
||||||
FRISO_API int utf8_lowercase_letter( uint_t u )
|
FRISO_API int utf8_lowercase_letter(uint_t u) {
|
||||||
{
|
if(u > 65280) u -= 65248;
|
||||||
if ( u > 65280 ) u -= 65248;
|
return (u >= 97 && u <= 122);
|
||||||
return ( u >= 97 && u <= 122 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the given char is a numeric
|
//check the given char is a numeric
|
||||||
// included the full-width and half-width arabic numeric.
|
// included the full-width and half-width arabic numeric.
|
||||||
FRISO_API int utf8_numeric_letter( uint_t u )
|
FRISO_API int utf8_numeric_letter(uint_t u) {
|
||||||
{
|
if(u > 65280) u -= 65248; //make full-width half-width.
|
||||||
if ( u > 65280 ) u -= 65248; //make full-width half-width.
|
return ((u >= 48 && u <= 57));
|
||||||
return ( ( u >= 48 && u <= 57 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the given char is a english letter.(included the full-width)
|
//check the given char is a english letter.(included the full-width)
|
||||||
// not the punctuation of course.
|
// not the punctuation of course.
|
||||||
FRISO_API int utf8_en_letter( uint_t u )
|
FRISO_API int utf8_en_letter(uint_t u) {
|
||||||
{
|
if(u > 65280) u -= 65248;
|
||||||
if ( u > 65280 ) u -= 65248;
|
return ((u >= 65 && u <= 90)
|
||||||
return ( ( u >= 65 && u <= 90 )
|
|| (u >= 97 && u <= 122));
|
||||||
|| ( u >= 97 && u <= 122 ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -310,24 +298,23 @@ FRISO_API int utf8_en_letter( uint_t u )
|
||||||
* 65304, 8
|
* 65304, 8
|
||||||
* 65305, 9
|
* 65305, 9
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_numeric_string( const fstring str )
|
FRISO_API int utf8_numeric_string(const fstring str) {
|
||||||
{
|
|
||||||
fstring s = str;
|
fstring s = str;
|
||||||
int bytes, u;
|
int bytes, u;
|
||||||
|
|
||||||
while ( *s != '\0' ) {
|
while(*s != '\0') {
|
||||||
//if ( ! utf8_numeric_letter( get_utf8_unicode( s++ ) ) ) {
|
//if ( ! utf8_numeric_letter( get_utf8_unicode( s++ ) ) ) {
|
||||||
// return 0;
|
// return 0;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//new implemention.
|
//new implemention.
|
||||||
//@date 2013-10-14
|
//@date 2013-10-14
|
||||||
bytes = 1;
|
bytes = 1;
|
||||||
if ( *s < 0 ) { //full-width chars.
|
if(*s < 0) { //full-width chars.
|
||||||
u = get_utf8_unicode(s);
|
u = get_utf8_unicode(s);
|
||||||
bytes = get_utf8_bytes(*s);
|
bytes = get_utf8_bytes(*s);
|
||||||
if ( u < 65296 || u > 65305 ) return 0;
|
if(u < 65296 || u > 65305) return 0;
|
||||||
} else if ( *s < 48 || *s > 57 ) {
|
} else if(*s < 48 || *s > 57) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,25 +324,24 @@ FRISO_API int utf8_numeric_string( const fstring str )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API int utf8_decimal_string( const fstring str )
|
FRISO_API int utf8_decimal_string(const fstring str) {
|
||||||
{
|
|
||||||
int len = strlen(str), i, p = 0;
|
int len = strlen(str), i, p = 0;
|
||||||
int bytes = 0, u;
|
int bytes = 0, u;
|
||||||
|
|
||||||
if ( str[0] == '.' || str[len-1] == '.' ) return 0;
|
if(str[0] == '.' || str[len - 1] == '.') return 0;
|
||||||
|
|
||||||
for ( i = 1; i < len; bytes = 1 ) {
|
for(i = 1; i < len; bytes = 1) {
|
||||||
//count the number of char '.'
|
//count the number of char '.'
|
||||||
if ( str[i] == '.' ) {
|
if(str[i] == '.') {
|
||||||
i++;
|
i++;
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
} else if ( str[i] < 0 ) {
|
} else if(str[i] < 0) {
|
||||||
//full-width numeric.
|
//full-width numeric.
|
||||||
u = get_utf8_unicode(str+i);
|
u = get_utf8_unicode(str + i);
|
||||||
bytes = get_utf8_bytes(str[i]);
|
bytes = get_utf8_bytes(str[i]);
|
||||||
if ( u < 65296 || u > 65305 ) return 0;
|
if(u < 65296 || u > 65305) return 0;
|
||||||
} else if ( str[i] < 48 || str[i] > 57 ) {
|
} else if(str[i] < 48 || str[i] > 57) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,13 +353,12 @@ FRISO_API int utf8_decimal_string( const fstring str )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given char is a whitespace or not.
|
* check the given char is a whitespace or not.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int 1 for yes and 0 for not.
|
* @return int 1 for yes and 0 for not.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_whitespace( uint_t u )
|
FRISO_API int utf8_whitespace(uint_t u) {
|
||||||
{
|
if(u == 32 || u == 12288) {
|
||||||
if ( u == 32 || u == 12288 ) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -382,17 +367,16 @@ FRISO_API int utf8_whitespace( uint_t u )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given char is a english punctuation.
|
* check the given char is a english punctuation.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_en_punctuation( uint_t u )
|
FRISO_API int utf8_en_punctuation(uint_t u) {
|
||||||
{
|
|
||||||
//if ( u > 65280 ) u = u - 65248; //make full-width half-width
|
//if ( u > 65280 ) u = u - 65248; //make full-width half-width
|
||||||
return ( (u > 32 && u < 48)
|
return ((u > 32 && u < 48)
|
||||||
|| ( u > 57 && u < 65 )
|
|| (u > 57 && u < 65)
|
||||||
|| ( u > 90 && u < 97 ) //added @2013-08-31
|
|| (u > 90 && u < 97) //added @2013-08-31
|
||||||
|| ( u > 122 && u < 127 ) );
|
|| (u > 122 && u < 127));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -400,17 +384,16 @@ FRISO_API int utf8_en_punctuation( uint_t u )
|
||||||
* @date 2013-08-31 added.
|
* @date 2013-08-31 added.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_cn_punctuation( uint_t u )
|
FRISO_API int utf8_cn_punctuation(uint_t u) {
|
||||||
{
|
return ((u > 65280 && u < 65296)
|
||||||
return ( ( u > 65280 && u < 65296 )
|
|| (u > 65305 && u < 65312)
|
||||||
|| ( u > 65305 && u < 65312 )
|
|| (u > 65338 && u < 65345)
|
||||||
|| ( u > 65338 && u < 65345 )
|
|| (u > 65370 && u < 65382)
|
||||||
|| ( u > 65370 && u < 65382 )
|
//cjk symbol and punctuation.(added 2013-09-06)
|
||||||
//cjk symbol and punctuation.(added 2013-09-06)
|
//from http://www.unicode.org/charts/PDF/U3000.pdf
|
||||||
//from http://www.unicode.org/charts/PDF/U3000.pdf
|
|| (u >= 12289 && u <= 12319));
|
||||||
|| ( u >= 12289 && u <= 12319) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -419,8 +402,7 @@ FRISO_API int utf8_cn_punctuation( uint_t u )
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_letter_number( uint_t u )
|
FRISO_API int utf8_letter_number(uint_t u) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,13 +412,12 @@ FRISO_API int utf8_letter_number( uint_t u )
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_other_number( uint_t u )
|
FRISO_API int utf8_other_number(uint_t u) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//A macro define has replace this.
|
//A macro define has replace this.
|
||||||
//FRISO_API int is_en_punctuation( char c )
|
//FRISO_API int is_en_punctuation( char c )
|
||||||
//{
|
//{
|
||||||
// return utf8_en_punctuation( (uint_t) c );
|
// return utf8_en_punctuation( (uint_t) c );
|
||||||
//}
|
//}
|
||||||
|
@ -448,9 +429,9 @@ FRISO_API int utf8_other_number( uint_t u )
|
||||||
|
|
||||||
/* @Deprecated
|
/* @Deprecated
|
||||||
* check the given char is an english keep punctuation.*/
|
* check the given char is an english keep punctuation.*/
|
||||||
//FRISO_API int utf8_keep_punctuation( fstring str )
|
//FRISO_API int utf8_keep_punctuation( fstring str )
|
||||||
//{
|
//{
|
||||||
// if ( __keep_punctuations_hash__ == NULL )
|
// if ( __keep_punctuations_hash__ == NULL )
|
||||||
// {
|
// {
|
||||||
// __keep_punctuations_hash__ = new_hash_table();
|
// __keep_punctuations_hash__ = new_hash_table();
|
||||||
// hash_put_mapping( __keep_punctuations_hash__, "@", NULL );
|
// hash_put_mapping( __keep_punctuations_hash__, "@", NULL );
|
||||||
|
@ -473,11 +454,11 @@ FRISO_API int utf8_other_number( uint_t u )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given english char is a full-width char or not.
|
* check the given english char is a full-width char or not.
|
||||||
*
|
*
|
||||||
* @param ch
|
* @param ch
|
||||||
* @return 1 for yes and 0 for not.
|
* @return 1 for yes and 0 for not.
|
||||||
*/
|
*/
|
||||||
//FRISO_API int utf8_fullwidth_char( uint_t u )
|
//FRISO_API int utf8_fullwidth_char( uint_t u )
|
||||||
//{
|
//{
|
||||||
// if ( u == 12288 )
|
// if ( u == 12288 )
|
||||||
// return 1; //full-width space
|
// return 1; //full-width space
|
||||||
|
|
|
@ -10,16 +10,15 @@
|
||||||
/* ********************************************
|
/* ********************************************
|
||||||
* friso array list static functions block *
|
* friso array list static functions block *
|
||||||
**********************************************/
|
**********************************************/
|
||||||
__STATIC_API__ void **create_array_entries( uint_t __blocks )
|
__STATIC_API__ void **create_array_entries(uint_t __blocks) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
void **block = ( void ** ) FRISO_CALLOC( sizeof( void * ), __blocks );
|
void **block = (void **) FRISO_CALLOC(sizeof(void *), __blocks);
|
||||||
if ( block == NULL ) {
|
if(block == NULL) {
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize
|
//initialize
|
||||||
for ( t = 0; t < __blocks; t++ ) {
|
for(t = 0; t < __blocks; t++) {
|
||||||
block[t] = NULL;
|
block[t] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,18 +26,17 @@ __STATIC_API__ void **create_array_entries( uint_t __blocks )
|
||||||
}
|
}
|
||||||
|
|
||||||
//resize the array. (the opacity should not be smaller than array->length)
|
//resize the array. (the opacity should not be smaller than array->length)
|
||||||
__STATIC_API__ friso_array_t resize_array_list(
|
__STATIC_API__ friso_array_t resize_array_list(
|
||||||
friso_array_t array,
|
friso_array_t array,
|
||||||
uint_t opacity )
|
uint_t opacity) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
void **block = create_array_entries( opacity );
|
void **block = create_array_entries(opacity);
|
||||||
|
|
||||||
for ( t = 0; t < array->length ; t++ ) {
|
for(t = 0; t < array->length ; t++) {
|
||||||
block[t] = array->items[t];
|
block[t] = array->items[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_FREE( array->items );
|
FRISO_FREE(array->items);
|
||||||
array->items = block;
|
array->items = block;
|
||||||
array->allocs = opacity;
|
array->allocs = opacity;
|
||||||
|
|
||||||
|
@ -55,16 +53,15 @@ __STATIC_API__ friso_array_t resize_array_list(
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//create a new array list with a given opacity.
|
//create a new array list with a given opacity.
|
||||||
FRISO_API friso_array_t new_array_list_with_opacity( uint_t opacity )
|
FRISO_API friso_array_t new_array_list_with_opacity(uint_t opacity) {
|
||||||
{
|
friso_array_t array = (friso_array_t)
|
||||||
friso_array_t array = ( friso_array_t )
|
FRISO_MALLOC(sizeof(friso_array_entry));
|
||||||
FRISO_MALLOC( sizeof( friso_array_entry ) );
|
if(array == NULL) {
|
||||||
if ( array == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize
|
//initialize
|
||||||
array->items = create_array_entries( opacity );
|
array->items = create_array_entries(opacity);
|
||||||
array->allocs = opacity;
|
array->allocs = opacity;
|
||||||
array->length = 0;
|
array->length = 0;
|
||||||
|
|
||||||
|
@ -73,10 +70,9 @@ FRISO_API friso_array_t new_array_list_with_opacity( uint_t opacity )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free the given friso array.
|
* free the given friso array.
|
||||||
* and its items, but never where its items item pointed to .
|
* and its items, but never where its items item pointed to .
|
||||||
*/
|
*/
|
||||||
FRISO_API void free_array_list( friso_array_t array )
|
FRISO_API void free_array_list(friso_array_t array) {
|
||||||
{
|
|
||||||
//free the allocation that all the items pointed to
|
//free the allocation that all the items pointed to
|
||||||
//register int t;
|
//register int t;
|
||||||
//if ( flag == 1 ) {
|
//if ( flag == 1 ) {
|
||||||
|
@ -87,40 +83,38 @@ FRISO_API void free_array_list( friso_array_t array )
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
FRISO_FREE( array->items );
|
FRISO_FREE(array->items);
|
||||||
FRISO_FREE( array );
|
FRISO_FREE(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add a new item to the array.
|
//add a new item to the array.
|
||||||
FRISO_API void array_list_add( friso_array_t array, void *value )
|
FRISO_API void array_list_add(friso_array_t array, void *value) {
|
||||||
{
|
|
||||||
//check the condition to resize.
|
//check the condition to resize.
|
||||||
if ( array->length == array->allocs ) {
|
if(array->length == array->allocs) {
|
||||||
resize_array_list( array, array->length * 2 + 1 );
|
resize_array_list(array, array->length * 2 + 1);
|
||||||
}
|
}
|
||||||
array->items[array->length++] = value;
|
array->items[array->length++] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//insert a new item at a specified position.
|
//insert a new item at a specified position.
|
||||||
FRISO_API void array_list_insert(
|
FRISO_API void array_list_insert(
|
||||||
friso_array_t array,
|
friso_array_t array,
|
||||||
uint_t idx,
|
uint_t idx,
|
||||||
void *value )
|
void *value) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
|
|
||||||
if ( idx <= array->length ) {
|
if(idx <= array->length) {
|
||||||
//check the condition to resize the array.
|
//check the condition to resize the array.
|
||||||
if ( array->length == array->allocs ) {
|
if(array->length == array->allocs) {
|
||||||
resize_array_list( array, array->length * 2 + 1 );
|
resize_array_list(array, array->length * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//move the elements after idx.
|
//move the elements after idx.
|
||||||
//for ( t = idx; t < array->length; t++ ) {
|
//for ( t = idx; t < array->length; t++ ) {
|
||||||
// array->items[t+1] = array->items[t];
|
// array->items[t+1] = array->items[t];
|
||||||
//}
|
//}
|
||||||
for ( t = array->length - 1; t >= idx; t-- ) {
|
for(t = array->length - 1; t >= idx; t--) {
|
||||||
array->items[t+1] = array->items[t];
|
array->items[t + 1] = array->items[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
array->items[idx] = value;
|
array->items[idx] = value;
|
||||||
|
@ -129,9 +123,8 @@ FRISO_API void array_list_insert(
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the item at a specified position.
|
//get the item at a specified position.
|
||||||
FRISO_API void *array_list_get( friso_array_t array, uint_t idx )
|
FRISO_API void *array_list_get(friso_array_t array, uint_t idx) {
|
||||||
{
|
if(idx < array->length) {
|
||||||
if ( idx < array->length ) {
|
|
||||||
return array->items[idx];
|
return array->items[idx];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -139,13 +132,12 @@ FRISO_API void *array_list_get( friso_array_t array, uint_t idx )
|
||||||
|
|
||||||
//set the value of the item at a specified position.
|
//set the value of the item at a specified position.
|
||||||
//this will return the old value.
|
//this will return the old value.
|
||||||
FRISO_API void * array_list_set(
|
FRISO_API void * array_list_set(
|
||||||
friso_array_t array,
|
friso_array_t array,
|
||||||
uint_t idx,
|
uint_t idx,
|
||||||
void * value )
|
void * value) {
|
||||||
{
|
|
||||||
void * oval = NULL;
|
void * oval = NULL;
|
||||||
if ( idx < array->length ) {
|
if(idx < array->length) {
|
||||||
oval = array->items[idx];
|
oval = array->items[idx];
|
||||||
array->items[idx] = value;
|
array->items[idx] = value;
|
||||||
}
|
}
|
||||||
|
@ -154,16 +146,15 @@ FRISO_API void * array_list_set(
|
||||||
|
|
||||||
//remove the item at a specified position.
|
//remove the item at a specified position.
|
||||||
//this will return the value of the removed item.
|
//this will return the value of the removed item.
|
||||||
FRISO_API void * array_list_remove(
|
FRISO_API void * array_list_remove(
|
||||||
friso_array_t array, uint_t idx )
|
friso_array_t array, uint_t idx) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
void *oval = NULL;
|
void *oval = NULL;
|
||||||
|
|
||||||
if ( idx < array->length ) {
|
if(idx < array->length) {
|
||||||
oval = array->items[idx];
|
oval = array->items[idx];
|
||||||
//move the elements after idx.
|
//move the elements after idx.
|
||||||
for ( t = idx; t < array->length - 1; t++ ) {
|
for(t = idx; t < array->length - 1; t++) {
|
||||||
array->items[t] = array->items[ t + 1 ];
|
array->items[t] = array->items[ t + 1 ];
|
||||||
}
|
}
|
||||||
array->items[array->length - 1] = NULL;
|
array->items[array->length - 1] = NULL;
|
||||||
|
@ -174,11 +165,10 @@ FRISO_API void * array_list_remove(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*trim the array list*/
|
/*trim the array list*/
|
||||||
FRISO_API friso_array_t array_list_trim( friso_array_t array )
|
FRISO_API friso_array_t array_list_trim(friso_array_t array) {
|
||||||
{
|
if(array->length < array->allocs) {
|
||||||
if ( array->length < array->allocs ) {
|
return resize_array_list(array, array->length);
|
||||||
return resize_array_list( array, array->length );
|
}
|
||||||
}
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,20 +178,19 @@ FRISO_API friso_array_t array_list_trim( friso_array_t array )
|
||||||
* but will not free the point array allocations,
|
* but will not free the point array allocations,
|
||||||
* and will reset the length of it.
|
* and will reset the length of it.
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_array_t array_list_clear( friso_array_t array )
|
FRISO_API friso_array_t array_list_clear(friso_array_t array) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
//free all the allocations that the array->length's pointer pointed.
|
//free all the allocations that the array->length's pointer pointed.
|
||||||
for ( t = 0; t < array->length; t++ ) {
|
for(t = 0; t < array->length; t++) {
|
||||||
/*if ( array->items[t] == NULL ) continue;
|
/*if ( array->items[t] == NULL ) continue;
|
||||||
FRISO_FREE( array->items[t] ); */
|
FRISO_FREE( array->items[t] ); */
|
||||||
array->items[t] = NULL;
|
array->items[t] = NULL;
|
||||||
}
|
}
|
||||||
//attribute reset.
|
//attribute reset.
|
||||||
array->length = 0;
|
array->length = 0;
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the size of the array list. (A macro define has replace this.)
|
//get the size of the array list. (A macro define has replace this.)
|
||||||
//FRISO_API uint_t array_list_size( friso_array_t array ) {
|
//FRISO_API uint_t array_list_size( friso_array_t array ) {
|
||||||
|
@ -214,7 +203,7 @@ FRISO_API friso_array_t array_list_clear( friso_array_t array )
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//check if the array is empty.(A macro define has replace this.)
|
//check if the array is empty.(A macro define has replace this.)
|
||||||
//FRISO_API int array_list_empty( friso_array_t array )
|
//FRISO_API int array_list_empty( friso_array_t array )
|
||||||
//{
|
//{
|
||||||
// return ( array->length == 0 );
|
// return ( array->length == 0 );
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* friso string type check functions,
|
* friso string type check functions,
|
||||||
* like english/CJK, full-wdith/half-width, punctuation or not.
|
* like english/CJK, full-wdith/half-width, punctuation or not.
|
||||||
* @see friso_UTF8.c and friso_GBK.c for detail.
|
* @see friso_UTF8.c and friso_GBK.c for detail.
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
|
@ -13,16 +13,15 @@
|
||||||
#include "friso_API.h"
|
#include "friso_API.h"
|
||||||
|
|
||||||
/* check if the specified string is a cn string.
|
/* check if the specified string is a cn string.
|
||||||
*
|
*
|
||||||
* @return int (true for cn string or false)
|
* @return int (true for cn string or false)
|
||||||
* */
|
* */
|
||||||
FRISO_API int friso_cn_string(
|
FRISO_API int friso_cn_string(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
|
||||||
return utf8_cjk_string(task->unicode);
|
return utf8_cjk_string(task->unicode);
|
||||||
} else if ( charset == FRISO_GBK ) {
|
} else if(charset == FRISO_GBK) {
|
||||||
return gbk_cn_string(task->buffer);
|
return gbk_cn_string(task->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +29,12 @@ FRISO_API int friso_cn_string(
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the specified word is a whitespace.
|
//check if the specified word is a whitespace.
|
||||||
FRISO_API int friso_whitespace(
|
FRISO_API int friso_whitespace(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
|
||||||
return utf8_whitespace(task->unicode);
|
return utf8_whitespace(task->unicode);
|
||||||
} else if ( charset == FRISO_GBK ) {
|
} else if(charset == FRISO_GBK) {
|
||||||
return gbk_whitespace(task->buffer);
|
return gbk_whitespace(task->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +44,10 @@ FRISO_API int friso_whitespace(
|
||||||
//check if the specifiled word is a numeric letter.
|
//check if the specifiled word is a numeric letter.
|
||||||
FRISO_API int friso_numeric_letter(
|
FRISO_API int friso_numeric_letter(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task)
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
|
||||||
return utf8_numeric_letter((uint_t) task->text[task->idx]);
|
return utf8_numeric_letter((uint_t) task->text[task->idx]);
|
||||||
} else if ( charset == FRISO_GBK ) {
|
} else if(charset == FRISO_GBK) {
|
||||||
return gbk_numeric_letter(task->text + task->idx);
|
return gbk_numeric_letter(task->text + task->idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +55,13 @@ FRISO_API int friso_numeric_letter(
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the specified word is aa english letter.
|
//check if the specified word is aa english letter.
|
||||||
FRISO_API int friso_en_letter(
|
FRISO_API int friso_en_letter(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_en_letter((uint_t) task->text[task->idx]);
|
||||||
return utf8_en_letter( ( uint_t ) task->text[task->idx]);
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_en_letter(task->text + task->idx);
|
||||||
return gbk_en_letter( task->text + task->idx );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -73,13 +69,12 @@ FRISO_API int friso_en_letter(
|
||||||
|
|
||||||
//check if the specified word is a half-width letter.
|
//check if the specified word is a half-width letter.
|
||||||
// punctuations are inclued.
|
// punctuations are inclued.
|
||||||
FRISO_API int friso_halfwidth_en_char(
|
FRISO_API int friso_halfwidth_en_char(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
|
||||||
return utf8_halfwidth_en_char(task->unicode);
|
return utf8_halfwidth_en_char(task->unicode);
|
||||||
} else if ( charset == FRISO_GBK ) {
|
} else if(charset == FRISO_GBK) {
|
||||||
return gbk_halfwidth_en_char(task->buffer[0]);
|
return gbk_halfwidth_en_char(task->buffer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,14 +83,13 @@ FRISO_API int friso_halfwidth_en_char(
|
||||||
|
|
||||||
//check if the specified word is a full-width letter.
|
//check if the specified word is a full-width letter.
|
||||||
// full-width punctuations are not included.
|
// full-width punctuations are not included.
|
||||||
FRISO_API int friso_fullwidth_en_char(
|
FRISO_API int friso_fullwidth_en_char(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_fullwidth_en_char(task->unicode);
|
||||||
return utf8_fullwidth_en_char( task->unicode );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_fullwidth_en_char(task->buffer);
|
||||||
return gbk_fullwidth_en_char( task->buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -104,49 +98,45 @@ FRISO_API int friso_fullwidth_en_char(
|
||||||
//check if the specified word is an english punctuations.
|
//check if the specified word is an english punctuations.
|
||||||
FRISO_API int friso_en_punctuation(
|
FRISO_API int friso_en_punctuation(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_en_punctuation(task->unicode);
|
||||||
return utf8_en_punctuation( task->unicode );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_en_punctuation(task->buffer[0]);
|
||||||
return gbk_en_punctuation( task->buffer[0] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the specified word ia sn chinese punctuation.
|
//check if the specified word ia sn chinese punctuation.
|
||||||
FRISO_API int friso_cn_punctuation(
|
FRISO_API int friso_cn_punctuation(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_cn_punctuation(task->unicode);
|
||||||
return utf8_cn_punctuation( task->unicode );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_cn_punctuation(task->buffer);
|
||||||
return gbk_cn_punctuation( task->buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API int friso_letter_number(
|
FRISO_API int friso_letter_number(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API int friso_other_number(
|
FRISO_API int friso_other_number(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if the word is a keep punctuation.
|
//check if the word is a keep punctuation.
|
||||||
//@Deprecated
|
//@Deprecated
|
||||||
//FRISO_API int friso_keep_punctuation(
|
//FRISO_API int friso_keep_punctuation(
|
||||||
// friso_charset_t charset,
|
// friso_charset_t charset,
|
||||||
// friso_task_t task )
|
// friso_task_t task )
|
||||||
//{
|
//{
|
||||||
// if ( charset == FRISO_UTF8 )
|
// if ( charset == FRISO_UTF8 )
|
||||||
|
@ -158,40 +148,37 @@ FRISO_API int friso_other_number(
|
||||||
|
|
||||||
//check if the specified char is en english punctuation.
|
//check if the specified char is en english punctuation.
|
||||||
// this function is the same as friso_en_punctuation.
|
// this function is the same as friso_en_punctuation.
|
||||||
FRISO_API int is_en_punctuation(
|
FRISO_API int is_en_punctuation(
|
||||||
friso_charset_t charset, char c )
|
friso_charset_t charset, char c) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_en_punctuation((uint_t) c);
|
||||||
return utf8_en_punctuation( (uint_t) c);
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_en_punctuation(c);
|
||||||
return gbk_en_punctuation( c );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the specified string is make up with numeric.
|
//check the specified string is make up with numeric.
|
||||||
FRISO_API int friso_numeric_string(
|
FRISO_API int friso_numeric_string(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
char *buffer )
|
char *buffer) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_numeric_string(buffer);
|
||||||
return utf8_numeric_string( buffer );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_numeric_string(buffer);
|
||||||
return gbk_numeric_string( buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the specified string is a decimal string.
|
//check the specified string is a decimal string.
|
||||||
FRISO_API int friso_decimal_string(
|
FRISO_API int friso_decimal_string(
|
||||||
friso_charset_t charset, char *buffer )
|
friso_charset_t charset, char *buffer) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_decimal_string(buffer);
|
||||||
return utf8_decimal_string( buffer );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_decimal_string(buffer);
|
||||||
return gbk_decimal_string( buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -199,14 +186,13 @@ FRISO_API int friso_decimal_string(
|
||||||
|
|
||||||
//check if the specified char is english uppercase letter.
|
//check if the specified char is english uppercase letter.
|
||||||
// included full-width and half-width letters.
|
// included full-width and half-width letters.
|
||||||
FRISO_API int friso_uppercase_letter(
|
FRISO_API int friso_uppercase_letter(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
if(charset == FRISO_UTF8) {
|
||||||
if ( charset == FRISO_UTF8 ) {
|
return utf8_uppercase_letter(task->unicode);
|
||||||
return utf8_uppercase_letter( task->unicode );
|
} else if(charset == FRISO_GBK) {
|
||||||
} else if ( charset == FRISO_GBK ) {
|
return gbk_uppercase_letter(task->buffer);
|
||||||
return gbk_uppercase_letter( task->buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -216,27 +202,26 @@ FRISO_API int friso_uppercase_letter(
|
||||||
* the type will be the constants defined above.
|
* the type will be the constants defined above.
|
||||||
* (include the fullwidth english char.)
|
* (include the fullwidth english char.)
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_enchar_t friso_enchar_type(
|
FRISO_API friso_enchar_t friso_enchar_type(
|
||||||
friso_charset_t charset,
|
friso_charset_t charset,
|
||||||
friso_task_t task )
|
friso_task_t task) {
|
||||||
{
|
|
||||||
//Unicode or ASCII.(Both UTF-8 and GBK are valid)
|
//Unicode or ASCII.(Both UTF-8 and GBK are valid)
|
||||||
uint_t u = 0;
|
uint_t u = 0;
|
||||||
|
|
||||||
if ( charset == FRISO_UTF8 ) {
|
if(charset == FRISO_UTF8) {
|
||||||
u = task->unicode;
|
u = task->unicode;
|
||||||
//if ( u >= 65280 ) u = 65280 - 65248;
|
//if ( u >= 65280 ) u = 65280 - 65248;
|
||||||
} else if ( charset == FRISO_GBK ) {
|
} else if(charset == FRISO_GBK) {
|
||||||
u = (uchar_t)task->buffer[0];
|
u = (uchar_t)task->buffer[0];
|
||||||
//if ( u == 0xa3 ) ; //full-width.
|
//if ( u == 0xa3 ) ; //full-width.
|
||||||
}
|
}
|
||||||
|
|
||||||
//range check.
|
//range check.
|
||||||
if ( u > 126 || u < 32 ) return FRISO_EN_UNKNOW;
|
if(u > 126 || u < 32) return FRISO_EN_UNKNOW;
|
||||||
if ( u == 32 ) return FRISO_EN_WHITESPACE;
|
if(u == 32) return FRISO_EN_WHITESPACE;
|
||||||
if ( u >= 48 && u <= 57 ) return FRISO_EN_NUMERIC;
|
if(u >= 48 && u <= 57) return FRISO_EN_NUMERIC;
|
||||||
if ( u >= 65 && u <= 90 ) return FRISO_EN_LETTER;
|
if(u >= 65 && u <= 90) return FRISO_EN_LETTER;
|
||||||
if ( u >= 97 && u <= 122 ) return FRISO_EN_LETTER;
|
if(u >= 97 && u <= 122) return FRISO_EN_LETTER;
|
||||||
|
|
||||||
return FRISO_EN_PUNCTUATION;
|
return FRISO_EN_PUNCTUATION;
|
||||||
}
|
}
|
||||||
|
@ -245,16 +230,15 @@ FRISO_API friso_enchar_t friso_enchar_type(
|
||||||
* the type will be the constants defined above.
|
* the type will be the constants defined above.
|
||||||
* (the char should be half-width english char only)
|
* (the char should be half-width english char only)
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_enchar_t get_enchar_type( char ch )
|
FRISO_API friso_enchar_t get_enchar_type(char ch) {
|
||||||
{
|
|
||||||
uint_t u = (uchar_t) ch;
|
uint_t u = (uchar_t) ch;
|
||||||
|
|
||||||
//range check.
|
//range check.
|
||||||
if ( u > 126 || u < 32 ) return FRISO_EN_UNKNOW;
|
if(u > 126 || u < 32) return FRISO_EN_UNKNOW;
|
||||||
if ( u == 32 ) return FRISO_EN_WHITESPACE;
|
if(u == 32) return FRISO_EN_WHITESPACE;
|
||||||
if ( u >= 48 && u <= 57 ) return FRISO_EN_NUMERIC;
|
if(u >= 48 && u <= 57) return FRISO_EN_NUMERIC;
|
||||||
if ( u >= 65 && u <= 90 ) return FRISO_EN_LETTER;
|
if(u >= 65 && u <= 90) return FRISO_EN_LETTER;
|
||||||
if ( u >= 97 && u <= 122 ) return FRISO_EN_LETTER;
|
if(u >= 97 && u <= 122) return FRISO_EN_LETTER;
|
||||||
|
|
||||||
return FRISO_EN_PUNCTUATION;
|
return FRISO_EN_PUNCTUATION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,50 +19,50 @@
|
||||||
|
|
||||||
/** {{{ wrap interface */
|
/** {{{ wrap interface */
|
||||||
/* check if the specified string is a cn string.
|
/* check if the specified string is a cn string.
|
||||||
*
|
*
|
||||||
* @return int (true for cn string or false)
|
* @return int (true for cn string or false)
|
||||||
* */
|
* */
|
||||||
FRISO_API int friso_cn_string( friso_charset_t, friso_task_t );
|
FRISO_API int friso_cn_string(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word is a whitespace.
|
//check if the specified word is a whitespace.
|
||||||
FRISO_API int friso_whitespace( friso_charset_t, friso_task_t );
|
FRISO_API int friso_whitespace(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specifiled word is a numeric letter.
|
//check if the specifiled word is a numeric letter.
|
||||||
FRISO_API int friso_numeric_letter(friso_charset_t, friso_task_t);
|
FRISO_API int friso_numeric_letter(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word is a english letter.
|
//check if the specified word is a english letter.
|
||||||
FRISO_API int friso_en_letter( friso_charset_t, friso_task_t );
|
FRISO_API int friso_en_letter(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word is a half-width letter.
|
//check if the specified word is a half-width letter.
|
||||||
// punctuations are inclued.
|
// punctuations are inclued.
|
||||||
FRISO_API int friso_halfwidth_en_char( friso_charset_t, friso_task_t );
|
FRISO_API int friso_halfwidth_en_char(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word is a full-width letter.
|
//check if the specified word is a full-width letter.
|
||||||
// full-width punctuations are not included.
|
// full-width punctuations are not included.
|
||||||
FRISO_API int friso_fullwidth_en_char( friso_charset_t, friso_task_t );
|
FRISO_API int friso_fullwidth_en_char(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word is an english punctuations.
|
//check if the specified word is an english punctuations.
|
||||||
FRISO_API int friso_en_punctuation( friso_charset_t, friso_task_t );
|
FRISO_API int friso_en_punctuation(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the specified word ia sn chinese punctuation.
|
//check if the specified word ia sn chinese punctuation.
|
||||||
FRISO_API int friso_cn_punctuation( friso_charset_t, friso_task_t );
|
FRISO_API int friso_cn_punctuation(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
FRISO_API int friso_letter_number( friso_charset_t, friso_task_t );
|
FRISO_API int friso_letter_number(friso_charset_t, friso_task_t);
|
||||||
FRISO_API int friso_other_number( friso_charset_t, friso_task_t );
|
FRISO_API int friso_other_number(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
//check if the word is a keep punctuation.
|
//check if the word is a keep punctuation.
|
||||||
//@Deprecated
|
//@Deprecated
|
||||||
//FRISO_API int friso_keep_punctuation( friso_charset_t, friso_task_t );
|
//FRISO_API int friso_keep_punctuation( friso_charset_t, friso_task_t );
|
||||||
|
|
||||||
//check the specified string is numeric string.
|
//check the specified string is numeric string.
|
||||||
FRISO_API int friso_numeric_string( friso_charset_t, char * );
|
FRISO_API int friso_numeric_string(friso_charset_t, char *);
|
||||||
|
|
||||||
//check the specified string is a decimal string.
|
//check the specified string is a decimal string.
|
||||||
FRISO_API int friso_decimal_string( friso_charset_t, char * );
|
FRISO_API int friso_decimal_string(friso_charset_t, char *);
|
||||||
|
|
||||||
//check if the specified char is english uppercase letter.
|
//check if the specified char is english uppercase letter.
|
||||||
// included full-width and half-width letters.
|
// included full-width and half-width letters.
|
||||||
FRISO_API int friso_uppercase_letter( friso_charset_t, friso_task_t );
|
FRISO_API int friso_uppercase_letter(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
|
|
||||||
//en char type.
|
//en char type.
|
||||||
|
@ -83,13 +83,13 @@ typedef enum {
|
||||||
* the type will be the constants defined above.
|
* the type will be the constants defined above.
|
||||||
* (include the fullwidth english char.)
|
* (include the fullwidth english char.)
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_enchar_t friso_enchar_type( friso_charset_t, friso_task_t );
|
FRISO_API friso_enchar_t friso_enchar_type(friso_charset_t, friso_task_t);
|
||||||
|
|
||||||
/* get the type of the specified en char.
|
/* get the type of the specified en char.
|
||||||
* the type will be the constants defined above.
|
* the type will be the constants defined above.
|
||||||
* (the char should be half-width english char only)
|
* (the char should be half-width english char only)
|
||||||
*/
|
*/
|
||||||
FRISO_API friso_enchar_t get_enchar_type( char );
|
FRISO_API friso_enchar_t get_enchar_type(char);
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -102,76 +102,76 @@ FRISO_API friso_enchar_t get_enchar_type( char );
|
||||||
*
|
*
|
||||||
* @return int the bytes of the current readed word.
|
* @return int the bytes of the current readed word.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_next_word( friso_task_t, uint_t *, fstring );
|
FRISO_API int utf8_next_word(friso_task_t, uint_t *, fstring);
|
||||||
|
|
||||||
//get the bytes of a utf-8 char.
|
//get the bytes of a utf-8 char.
|
||||||
FRISO_API int get_utf8_bytes( char );
|
FRISO_API int get_utf8_bytes(char);
|
||||||
|
|
||||||
//return the unicode serial number of a given string.
|
//return the unicode serial number of a given string.
|
||||||
FRISO_API int get_utf8_unicode( const fstring );
|
FRISO_API int get_utf8_unicode(const fstring);
|
||||||
|
|
||||||
//convert the unicode serial to a utf-8 string.
|
//convert the unicode serial to a utf-8 string.
|
||||||
FRISO_API int unicode_to_utf8( uint_t, fstring );
|
FRISO_API int unicode_to_utf8(uint_t, fstring);
|
||||||
|
|
||||||
//check if the given char is a CJK.
|
//check if the given char is a CJK.
|
||||||
FRISO_API int utf8_cjk_string( uint_t ) ;
|
FRISO_API int utf8_cjk_string(uint_t) ;
|
||||||
|
|
||||||
/*check the given char is a Basic Latin letter or not.
|
/*check the given char is a Basic Latin letter or not.
|
||||||
* include all the letters and english puntuations.*/
|
* include all the letters and english puntuations.*/
|
||||||
FRISO_API int utf8_halfwidth_en_char( uint_t );
|
FRISO_API int utf8_halfwidth_en_char(uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check the given char is a full-width latain or not.
|
* check the given char is a full-width latain or not.
|
||||||
* include the full-width arabic numeber, letters.
|
* include the full-width arabic numeber, letters.
|
||||||
* but not the full-width puntuations.
|
* but not the full-width puntuations.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_fullwidth_en_char( uint_t );
|
FRISO_API int utf8_fullwidth_en_char(uint_t);
|
||||||
|
|
||||||
//check the given char is a upper case letter or not.
|
//check the given char is a upper case letter or not.
|
||||||
// included all the full-width and half-width letters.
|
// included all the full-width and half-width letters.
|
||||||
FRISO_API int utf8_uppercase_letter( uint_t );
|
FRISO_API int utf8_uppercase_letter(uint_t);
|
||||||
|
|
||||||
//check the given char is a lower case letter or not.
|
//check the given char is a lower case letter or not.
|
||||||
// included all the full-width and half-width letters.
|
// included all the full-width and half-width letters.
|
||||||
FRISO_API int utf8_lowercase_letter( uint_t );
|
FRISO_API int utf8_lowercase_letter(uint_t);
|
||||||
|
|
||||||
//check the given char is a numeric.
|
//check the given char is a numeric.
|
||||||
// included the full-width and half-width arabic numeric.
|
// included the full-width and half-width arabic numeric.
|
||||||
FRISO_API int utf8_numeric_letter( uint_t );
|
FRISO_API int utf8_numeric_letter(uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given fstring is make up with numeric chars.
|
* check if the given fstring is make up with numeric chars.
|
||||||
* both full-width,half-width numeric is ok.
|
* both full-width,half-width numeric is ok.
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_numeric_string( char * );
|
FRISO_API int utf8_numeric_string(char *);
|
||||||
|
|
||||||
FRISO_API int utf8_decimal_string( char * );
|
FRISO_API int utf8_decimal_string(char *);
|
||||||
|
|
||||||
//check the given char is a english char.
|
//check the given char is a english char.
|
||||||
//(full-width and half-width)
|
//(full-width and half-width)
|
||||||
//not the punctuation of course.
|
//not the punctuation of course.
|
||||||
FRISO_API int utf8_en_letter( uint_t );
|
FRISO_API int utf8_en_letter(uint_t);
|
||||||
|
|
||||||
//check the given char is a whitespace or not.
|
//check the given char is a whitespace or not.
|
||||||
FRISO_API int utf8_whitespace( uint_t );
|
FRISO_API int utf8_whitespace(uint_t);
|
||||||
|
|
||||||
/* check if the given char is a letter number like 'ⅠⅡ'
|
/* check if the given char is a letter number like 'ⅠⅡ'
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_letter_number( uint_t );
|
FRISO_API int utf8_letter_number(uint_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given char is a other number like '①⑩⑽㈩'
|
* check if the given char is a other number like '①⑩⑽㈩'
|
||||||
*/
|
*/
|
||||||
FRISO_API int utf8_other_number( uint_t );
|
FRISO_API int utf8_other_number(uint_t);
|
||||||
|
|
||||||
//check if the given char is a english punctuation.
|
//check if the given char is a english punctuation.
|
||||||
FRISO_API int utf8_en_punctuation( uint_t ) ;
|
FRISO_API int utf8_en_punctuation(uint_t) ;
|
||||||
|
|
||||||
//check if the given char is a chinese punctuation.
|
//check if the given char is a chinese punctuation.
|
||||||
FRISO_API int utf8_cn_punctuation( uint_t u );
|
FRISO_API int utf8_cn_punctuation(uint_t u);
|
||||||
|
|
||||||
FRISO_API int is_en_punctuation( friso_charset_t, char );
|
FRISO_API int is_en_punctuation(friso_charset_t, char);
|
||||||
//#define is_en_punctuation( c ) utf8_en_punctuation((uint_t) c)
|
//#define is_en_punctuation( c ) utf8_en_punctuation((uint_t) c)
|
||||||
|
|
||||||
//@Deprecated
|
//@Deprecated
|
||||||
//FRISO_API int utf8_keep_punctuation( fstring );
|
//FRISO_API int utf8_keep_punctuation( fstring );
|
||||||
|
@ -186,67 +186,67 @@ FRISO_API int is_en_punctuation( friso_charset_t, char );
|
||||||
*
|
*
|
||||||
* @return int the bytes of the current readed word.
|
* @return int the bytes of the current readed word.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_next_word( friso_task_t, uint_t *, fstring );
|
FRISO_API int gbk_next_word(friso_task_t, uint_t *, fstring);
|
||||||
|
|
||||||
//get the bytes of a utf-8 char.
|
//get the bytes of a utf-8 char.
|
||||||
FRISO_API int get_gbk_bytes( char );
|
FRISO_API int get_gbk_bytes(char);
|
||||||
|
|
||||||
//check if the given char is a gbk char (ANSII string).
|
//check if the given char is a gbk char (ANSII string).
|
||||||
FRISO_API int gbk_cn_string( char * ) ;
|
FRISO_API int gbk_cn_string(char *) ;
|
||||||
|
|
||||||
/*check if the given char is a ASCII letter
|
/*check if the given char is a ASCII letter
|
||||||
* include all the letters and english puntuations.*/
|
* include all the letters and english puntuations.*/
|
||||||
FRISO_API int gbk_halfwidth_en_char( char );
|
FRISO_API int gbk_halfwidth_en_char(char);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given char is a full-width latain.
|
* check if the given char is a full-width latain.
|
||||||
* include the full-width arabic numeber, letters.
|
* include the full-width arabic numeber, letters.
|
||||||
* but not the full-width puntuations.
|
* but not the full-width puntuations.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_fullwidth_en_char( char * );
|
FRISO_API int gbk_fullwidth_en_char(char *);
|
||||||
|
|
||||||
//check if the given char is a upper case char.
|
//check if the given char is a upper case char.
|
||||||
// included all the full-width and half-width letters.
|
// included all the full-width and half-width letters.
|
||||||
FRISO_API int gbk_uppercase_letter( char * );
|
FRISO_API int gbk_uppercase_letter(char *);
|
||||||
|
|
||||||
//check if the given char is a lower case char.
|
//check if the given char is a lower case char.
|
||||||
// included all the full-width and half-width letters.
|
// included all the full-width and half-width letters.
|
||||||
FRISO_API int gbk_lowercase_letter( char * );
|
FRISO_API int gbk_lowercase_letter(char *);
|
||||||
|
|
||||||
//check if the given char is a numeric.
|
//check if the given char is a numeric.
|
||||||
// included the full-width and half-width arabic numeric.
|
// included the full-width and half-width arabic numeric.
|
||||||
FRISO_API int gbk_numeric_letter( char * );
|
FRISO_API int gbk_numeric_letter(char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given fstring is make up with numeric chars.
|
* check if the given fstring is make up with numeric chars.
|
||||||
* both full-width,half-width numeric is ok.
|
* both full-width,half-width numeric is ok.
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_numeric_string( char * );
|
FRISO_API int gbk_numeric_string(char *);
|
||||||
|
|
||||||
FRISO_API int gbk_decimal_string( char * );
|
FRISO_API int gbk_decimal_string(char *);
|
||||||
|
|
||||||
//check if the given char is a english(ASCII) char.
|
//check if the given char is a english(ASCII) char.
|
||||||
//(full-width and half-width)
|
//(full-width and half-width)
|
||||||
//not the punctuation of course.
|
//not the punctuation of course.
|
||||||
FRISO_API int gbk_en_letter( char * );
|
FRISO_API int gbk_en_letter(char *);
|
||||||
|
|
||||||
//check the specified char is a whitespace or not.
|
//check the specified char is a whitespace or not.
|
||||||
FRISO_API int gbk_whitespace( char * );
|
FRISO_API int gbk_whitespace(char *);
|
||||||
|
|
||||||
/* check if the given char is a letter number like 'ⅠⅡ'
|
/* check if the given char is a letter number like 'ⅠⅡ'
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_letter_number( char * );
|
FRISO_API int gbk_letter_number(char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check if the given char is a other number like '①⑩⑽㈩'
|
* check if the given char is a other number like '①⑩⑽㈩'
|
||||||
*/
|
*/
|
||||||
FRISO_API int gbk_other_number( char * );
|
FRISO_API int gbk_other_number(char *);
|
||||||
|
|
||||||
//check if the given char is a english punctuation.
|
//check if the given char is a english punctuation.
|
||||||
FRISO_API int gbk_en_punctuation( char ) ;
|
FRISO_API int gbk_en_punctuation(char) ;
|
||||||
|
|
||||||
//check the given char is a chinese punctuation.
|
//check the given char is a chinese punctuation.
|
||||||
FRISO_API int gbk_cn_punctuation( char * );
|
FRISO_API int gbk_cn_punctuation(char *);
|
||||||
|
|
||||||
//cause the logic handle is the same as the utf8.
|
//cause the logic handle is the same as the utf8.
|
||||||
// here invoke the utf8 interface directly.
|
// here invoke the utf8 interface directly.
|
||||||
|
|
|
@ -16,32 +16,30 @@
|
||||||
/* ************************
|
/* ************************
|
||||||
* mapping function area *
|
* mapping function area *
|
||||||
**************************/
|
**************************/
|
||||||
__STATIC_API__ uint_t hash( fstring str, uint_t length )
|
__STATIC_API__ uint_t hash(fstring str, uint_t length) {
|
||||||
{
|
|
||||||
//hash code
|
//hash code
|
||||||
uint_t h = 0;
|
uint_t h = 0;
|
||||||
|
|
||||||
while ( *str != '\0' ) {
|
while(*str != '\0') {
|
||||||
h = h * HASH_FACTOR + ( *str++ );
|
h = h * HASH_FACTOR + (*str++);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (h % length);
|
return (h % length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*test if a integer is a prime.*/
|
/*test if a integer is a prime.*/
|
||||||
__STATIC_API__ int is_prime( int n )
|
__STATIC_API__ int is_prime(int n) {
|
||||||
{
|
|
||||||
int j;
|
int j;
|
||||||
if ( n == 2 || n == 3 ) {
|
if(n == 2 || n == 3) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( n == 1 || n % 2 == 0 ) {
|
if(n == 1 || n % 2 == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = 3; j * j < n; j++ ) {
|
for(j = 3; j * j < n; j++) {
|
||||||
if ( n % j == 0 ) {
|
if(n % j == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,10 +48,9 @@ __STATIC_API__ int is_prime( int n )
|
||||||
}
|
}
|
||||||
|
|
||||||
/*get the next prime just after the speicified integer.*/
|
/*get the next prime just after the speicified integer.*/
|
||||||
__STATIC_API__ int next_prime( int n )
|
__STATIC_API__ int next_prime(int n) {
|
||||||
{
|
if(n % 2 == 0) n++;
|
||||||
if ( n % 2 == 0 ) n++;
|
for(; ! is_prime(n); n = n + 2) ;
|
||||||
for ( ; ! is_prime( n ); n = n + 2 ) ;
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -76,14 +73,13 @@ __STATIC_API__ int next_prime( int n )
|
||||||
/* *********************************
|
/* *********************************
|
||||||
* static hashtable function area. *
|
* static hashtable function area. *
|
||||||
***********************************/
|
***********************************/
|
||||||
__STATIC_API__ hash_entry_t new_hash_entry(
|
__STATIC_API__ hash_entry_t new_hash_entry(
|
||||||
fstring key,
|
fstring key,
|
||||||
void * value,
|
void * value,
|
||||||
hash_entry_t next )
|
hash_entry_t next) {
|
||||||
{
|
hash_entry_t e = (hash_entry_t)
|
||||||
hash_entry_t e = ( hash_entry_t )
|
FRISO_MALLOC(sizeof(friso_hash_entry));
|
||||||
FRISO_MALLOC( sizeof( friso_hash_entry ) );
|
if(e == NULL) {
|
||||||
if ( e == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,16 +92,15 @@ __STATIC_API__ hash_entry_t new_hash_entry(
|
||||||
}
|
}
|
||||||
|
|
||||||
//create blocks copy of entries.
|
//create blocks copy of entries.
|
||||||
__STATIC_API__ hash_entry_t * create_hash_entries( uint_t blocks )
|
__STATIC_API__ hash_entry_t * create_hash_entries(uint_t blocks) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
hash_entry_t *e = ( hash_entry_t * )
|
hash_entry_t *e = (hash_entry_t *)
|
||||||
FRISO_CALLOC( sizeof( hash_entry_t ), blocks );
|
FRISO_CALLOC(sizeof(hash_entry_t), blocks);
|
||||||
if ( e == NULL ) {
|
if(e == NULL) {
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( t = 0; t < blocks; t++ ) {
|
for(t = 0; t < blocks; t++) {
|
||||||
e[t] = NULL;
|
e[t] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,35 +108,34 @@ __STATIC_API__ hash_entry_t * create_hash_entries( uint_t blocks )
|
||||||
}
|
}
|
||||||
|
|
||||||
//a static function to do the re-hash work.
|
//a static function to do the re-hash work.
|
||||||
__STATIC_API__ void rebuild_hash( friso_hash_t _hash )
|
__STATIC_API__ void rebuild_hash(friso_hash_t _hash) {
|
||||||
{
|
|
||||||
//printf("rehashed.\n");
|
//printf("rehashed.\n");
|
||||||
//find the next prime as the length of the hashtable.
|
//find the next prime as the length of the hashtable.
|
||||||
uint_t t, length = next_prime( _hash->length * 2 + 1 );
|
uint_t t, length = next_prime(_hash->length * 2 + 1);
|
||||||
hash_entry_t e, next, *_src = _hash->table, \
|
hash_entry_t e, next, *_src = _hash->table, \
|
||||||
*table = create_hash_entries( length );
|
*table = create_hash_entries(length);
|
||||||
uint_t bucket;
|
uint_t bucket;
|
||||||
|
|
||||||
//copy the nodes
|
//copy the nodes
|
||||||
for ( t = 0; t < _hash->length; t++ ) {
|
for(t = 0; t < _hash->length; t++) {
|
||||||
e = *( _src + t );
|
e = *(_src + t);
|
||||||
if ( e != NULL ) {
|
if(e != NULL) {
|
||||||
do {
|
do {
|
||||||
next = e->_next;
|
next = e->_next;
|
||||||
bucket = hash( e->_key, length );
|
bucket = hash(e->_key, length);
|
||||||
e->_next = table[bucket];
|
e->_next = table[bucket];
|
||||||
table[bucket] = e;
|
table[bucket] = e;
|
||||||
e = next;
|
e = next;
|
||||||
} while ( e != NULL );
|
} while(e != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_hash->table = table;
|
_hash->table = table;
|
||||||
_hash->length = length;
|
_hash->length = length;
|
||||||
_hash->threshold = ( uint_t ) ( _hash->length * _hash->factor );
|
_hash->threshold = (uint_t)(_hash->length * _hash->factor);
|
||||||
|
|
||||||
//free the old hash_entry_t blocks allocations.
|
//free the old hash_entry_t blocks allocations.
|
||||||
FRISO_FREE( _src );
|
FRISO_FREE(_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************
|
/* ********************************
|
||||||
|
@ -149,10 +143,9 @@ __STATIC_API__ void rebuild_hash( friso_hash_t _hash )
|
||||||
* ********************************/
|
* ********************************/
|
||||||
|
|
||||||
//create a new hash table.
|
//create a new hash table.
|
||||||
FRISO_API friso_hash_t new_hash_table( void )
|
FRISO_API friso_hash_t new_hash_table(void) {
|
||||||
{
|
friso_hash_t _hash = (friso_hash_t) FRISO_MALLOC(sizeof(friso_hash_cdt));
|
||||||
friso_hash_t _hash = ( friso_hash_t ) FRISO_MALLOC( sizeof ( friso_hash_cdt ) );
|
if(_hash == NULL) {
|
||||||
if ( _hash == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,51 +153,49 @@ FRISO_API friso_hash_t new_hash_table( void )
|
||||||
_hash->length = DEFAULT_LENGTH;
|
_hash->length = DEFAULT_LENGTH;
|
||||||
_hash->size = 0;
|
_hash->size = 0;
|
||||||
_hash->factor = DEFAULT_FACTOR;
|
_hash->factor = DEFAULT_FACTOR;
|
||||||
_hash->threshold = ( uint_t ) ( _hash->length * _hash->factor );
|
_hash->threshold = (uint_t)(_hash->length * _hash->factor);
|
||||||
_hash->table = create_hash_entries( _hash->length );
|
_hash->table = create_hash_entries(_hash->length);
|
||||||
|
|
||||||
return _hash;
|
return _hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void free_hash_table(
|
FRISO_API void free_hash_table(
|
||||||
friso_hash_t _hash,
|
friso_hash_t _hash,
|
||||||
fhash_callback_fn_t fentry_func )
|
fhash_callback_fn_t fentry_func) {
|
||||||
{
|
|
||||||
register uint_t j;
|
register uint_t j;
|
||||||
hash_entry_t e, n;
|
hash_entry_t e, n;
|
||||||
|
|
||||||
for ( j = 0; j < _hash->length; j++ ) {
|
for(j = 0; j < _hash->length; j++) {
|
||||||
e = *( _hash->table + j );
|
e = *(_hash->table + j);
|
||||||
for ( ; e != NULL ; ) {
|
for(; e != NULL ;) {
|
||||||
n = e->_next;
|
n = e->_next;
|
||||||
if ( fentry_func != NULL ) fentry_func(e);
|
if(fentry_func != NULL) fentry_func(e);
|
||||||
FRISO_FREE( e );
|
FRISO_FREE(e);
|
||||||
e = n;
|
e = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//free the pointer array block ( 4 * htable->length continuous bytes ).
|
//free the pointer array block ( 4 * htable->length continuous bytes ).
|
||||||
FRISO_FREE( _hash->table );
|
FRISO_FREE(_hash->table);
|
||||||
FRISO_FREE( _hash );
|
FRISO_FREE(_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//put a new mapping insite.
|
//put a new mapping insite.
|
||||||
//the value cannot be NULL.
|
//the value cannot be NULL.
|
||||||
FRISO_API void *hash_put_mapping(
|
FRISO_API void *hash_put_mapping(
|
||||||
friso_hash_t _hash,
|
friso_hash_t _hash,
|
||||||
fstring key,
|
fstring key,
|
||||||
void * value )
|
void * value) {
|
||||||
{
|
uint_t bucket = (key == NULL) ? 0 : hash(key, _hash->length);
|
||||||
uint_t bucket = ( key == NULL ) ? 0 : hash( key, _hash->length );
|
hash_entry_t e = *(_hash->table + bucket);
|
||||||
hash_entry_t e = *( _hash->table + bucket );
|
|
||||||
void *oval = NULL;
|
void *oval = NULL;
|
||||||
|
|
||||||
//check the given key is already exists or not.
|
//check the given key is already exists or not.
|
||||||
for ( ; e != NULL; e = e->_next ) {
|
for(; e != NULL; e = e->_next) {
|
||||||
if ( key == e->_key
|
if(key == e->_key
|
||||||
|| ( key != NULL && e->_key != NULL
|
|| (key != NULL && e->_key != NULL
|
||||||
&& strcmp( key, e->_key ) == 0 ) ) {
|
&& strcmp(key, e->_key) == 0)) {
|
||||||
oval = e->_val; //bak the old value
|
oval = e->_val; //bak the old value
|
||||||
e->_key = key;
|
e->_key = key;
|
||||||
e->_val = value;
|
e->_val = value;
|
||||||
|
@ -213,29 +204,28 @@ FRISO_API void *hash_put_mapping(
|
||||||
}
|
}
|
||||||
|
|
||||||
//put a new mapping into the hashtable.
|
//put a new mapping into the hashtable.
|
||||||
_hash->table[bucket] = new_hash_entry( key, value, _hash->table[bucket] );
|
_hash->table[bucket] = new_hash_entry(key, value, _hash->table[bucket]);
|
||||||
_hash->size++;
|
_hash->size++;
|
||||||
|
|
||||||
//check the condition to rebuild the hashtable.
|
//check the condition to rebuild the hashtable.
|
||||||
if ( _hash->size >= _hash->threshold ) {
|
if(_hash->size >= _hash->threshold) {
|
||||||
rebuild_hash( _hash );
|
rebuild_hash(_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
return oval;
|
return oval;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check the existence of the mapping associated with the given key.
|
//check the existence of the mapping associated with the given key.
|
||||||
FRISO_API int hash_exist_mapping(
|
FRISO_API int hash_exist_mapping(
|
||||||
friso_hash_t _hash, fstring key )
|
friso_hash_t _hash, fstring key) {
|
||||||
{
|
uint_t bucket = (key == NULL) ? 0 : hash(key, _hash->length);
|
||||||
uint_t bucket = ( key == NULL ) ? 0 : hash( key, _hash->length );
|
|
||||||
hash_entry_t e;
|
hash_entry_t e;
|
||||||
|
|
||||||
for ( e = *( _hash->table + bucket );
|
for(e = *(_hash->table + bucket);
|
||||||
e != NULL; e = e->_next ) {
|
e != NULL; e = e->_next) {
|
||||||
if ( key == e->_key
|
if(key == e->_key
|
||||||
|| ( key != NULL && e->_key != NULL
|
|| (key != NULL && e->_key != NULL
|
||||||
&& strcmp( key, e->_key ) == 0 )) {
|
&& strcmp(key, e->_key) == 0)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,16 +234,15 @@ FRISO_API int hash_exist_mapping(
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the value associated with the given key.
|
//get the value associated with the given key.
|
||||||
FRISO_API void *hash_get_value( friso_hash_t _hash, fstring key )
|
FRISO_API void *hash_get_value(friso_hash_t _hash, fstring key) {
|
||||||
{
|
uint_t bucket = (key == NULL) ? 0 : hash(key, _hash->length);
|
||||||
uint_t bucket = ( key == NULL ) ? 0 : hash( key, _hash->length );
|
|
||||||
hash_entry_t e;
|
hash_entry_t e;
|
||||||
|
|
||||||
for ( e = *( _hash->table + bucket );
|
for(e = *(_hash->table + bucket);
|
||||||
e != NULL; e = e->_next ) {
|
e != NULL; e = e->_next) {
|
||||||
if ( key == e->_key
|
if(key == e->_key
|
||||||
|| ( key != NULL && e->_key != NULL
|
|| (key != NULL && e->_key != NULL
|
||||||
&& strcmp( key, e->_key ) == 0 )) {
|
&& strcmp(key, e->_key) == 0)) {
|
||||||
return e->_val;
|
return e->_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,21 +251,20 @@ FRISO_API void *hash_get_value( friso_hash_t _hash, fstring key )
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove the mapping associated with the given key.
|
//remove the mapping associated with the given key.
|
||||||
FRISO_API hash_entry_t hash_remove_mapping(
|
FRISO_API hash_entry_t hash_remove_mapping(
|
||||||
friso_hash_t _hash, fstring key )
|
friso_hash_t _hash, fstring key) {
|
||||||
{
|
uint_t bucket = (key == NULL) ? 0 : hash(key, _hash->length);
|
||||||
uint_t bucket = ( key == NULL ) ? 0 : hash( key, _hash->length );
|
|
||||||
hash_entry_t e, prev = NULL;
|
hash_entry_t e, prev = NULL;
|
||||||
hash_entry_t b;
|
hash_entry_t b;
|
||||||
|
|
||||||
for ( e = *( _hash->table + bucket );
|
for(e = *(_hash->table + bucket);
|
||||||
e != NULL; prev = e, e = e->_next ) {
|
e != NULL; prev = e, e = e->_next) {
|
||||||
if ( key == e->_key
|
if(key == e->_key
|
||||||
|| ( key != NULL && e->_key != NULL
|
|| (key != NULL && e->_key != NULL
|
||||||
&& strcmp( key, e->_key ) == 0 ) ) {
|
&& strcmp(key, e->_key) == 0)) {
|
||||||
b = e;
|
b = e;
|
||||||
//the node located at *( htable->table + bucket )
|
//the node located at *( htable->table + bucket )
|
||||||
if ( prev == NULL ) {
|
if(prev == NULL) {
|
||||||
_hash->table[bucket] = e->_next;
|
_hash->table[bucket] = e->_next;
|
||||||
} else {
|
} else {
|
||||||
prev->_next = e->_next;
|
prev->_next = e->_next;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* friso lexicon functions implementation.
|
* friso lexicon functions implementation.
|
||||||
* used to deal with the friso lexicon, like: load,remove,match...
|
* used to deal with the friso lexicon, like: load,remove,match...
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -15,16 +15,15 @@
|
||||||
#define __FRISO_LEX_IFILE__ "friso.lex.ini"
|
#define __FRISO_LEX_IFILE__ "friso.lex.ini"
|
||||||
|
|
||||||
//create a new lexicon
|
//create a new lexicon
|
||||||
FRISO_API friso_dic_t friso_dic_new()
|
FRISO_API friso_dic_t friso_dic_new() {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
friso_dic_t dic = ( friso_dic_t ) FRISO_CALLOC(
|
friso_dic_t dic = (friso_dic_t) FRISO_CALLOC(
|
||||||
sizeof( friso_hash_t ), __FRISO_LEXICON_LENGTH__ );
|
sizeof(friso_hash_t), __FRISO_LEXICON_LENGTH__);
|
||||||
if ( dic == NULL ) {
|
if(dic == NULL) {
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( t = 0; t < __FRISO_LEXICON_LENGTH__; t++ ) {
|
for(t = 0; t < __FRISO_LEXICON_LENGTH__; t++) {
|
||||||
dic[t] = new_hash_table();
|
dic[t] = new_hash_table();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,24 +32,23 @@ FRISO_API friso_dic_t friso_dic_new()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* default callback function to invoke
|
* default callback function to invoke
|
||||||
* when free the friso dictionary .
|
* when free the friso dictionary .
|
||||||
*
|
*
|
||||||
* @date 2013-06-12
|
* @date 2013-06-12
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ void default_fdic_callback( hash_entry_t e )
|
__STATIC_API__ void default_fdic_callback(hash_entry_t e) {
|
||||||
{
|
|
||||||
register uint_t i;
|
register uint_t i;
|
||||||
friso_array_t syn;
|
friso_array_t syn;
|
||||||
lex_entry_t lex = ( lex_entry_t ) e->_val;
|
lex_entry_t lex = (lex_entry_t) e->_val;
|
||||||
//free the lex->word
|
//free the lex->word
|
||||||
FRISO_FREE( lex->word );
|
FRISO_FREE(lex->word);
|
||||||
//free the lex->syn if it is not NULL
|
//free the lex->syn if it is not NULL
|
||||||
if ( lex->syn != NULL ) {
|
if(lex->syn != NULL) {
|
||||||
syn = lex->syn;
|
syn = lex->syn;
|
||||||
for ( i = 0; i < syn->length; i++ ) {
|
for(i = 0; i < syn->length; i++) {
|
||||||
FRISO_FREE( syn->items[i] );
|
FRISO_FREE(syn->items[i]);
|
||||||
}
|
}
|
||||||
free_array_list( syn );
|
free_array_list(syn);
|
||||||
}
|
}
|
||||||
|
|
||||||
//free the e->_val
|
//free the e->_val
|
||||||
|
@ -58,29 +56,27 @@ __STATIC_API__ void default_fdic_callback( hash_entry_t e )
|
||||||
FRISO_FREE(lex);
|
FRISO_FREE(lex);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void friso_dic_free( friso_dic_t dic )
|
FRISO_API void friso_dic_free(friso_dic_t dic) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
for ( t = 0; t < __FRISO_LEXICON_LENGTH__; t++ ) {
|
for(t = 0; t < __FRISO_LEXICON_LENGTH__; t++) {
|
||||||
//free the hash table
|
//free the hash table
|
||||||
free_hash_table( dic[t], default_fdic_callback );
|
free_hash_table(dic[t], default_fdic_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_FREE( dic );
|
FRISO_FREE(dic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//create a new lexicon entry
|
//create a new lexicon entry
|
||||||
FRISO_API lex_entry_t new_lex_entry(
|
FRISO_API lex_entry_t new_lex_entry(
|
||||||
fstring word,
|
fstring word,
|
||||||
friso_array_t syn,
|
friso_array_t syn,
|
||||||
uint_t fre,
|
uint_t fre,
|
||||||
uint_t length,
|
uint_t length,
|
||||||
uint_t type )
|
uint_t type) {
|
||||||
{
|
lex_entry_t e = (lex_entry_t)
|
||||||
lex_entry_t e = ( lex_entry_t )
|
FRISO_MALLOC(sizeof(lex_entry_cdt));
|
||||||
FRISO_MALLOC( sizeof( lex_entry_cdt ) );
|
if(e == NULL) {
|
||||||
if ( e == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,20 +103,19 @@ FRISO_API lex_entry_t new_lex_entry(
|
||||||
* 3. free its pos. (friso_array_t)
|
* 3. free its pos. (friso_array_t)
|
||||||
* 4. free the lex_entry_t.
|
* 4. free the lex_entry_t.
|
||||||
*/
|
*/
|
||||||
FRISO_API void free_lex_entry_full( lex_entry_t e )
|
FRISO_API void free_lex_entry_full(lex_entry_t e) {
|
||||||
{
|
|
||||||
register uint_t i;
|
register uint_t i;
|
||||||
friso_array_t syn;
|
friso_array_t syn;
|
||||||
|
|
||||||
//free the lex->word
|
//free the lex->word
|
||||||
FRISO_FREE( e->word );
|
FRISO_FREE(e->word);
|
||||||
//free the lex->syn if it is not NULL
|
//free the lex->syn if it is not NULL
|
||||||
if ( e->syn != NULL ) {
|
if(e->syn != NULL) {
|
||||||
syn = e->syn;
|
syn = e->syn;
|
||||||
for ( i = 0; i < syn->length; i++ ) {
|
for(i = 0; i < syn->length; i++) {
|
||||||
FRISO_FREE( syn->items[i] );
|
FRISO_FREE(syn->items[i]);
|
||||||
}
|
}
|
||||||
free_array_list( syn );
|
free_array_list(syn);
|
||||||
}
|
}
|
||||||
|
|
||||||
//free the e->_val
|
//free the e->_val
|
||||||
|
@ -128,8 +123,7 @@ FRISO_API void free_lex_entry_full( lex_entry_t e )
|
||||||
FRISO_FREE(e);
|
FRISO_FREE(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void free_lex_entry( lex_entry_t e )
|
FRISO_API void free_lex_entry(lex_entry_t e) {
|
||||||
{
|
|
||||||
//if ( e->syn != NULL ) {
|
//if ( e->syn != NULL ) {
|
||||||
// if ( flag == 1 ) free_array_list( e->syn);
|
// if ( flag == 1 ) free_array_list( e->syn);
|
||||||
// else free_array_list( e->syn );
|
// else free_array_list( e->syn );
|
||||||
|
@ -140,37 +134,35 @@ FRISO_API void free_lex_entry( lex_entry_t e )
|
||||||
|
|
||||||
|
|
||||||
//add a new entry to the dictionary.
|
//add a new entry to the dictionary.
|
||||||
FRISO_API void friso_dic_add(
|
FRISO_API void friso_dic_add(
|
||||||
friso_dic_t dic,
|
friso_dic_t dic,
|
||||||
friso_lex_t lex,
|
friso_lex_t lex,
|
||||||
fstring word,
|
fstring word,
|
||||||
friso_array_t syn )
|
friso_array_t syn) {
|
||||||
{
|
|
||||||
void *olex = NULL;
|
void *olex = NULL;
|
||||||
if ( lex >= 0 && lex < __FRISO_LEXICON_LENGTH__ ) {
|
if(lex >= 0 && lex < __FRISO_LEXICON_LENGTH__) {
|
||||||
//printf("lex=%d, word=%s, syn=%s\n", lex, word, syn);
|
//printf("lex=%d, word=%s, syn=%s\n", lex, word, syn);
|
||||||
olex = hash_put_mapping( dic[lex], word,
|
olex = hash_put_mapping(dic[lex], word,
|
||||||
new_lex_entry( word, syn, 0,
|
new_lex_entry(word, syn, 0,
|
||||||
(uint_t) strlen(word), (uint_t) lex ) );
|
(uint_t) strlen(word), (uint_t) lex));
|
||||||
if ( olex != NULL ) {
|
if(olex != NULL) {
|
||||||
free_lex_entry_full((lex_entry_t)olex);
|
free_lex_entry_full((lex_entry_t)olex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void friso_dic_add_with_fre(
|
FRISO_API void friso_dic_add_with_fre(
|
||||||
friso_dic_t dic,
|
friso_dic_t dic,
|
||||||
friso_lex_t lex,
|
friso_lex_t lex,
|
||||||
fstring word,
|
fstring word,
|
||||||
friso_array_t syn,
|
friso_array_t syn,
|
||||||
uint_t frequency )
|
uint_t frequency) {
|
||||||
{
|
|
||||||
void *olex = NULL;
|
void *olex = NULL;
|
||||||
if ( lex >= 0 && lex < __FRISO_LEXICON_LENGTH__ ) {
|
if(lex >= 0 && lex < __FRISO_LEXICON_LENGTH__) {
|
||||||
olex = hash_put_mapping( dic[lex], word,
|
olex = hash_put_mapping(dic[lex], word,
|
||||||
new_lex_entry( word, syn, frequency,
|
new_lex_entry(word, syn, frequency,
|
||||||
( uint_t ) strlen(word), ( uint_t ) lex ) );
|
(uint_t) strlen(word), (uint_t) lex));
|
||||||
if ( olex != NULL ) {
|
if(olex != NULL) {
|
||||||
free_lex_entry_full((lex_entry_t)olex);
|
free_lex_entry_full((lex_entry_t)olex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,39 +171,37 @@ FRISO_API void friso_dic_add_with_fre(
|
||||||
/*
|
/*
|
||||||
* read a line from a specified stream.
|
* read a line from a specified stream.
|
||||||
* the newline will be cleared.
|
* the newline will be cleared.
|
||||||
*
|
*
|
||||||
* @date 2012-11-24
|
* @date 2012-11-24
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring file_get_line( fstring __dst, FILE * _stream )
|
FRISO_API fstring file_get_line(fstring __dst, FILE * _stream) {
|
||||||
{
|
|
||||||
register int c;
|
register int c;
|
||||||
fstring cs;
|
fstring cs;
|
||||||
|
|
||||||
cs = __dst;
|
cs = __dst;
|
||||||
while ( ( c = fgetc( _stream ) ) != EOF ) {
|
while((c = fgetc(_stream)) != EOF) {
|
||||||
if ( c == '\n' ) break;
|
if(c == '\n') break;
|
||||||
*cs++ = c;
|
*cs++ = c;
|
||||||
}
|
}
|
||||||
*cs = '\0';
|
*cs = '\0';
|
||||||
|
|
||||||
return ( c == EOF && cs == __dst ) ? NULL : __dst;
|
return (c == EOF && cs == __dst) ? NULL : __dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* static function to copy a string.
|
* static function to copy a string.
|
||||||
*/
|
*/
|
||||||
///instead of memcpy
|
///instead of memcpy
|
||||||
__STATIC_API__ fstring string_copy(
|
__STATIC_API__ fstring string_copy(
|
||||||
fstring _src,
|
fstring _src,
|
||||||
fstring __dst,
|
fstring __dst,
|
||||||
uint_t blocks )
|
uint_t blocks) {
|
||||||
{
|
|
||||||
|
|
||||||
register fstring __src = _src;
|
register fstring __src = _src;
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
|
|
||||||
for ( t = 0; t < blocks; t++ ) {
|
for(t = 0; t < blocks; t++) {
|
||||||
if ( *__src == '\0' ) break;
|
if(*__src == '\0') break;
|
||||||
__dst[t] = *__src++;
|
__dst[t] = *__src++;
|
||||||
}
|
}
|
||||||
__dst[t] = '\0';
|
__dst[t] = '\0';
|
||||||
|
@ -220,24 +210,23 @@ __STATIC_API__ fstring string_copy(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* make a heap allocation, and copy the
|
* make a heap allocation, and copy the
|
||||||
* source fstring to the new allocation, and
|
* source fstring to the new allocation, and
|
||||||
* you should free it after use it .
|
* you should free it after use it .
|
||||||
*
|
*
|
||||||
* @param _src source fstring
|
* @param _src source fstring
|
||||||
* @param blocks number of bytes to copy
|
* @param blocks number of bytes to copy
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ fstring string_copy_heap(
|
__STATIC_API__ fstring string_copy_heap(
|
||||||
fstring _src, uint_t blocks )
|
fstring _src, uint_t blocks) {
|
||||||
{
|
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
|
|
||||||
fstring str = ( fstring ) FRISO_MALLOC( blocks + 1 );
|
fstring str = (fstring) FRISO_MALLOC(blocks + 1);
|
||||||
if ( str == NULL ) {
|
if(str == NULL) {
|
||||||
___ALLOCATION_ERROR___;
|
___ALLOCATION_ERROR___;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( t = 0; t < blocks; t++ ) {
|
for(t = 0; t < blocks; t++) {
|
||||||
//if ( *_src == '\0' ) break;
|
//if ( *_src == '\0' ) break;
|
||||||
str[t] = *_src++;
|
str[t] = *_src++;
|
||||||
}
|
}
|
||||||
|
@ -249,15 +238,14 @@ __STATIC_API__ fstring string_copy_heap(
|
||||||
/*
|
/*
|
||||||
* find the postion of the first appear of the given char.
|
* find the postion of the first appear of the given char.
|
||||||
* address of the char in the fstring will be return .
|
* address of the char in the fstring will be return .
|
||||||
* if not found NULL will be return .
|
* if not found NULL will be return .
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ fstring indexOf( fstring __str, char delimiter )
|
__STATIC_API__ fstring indexOf(fstring __str, char delimiter) {
|
||||||
{
|
|
||||||
uint_t i, __length__;
|
uint_t i, __length__;
|
||||||
|
|
||||||
__length__ = strlen( __str );
|
__length__ = strlen(__str);
|
||||||
for ( i = 0; i < __length__; i++ ) {
|
for(i = 0; i < __length__; i++) {
|
||||||
if ( __str[i] == delimiter ) {
|
if(__str[i] == delimiter) {
|
||||||
return __str + i;
|
return __str + i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,20 +254,19 @@ __STATIC_API__ fstring indexOf( fstring __str, char delimiter )
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load all the valid wors from a specified lexicon file .
|
* load all the valid wors from a specified lexicon file .
|
||||||
*
|
*
|
||||||
* @param dic friso dictionary instance (A hash array)
|
* @param dic friso dictionary instance (A hash array)
|
||||||
* @param lex the lexicon type
|
* @param lex the lexicon type
|
||||||
* @param lex_file the path of the lexicon file
|
* @param lex_file the path of the lexicon file
|
||||||
* @param length the maximum length of the word item
|
* @param length the maximum length of the word item
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_load(
|
FRISO_API void friso_dic_load(
|
||||||
friso_t friso,
|
friso_t friso,
|
||||||
friso_config_t config,
|
friso_config_t config,
|
||||||
friso_lex_t lex,
|
friso_lex_t lex,
|
||||||
fstring lex_file,
|
fstring lex_file,
|
||||||
uint_t length )
|
uint_t length) {
|
||||||
{
|
|
||||||
|
|
||||||
FILE * _stream;
|
FILE * _stream;
|
||||||
char __char[1024], _buffer[512];
|
char __char[1024], _buffer[512];
|
||||||
|
@ -292,35 +279,35 @@ FRISO_API void friso_dic_load(
|
||||||
friso_array_t sywords;
|
friso_array_t sywords;
|
||||||
uint_t _fre;
|
uint_t _fre;
|
||||||
|
|
||||||
if ( ( _stream = fopen( lex_file, "rb" ) ) != NULL ) {
|
if((_stream = fopen(lex_file, "rb")) != NULL) {
|
||||||
while ( ( _line = file_get_line( __char, _stream ) ) != NULL ) {
|
while((_line = file_get_line(__char, _stream)) != NULL) {
|
||||||
//clear up the notes
|
//clear up the notes
|
||||||
//make sure the length of the line is greater than 1.
|
//make sure the length of the line is greater than 1.
|
||||||
//like the single '#' mark in stopwords dictionary.
|
//like the single '#' mark in stopwords dictionary.
|
||||||
if ( _line[0] == '#' && strlen(_line) > 1 ) continue;
|
if(_line[0] == '#' && strlen(_line) > 1) continue;
|
||||||
|
|
||||||
//handle the stopwords.
|
//handle the stopwords.
|
||||||
if ( lex == __LEX_STOPWORDS__ ) {
|
if(lex == __LEX_STOPWORDS__) {
|
||||||
//clean the chinese words that its length is greater than max length.
|
//clean the chinese words that its length is greater than max length.
|
||||||
if ( ((int)_line[0]) < 0 && strlen( _line ) > length ) continue;
|
if(((int)_line[0]) < 0 && strlen(_line) > length) continue;
|
||||||
friso_dic_add( friso->dic, __LEX_STOPWORDS__,
|
friso_dic_add(friso->dic, __LEX_STOPWORDS__,
|
||||||
string_copy_heap( _line, strlen(_line) ), NULL );
|
string_copy_heap(_line, strlen(_line)), NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//split the fstring with '/'.
|
//split the fstring with '/'.
|
||||||
string_split_reset( &sse, "/", _line);
|
string_split_reset(&sse, "/", _line);
|
||||||
if ( string_split_next( &sse, _buffer ) == NULL ) {
|
if(string_split_next(&sse, _buffer) == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//1. get the word.
|
//1. get the word.
|
||||||
_word = string_copy_heap( _buffer, strlen(_buffer) );
|
_word = string_copy_heap(_buffer, strlen(_buffer));
|
||||||
|
|
||||||
if ( string_split_next( &sse, _buffer ) == NULL ) {
|
if(string_split_next(&sse, _buffer) == NULL) {
|
||||||
//normal lexicon type,
|
//normal lexicon type,
|
||||||
//add them to the dictionary directly
|
//add them to the dictionary directly
|
||||||
friso_dic_add( friso->dic, lex, _word, NULL );
|
friso_dic_add(friso->dic, lex, _word, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,87 +317,86 @@ FRISO_API void friso_dic_load(
|
||||||
* but not for __LEX_ECM_WORDS__ and english __LEX_STOPWORDS__
|
* but not for __LEX_ECM_WORDS__ and english __LEX_STOPWORDS__
|
||||||
* and __LEX_CEM_WORDS__.
|
* and __LEX_CEM_WORDS__.
|
||||||
*/
|
*/
|
||||||
if ( ! ( lex == __LEX_ECM_WORDS__ || lex == __LEX_CEM_WORDS__ )
|
if(!(lex == __LEX_ECM_WORDS__ || lex == __LEX_CEM_WORDS__)
|
||||||
&& strlen( _word ) > length ) {
|
&& strlen(_word) > length) {
|
||||||
FRISO_FREE(_word);
|
FRISO_FREE(_word);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//2. get the synonyms words.
|
//2. get the synonyms words.
|
||||||
_syn = NULL;
|
_syn = NULL;
|
||||||
if ( strcmp( _buffer, "null" ) != 0 ) {
|
if(strcmp(_buffer, "null") != 0) {
|
||||||
_syn = string_copy( _buffer, _sbuffer, strlen(_buffer) );
|
_syn = string_copy(_buffer, _sbuffer, strlen(_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
//3. get the word frequency if it available.
|
//3. get the word frequency if it available.
|
||||||
_fre = 0;
|
_fre = 0;
|
||||||
if ( string_split_next( &sse, _buffer ) != NULL ) {
|
if(string_split_next(&sse, _buffer) != NULL) {
|
||||||
_fre = atoi( _buffer );
|
_fre = atoi(_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here:
|
* Here:
|
||||||
* split the synonyms words with mark ","
|
* split the synonyms words with mark ","
|
||||||
* and put them in a array list if the synonyms is not NULL
|
* and put them in a array list if the synonyms is not NULL
|
||||||
*/
|
*/
|
||||||
sywords = NULL;
|
sywords = NULL;
|
||||||
if ( config->add_syn && _syn != NULL ) {
|
if(config->add_syn && _syn != NULL) {
|
||||||
string_split_reset( &sse, ",", _sbuffer );
|
string_split_reset(&sse, ",", _sbuffer);
|
||||||
sywords = new_array_list_with_opacity(5);
|
sywords = new_array_list_with_opacity(5);
|
||||||
while ( string_split_next( &sse, _buffer ) != NULL ) {
|
while(string_split_next(&sse, _buffer) != NULL) {
|
||||||
if ( strlen(_buffer) > length ) continue;
|
if(strlen(_buffer) > length) continue;
|
||||||
array_list_add( sywords,
|
array_list_add(sywords,
|
||||||
string_copy_heap(_buffer, strlen(_buffer)) );
|
string_copy_heap(_buffer, strlen(_buffer)));
|
||||||
}
|
}
|
||||||
sywords = array_list_trim( sywords );
|
sywords = array_list_trim(sywords);
|
||||||
}
|
}
|
||||||
|
|
||||||
//4. add the word item
|
//4. add the word item
|
||||||
friso_dic_add_with_fre(
|
friso_dic_add_with_fre(
|
||||||
friso->dic, lex, _word, sywords, _fre );
|
friso->dic, lex, _word, sywords, _fre);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose( _stream );
|
fclose(_stream);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Warning: Fail to open lexicon file %s\n", lex_file);
|
fprintf(stderr, "Warning: Fail to open lexicon file %s\n", lex_file);
|
||||||
fprintf(stderr, "Warning: Without lexicon file, segment results will not correct \n");
|
fprintf(stderr, "Warning: Without lexicon file, segment results will not correct \n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the lexicon type index with the specified
|
* get the lexicon type index with the specified
|
||||||
* type keywords .
|
* type keywords .
|
||||||
*
|
*
|
||||||
* @see friso.h#friso_lex_t
|
* @see friso.h#friso_lex_t
|
||||||
* @param _key
|
* @param _key
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ friso_lex_t get_lexicon_type_with_constant( fstring _key )
|
__STATIC_API__ friso_lex_t get_lexicon_type_with_constant(fstring _key) {
|
||||||
{
|
if(strcmp(_key, "__LEX_CJK_WORDS__") == 0) {
|
||||||
if ( strcmp( _key, "__LEX_CJK_WORDS__" ) == 0 ) {
|
|
||||||
return __LEX_CJK_WORDS__;
|
return __LEX_CJK_WORDS__;
|
||||||
} else if ( strcmp( _key, "__LEX_CJK_UNITS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CJK_UNITS__") == 0) {
|
||||||
return __LEX_CJK_UNITS__;
|
return __LEX_CJK_UNITS__;
|
||||||
} else if ( strcmp( _key, "__LEX_ECM_WORDS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_ECM_WORDS__") == 0) {
|
||||||
return __LEX_ECM_WORDS__;
|
return __LEX_ECM_WORDS__;
|
||||||
} else if ( strcmp( _key, "__LEX_CEM_WORDS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CEM_WORDS__") == 0) {
|
||||||
return __LEX_CEM_WORDS__;
|
return __LEX_CEM_WORDS__;
|
||||||
} else if ( strcmp( _key, "__LEX_CN_LNAME__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CN_LNAME__") == 0) {
|
||||||
return __LEX_CN_LNAME__;
|
return __LEX_CN_LNAME__;
|
||||||
} else if ( strcmp( _key, "__LEX_CN_SNAME__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CN_SNAME__") == 0) {
|
||||||
return __LEX_CN_SNAME__;
|
return __LEX_CN_SNAME__;
|
||||||
} else if ( strcmp( _key, "__LEX_CN_DNAME1__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CN_DNAME1__") == 0) {
|
||||||
return __LEX_CN_DNAME1__;
|
return __LEX_CN_DNAME1__;
|
||||||
} else if ( strcmp( _key, "__LEX_CN_DNAME2__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CN_DNAME2__") == 0) {
|
||||||
return __LEX_CN_DNAME2__;
|
return __LEX_CN_DNAME2__;
|
||||||
} else if ( strcmp( _key, "__LEX_CN_LNA__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_CN_LNA__") == 0) {
|
||||||
return __LEX_CN_LNA__;
|
return __LEX_CN_LNA__;
|
||||||
} else if ( strcmp( _key, "__LEX_STOPWORDS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_STOPWORDS__") == 0) {
|
||||||
return __LEX_STOPWORDS__;
|
return __LEX_STOPWORDS__;
|
||||||
} else if ( strcmp( _key, "__LEX_ENPUN_WORDS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_ENPUN_WORDS__") == 0) {
|
||||||
return __LEX_ENPUN_WORDS__;
|
return __LEX_ENPUN_WORDS__;
|
||||||
} else if ( strcmp( _key, "__LEX_EN_WORDS__" ) == 0 ) {
|
} else if(strcmp(_key, "__LEX_EN_WORDS__") == 0) {
|
||||||
return __LEX_EN_WORDS__;
|
return __LEX_EN_WORDS__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,14 +410,13 @@ __STATIC_API__ friso_lex_t get_lexicon_type_with_constant( fstring _key )
|
||||||
* @param friso friso instance
|
* @param friso friso instance
|
||||||
* @param config friso_config instance
|
* @param config friso_config instance
|
||||||
* @param _path dictionary directory
|
* @param _path dictionary directory
|
||||||
* @param _limitts words length limit
|
* @param _limitts words length limit
|
||||||
*/
|
*/
|
||||||
FRISO_API void friso_dic_load_from_ifile(
|
FRISO_API void friso_dic_load_from_ifile(
|
||||||
friso_t friso,
|
friso_t friso,
|
||||||
friso_config_t config,
|
friso_config_t config,
|
||||||
fstring _path,
|
fstring _path,
|
||||||
uint_t _limits )
|
uint_t _limits) {
|
||||||
{
|
|
||||||
|
|
||||||
//1.parse the configuration file.
|
//1.parse the configuration file.
|
||||||
FILE *__stream;
|
FILE *__stream;
|
||||||
|
@ -443,116 +428,112 @@ FRISO_API void friso_dic_load_from_ifile(
|
||||||
//get the lexicon configruation file path
|
//get the lexicon configruation file path
|
||||||
sb = new_string_buffer();
|
sb = new_string_buffer();
|
||||||
|
|
||||||
string_buffer_append( sb, _path );
|
string_buffer_append(sb, _path);
|
||||||
string_buffer_append( sb, __FRISO_LEX_IFILE__ );
|
string_buffer_append(sb, __FRISO_LEX_IFILE__);
|
||||||
//printf("%s\n", sb->buffer);
|
//printf("%s\n", sb->buffer);
|
||||||
|
|
||||||
if ( ( __stream = fopen( sb->buffer, "rb" ) ) != NULL ) {
|
if((__stream = fopen(sb->buffer, "rb")) != NULL) {
|
||||||
while ( ( __line__ =
|
while((__line__ =
|
||||||
file_get_line( __chars__, __stream ) ) != NULL ) {
|
file_get_line(__chars__, __stream)) != NULL) {
|
||||||
//comment filter.
|
//comment filter.
|
||||||
if ( __line__[0] == '#' ) continue;
|
if(__line__[0] == '#') continue;
|
||||||
if ( __line__[0] == '\0' ) continue;
|
if(__line__[0] == '\0') continue;
|
||||||
|
|
||||||
__length__ = strlen( __line__ );
|
__length__ = strlen(__line__);
|
||||||
//item start
|
//item start
|
||||||
if ( __line__[ __length__ - 1 ] == '[' ) {
|
if(__line__[ __length__ - 1 ] == '[') {
|
||||||
//get the type key
|
//get the type key
|
||||||
for ( i = 0; i < __length__
|
for(i = 0; i < __length__
|
||||||
&& ( __line__[i] == ' ' || __line__[i] == '\t' ); i++ );
|
&& (__line__[i] == ' ' || __line__[i] == '\t'); i++);
|
||||||
for ( t = 0; i < __length__; i++,t++ ) {
|
for(t = 0; i < __length__; i++, t++) {
|
||||||
if ( __line__[i] == ' '
|
if(__line__[i] == ' '
|
||||||
|| __line__[i] == '\t' || __line__[i] == ':' ) break;
|
|| __line__[i] == '\t' || __line__[i] == ':') break;
|
||||||
__key__[t] = __line__[i];
|
__key__[t] = __line__[i];
|
||||||
}
|
}
|
||||||
__key__[t] = '\0';
|
__key__[t] = '\0';
|
||||||
|
|
||||||
//get the lexicon type
|
//get the lexicon type
|
||||||
lex_t = get_lexicon_type_with_constant(__key__);
|
lex_t = get_lexicon_type_with_constant(__key__);
|
||||||
if ( lex_t == -1 ) continue;
|
if(lex_t == -1) continue;
|
||||||
|
|
||||||
//printf("key=%s, type=%d\n", __key__, lex_t );
|
//printf("key=%s, type=%d\n", __key__, lex_t );
|
||||||
while ( ( __line__ = file_get_line( __chars__, __stream ) ) != NULL ) {
|
while((__line__ = file_get_line(__chars__, __stream)) != NULL) {
|
||||||
//comments filter.
|
//comments filter.
|
||||||
if ( __line__[0] == '#' ) continue;
|
if(__line__[0] == '#') continue;
|
||||||
if ( __line__[0] == '\0' ) continue;
|
if(__line__[0] == '\0') continue;
|
||||||
|
|
||||||
__length__ = strlen( __line__ );
|
__length__ = strlen(__line__);
|
||||||
if ( __line__[ __length__ - 1 ] == ']' ) break;
|
if(__line__[ __length__ - 1 ] == ']') break;
|
||||||
|
|
||||||
for ( i = 0; i < __length__
|
for(i = 0; i < __length__
|
||||||
&& ( __line__[i] == ' ' || __line__[i] == '\t' ); i++ );
|
&& (__line__[i] == ' ' || __line__[i] == '\t'); i++);
|
||||||
for ( t = 0; i < __length__; i++,t++ ) {
|
for(t = 0; i < __length__; i++, t++) {
|
||||||
if ( __line__[i] == ' '
|
if(__line__[i] == ' '
|
||||||
|| __line__[i] == '\t' || __line__[i] == ';' ) break;
|
|| __line__[i] == '\t' || __line__[i] == ';') break;
|
||||||
__key__[t] = __line__[i];
|
__key__[t] = __line__[i];
|
||||||
}
|
}
|
||||||
__key__[t] = '\0';
|
__key__[t] = '\0';
|
||||||
|
|
||||||
//load the lexicon item from the lexicon file.
|
//load the lexicon item from the lexicon file.
|
||||||
string_buffer_clear( sb );
|
string_buffer_clear(sb);
|
||||||
string_buffer_append( sb, _path );
|
string_buffer_append(sb, _path);
|
||||||
string_buffer_append( sb, __key__ );
|
string_buffer_append(sb, __key__);
|
||||||
//printf("key=%s, type=%d\n", __key__, lex_t);
|
//printf("key=%s, type=%d\n", __key__, lex_t);
|
||||||
friso_dic_load( friso, config, lex_t, sb->buffer, _limits );
|
friso_dic_load(friso, config, lex_t, sb->buffer, _limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} //end while
|
} //end while
|
||||||
|
|
||||||
fclose( __stream );
|
fclose(__stream);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Warning: Fail to open the lexicon configuration file %s\n", sb->buffer);
|
fprintf(stderr, "Warning: Fail to open the lexicon configuration file %s\n", sb->buffer);
|
||||||
fprintf(stderr, "Warning: Without lexicon file, segment results will not correct \n");
|
fprintf(stderr, "Warning: Without lexicon file, segment results will not correct \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
free_string_buffer(sb);
|
free_string_buffer(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//match the item.
|
//match the item.
|
||||||
FRISO_API int friso_dic_match(
|
FRISO_API int friso_dic_match(
|
||||||
friso_dic_t dic,
|
friso_dic_t dic,
|
||||||
friso_lex_t lex,
|
friso_lex_t lex,
|
||||||
fstring word )
|
fstring word) {
|
||||||
{
|
if(lex >= 0 && lex < __FRISO_LEXICON_LENGTH__) {
|
||||||
if ( lex >= 0 && lex < __FRISO_LEXICON_LENGTH__ ) {
|
return hash_exist_mapping(dic[lex], word);
|
||||||
return hash_exist_mapping( dic[lex], word );
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the lex_entry_t associated with the word.
|
//get the lex_entry_t associated with the word.
|
||||||
FRISO_API lex_entry_t friso_dic_get(
|
FRISO_API lex_entry_t friso_dic_get(
|
||||||
friso_dic_t dic,
|
friso_dic_t dic,
|
||||||
friso_lex_t lex,
|
friso_lex_t lex,
|
||||||
fstring word )
|
fstring word) {
|
||||||
{
|
if(lex >= 0 && lex < __FRISO_LEXICON_LENGTH__) {
|
||||||
if ( lex >= 0 && lex < __FRISO_LEXICON_LENGTH__ ) {
|
return (lex_entry_t) hash_get_value(dic[lex], word);
|
||||||
return ( lex_entry_t ) hash_get_value( dic[lex], word );
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the size of the specified type dictionary.
|
//get the size of the specified type dictionary.
|
||||||
FRISO_API uint_t friso_spec_dic_size(
|
FRISO_API uint_t friso_spec_dic_size(
|
||||||
friso_dic_t dic,
|
friso_dic_t dic,
|
||||||
friso_lex_t lex )
|
friso_lex_t lex) {
|
||||||
{
|
if(lex >= 0 && lex < __FRISO_LEXICON_LENGTH__) {
|
||||||
if ( lex >= 0 && lex < __FRISO_LEXICON_LENGTH__ ) {
|
return hash_get_size(dic[lex]);
|
||||||
return hash_get_size( dic[lex] );
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//get size of the whole dictionary.
|
//get size of the whole dictionary.
|
||||||
FRISO_API uint_t friso_all_dic_size(
|
FRISO_API uint_t friso_all_dic_size(
|
||||||
friso_dic_t dic )
|
friso_dic_t dic) {
|
||||||
{
|
|
||||||
register uint_t size = 0, t;
|
register uint_t size = 0, t;
|
||||||
|
|
||||||
for ( t = 0; t < __FRISO_LEXICON_LENGTH__; t++ ) {
|
for(t = 0; t < __FRISO_LEXICON_LENGTH__; t++) {
|
||||||
size += hash_get_size( dic[t] );
|
size += hash_get_size(dic[t]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
|
@ -10,14 +10,13 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
//create a new link list node.
|
//create a new link list node.
|
||||||
__STATIC_API__ link_node_t new_node_entry(
|
__STATIC_API__ link_node_t new_node_entry(
|
||||||
void * value,
|
void * value,
|
||||||
link_node_t prev,
|
link_node_t prev,
|
||||||
link_node_t next )
|
link_node_t next) {
|
||||||
{
|
link_node_t node = (link_node_t)
|
||||||
link_node_t node = ( link_node_t )
|
FRISO_MALLOC(sizeof(link_node_entry));
|
||||||
FRISO_MALLOC( sizeof( link_node_entry ) );
|
if(node == NULL) {
|
||||||
if ( node == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,17 +28,16 @@ __STATIC_API__ link_node_t new_node_entry(
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a new link list
|
//create a new link list
|
||||||
FRISO_API friso_link_t new_link_list( void )
|
FRISO_API friso_link_t new_link_list(void) {
|
||||||
{
|
friso_link_t e = (friso_link_t)
|
||||||
friso_link_t e = ( friso_link_t )
|
FRISO_MALLOC(sizeof(friso_link_entry));
|
||||||
FRISO_MALLOC( sizeof( friso_link_entry ) );
|
if(e == NULL) {
|
||||||
if ( e == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize the entry
|
//initialize the entry
|
||||||
e->head = new_node_entry( NULL, NULL, NULL );
|
e->head = new_node_entry(NULL, NULL, NULL);
|
||||||
e->tail = new_node_entry( NULL, e->head, NULL );
|
e->tail = new_node_entry(NULL, e->head, NULL);
|
||||||
e->head->next = e->tail;
|
e->head->next = e->tail;
|
||||||
e->size = 0;
|
e->size = 0;
|
||||||
|
|
||||||
|
@ -47,28 +45,25 @@ FRISO_API friso_link_t new_link_list( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
//free the given link list
|
//free the given link list
|
||||||
FRISO_API void free_link_list( friso_link_t link )
|
FRISO_API void free_link_list(friso_link_t link) {
|
||||||
{
|
|
||||||
link_node_t node, next;
|
link_node_t node, next;
|
||||||
for ( node = link->head; node != NULL; ) {
|
for(node = link->head; node != NULL;) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
FRISO_FREE( node );
|
FRISO_FREE(node);
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_FREE( link );
|
FRISO_FREE(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear all nodes in the link list.
|
//clear all nodes in the link list.
|
||||||
FRISO_API friso_link_t link_list_clear(
|
FRISO_API friso_link_t link_list_clear(
|
||||||
friso_link_t link )
|
friso_link_t link) {
|
||||||
{
|
|
||||||
link_node_t node, next;
|
link_node_t node, next;
|
||||||
//free all the middle nodes.
|
//free all the middle nodes.
|
||||||
for ( node = link->head->next; node != link->tail; )
|
for(node = link->head->next; node != link->tail;) {
|
||||||
{
|
|
||||||
next = node->next;
|
next = node->next;
|
||||||
FRISO_FREE( node );
|
FRISO_FREE(node);
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,22 +89,20 @@ FRISO_API friso_link_t link_list_clear(
|
||||||
* find the node at a specified position.
|
* find the node at a specified position.
|
||||||
* static
|
* static
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ link_node_t get_node(
|
__STATIC_API__ link_node_t get_node(
|
||||||
friso_link_t link, uint_t idx )
|
friso_link_t link, uint_t idx) {
|
||||||
{
|
|
||||||
link_node_t p = NULL;
|
link_node_t p = NULL;
|
||||||
register uint_t t;
|
register uint_t t;
|
||||||
|
|
||||||
if ( idx >= 0 && idx < link->size )
|
if(idx >= 0 && idx < link->size) {
|
||||||
{
|
if(idx < link->size / 2) { //find from the head.
|
||||||
if ( idx < link->size / 2 ) { //find from the head.
|
|
||||||
p = link->head;
|
p = link->head;
|
||||||
for ( t = 0; t <= idx; t++ )
|
for(t = 0; t <= idx; t++)
|
||||||
p = p->next;
|
p = p->next;
|
||||||
} else { //find from the tail.
|
} else { //find from the tail.
|
||||||
p = link->tail;
|
p = link->tail;
|
||||||
for ( t = link->size; t > idx; t-- )
|
for(t = link->size; t > idx; t--)
|
||||||
p = p->prev;
|
p = p->prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +113,10 @@ __STATIC_API__ link_node_t get_node(
|
||||||
* insert a node before the given node.
|
* insert a node before the given node.
|
||||||
* static
|
* static
|
||||||
*/
|
*/
|
||||||
//__STATIC_API__ void insert_before(
|
//__STATIC_API__ void insert_before(
|
||||||
// friso_link_t link,
|
// friso_link_t link,
|
||||||
// link_node_t node,
|
// link_node_t node,
|
||||||
// void * value )
|
// void * value )
|
||||||
//{
|
//{
|
||||||
// link_node_t e = new_node_entry( value, node->prev, node );
|
// link_node_t e = new_node_entry( value, node->prev, node );
|
||||||
// e->prev->next = e;
|
// e->prev->next = e;
|
||||||
|
@ -147,48 +140,44 @@ __STATIC_API__ link_node_t get_node(
|
||||||
*
|
*
|
||||||
* @return the value of the removed node.
|
* @return the value of the removed node.
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ void * remove_node(
|
__STATIC_API__ void * remove_node(
|
||||||
friso_link_t link, link_node_t node )
|
friso_link_t link, link_node_t node) {
|
||||||
{
|
|
||||||
void * _value = node->value;
|
void * _value = node->value;
|
||||||
|
|
||||||
node->prev->next = node->next;
|
node->prev->next = node->next;
|
||||||
node->next->prev = node->prev;
|
node->next->prev = node->prev;
|
||||||
link->size--;
|
link->size--;
|
||||||
|
|
||||||
FRISO_FREE( node );
|
FRISO_FREE(node);
|
||||||
|
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//add a new node to the link list.(insert just before the tail)
|
//add a new node to the link list.(insert just before the tail)
|
||||||
FRISO_API void link_list_add(
|
FRISO_API void link_list_add(
|
||||||
friso_link_t link, void * value )
|
friso_link_t link, void * value) {
|
||||||
{
|
insert_before(link, link->tail, value);
|
||||||
insert_before( link, link->tail, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//add a new node before the given index.
|
//add a new node before the given index.
|
||||||
FRISO_API void link_list_insert_before(
|
FRISO_API void link_list_insert_before(
|
||||||
friso_link_t link, uint_t idx, void * value )
|
friso_link_t link, uint_t idx, void * value) {
|
||||||
{
|
link_node_t node = get_node(link, idx);
|
||||||
link_node_t node = get_node( link, idx );
|
if(node != NULL) {
|
||||||
if ( node != NULL ) {
|
insert_before(link, node, value);
|
||||||
insert_before( link, node, value );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the value with the specified node.
|
* get the value with the specified node.
|
||||||
*
|
*
|
||||||
* @return the value of the node.
|
* @return the value of the node.
|
||||||
*/
|
*/
|
||||||
FRISO_API void * link_list_get(
|
FRISO_API void * link_list_get(
|
||||||
friso_link_t link, uint_t idx )
|
friso_link_t link, uint_t idx) {
|
||||||
{
|
link_node_t node = get_node(link, idx);
|
||||||
link_node_t node = get_node( link, idx );
|
if(node != NULL) {
|
||||||
if ( node != NULL ) {
|
|
||||||
return node->value;
|
return node->value;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -198,17 +187,16 @@ FRISO_API void * link_list_get(
|
||||||
* set the value of the node that located in the specified position.
|
* set the value of the node that located in the specified position.
|
||||||
* we did't free the allocation of the old value, we return it to you.
|
* we did't free the allocation of the old value, we return it to you.
|
||||||
* free it yourself when it is necessary.
|
* free it yourself when it is necessary.
|
||||||
*
|
*
|
||||||
* @return the old value.
|
* @return the old value.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *link_list_set(
|
FRISO_API void *link_list_set(
|
||||||
friso_link_t link,
|
friso_link_t link,
|
||||||
uint_t idx, void * value )
|
uint_t idx, void * value) {
|
||||||
{
|
link_node_t node = get_node(link, idx);
|
||||||
link_node_t node = get_node( link, idx );
|
|
||||||
void * _value = NULL;
|
void * _value = NULL;
|
||||||
|
|
||||||
if ( node != NULL ) {
|
if(node != NULL) {
|
||||||
_value = node->value;
|
_value = node->value;
|
||||||
node->value = value;
|
node->value = value;
|
||||||
}
|
}
|
||||||
|
@ -222,14 +210,13 @@ FRISO_API void *link_list_set(
|
||||||
* @see remove_node
|
* @see remove_node
|
||||||
* @return the value of the node removed.
|
* @return the value of the node removed.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *link_list_remove(
|
FRISO_API void *link_list_remove(
|
||||||
friso_link_t link, uint_t idx )
|
friso_link_t link, uint_t idx) {
|
||||||
{
|
link_node_t node = get_node(link, idx);
|
||||||
link_node_t node = get_node( link, idx );
|
|
||||||
|
|
||||||
if ( node != NULL ) {
|
if(node != NULL) {
|
||||||
//printf("idx=%d, node->value=%s\n", idx, (string) node->value );
|
//printf("idx=%d, node->value=%s\n", idx, (string) node->value );
|
||||||
return remove_node( link, node );
|
return remove_node(link, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -237,48 +224,43 @@ FRISO_API void *link_list_remove(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove the given node from the given link list.
|
* remove the given node from the given link list.
|
||||||
*
|
*
|
||||||
* @see remove_node.
|
* @see remove_node.
|
||||||
* @return the value of the node removed.
|
* @return the value of the node removed.
|
||||||
*/
|
*/
|
||||||
FRISO_API void *link_list_remove_node(
|
FRISO_API void *link_list_remove_node(
|
||||||
friso_link_t link,
|
friso_link_t link,
|
||||||
link_node_t node )
|
link_node_t node) {
|
||||||
{
|
return remove_node(link, node);
|
||||||
return remove_node( link, node );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove the first node after the head
|
//remove the first node after the head
|
||||||
FRISO_API void *link_list_remove_first(
|
FRISO_API void *link_list_remove_first(
|
||||||
friso_link_t link )
|
friso_link_t link) {
|
||||||
{
|
if(link->size > 0) {
|
||||||
if ( link->size > 0 ) {
|
return remove_node(link, link->head->next);
|
||||||
return remove_node( link, link->head->next );
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove the last node just before the tail.
|
//remove the last node just before the tail.
|
||||||
FRISO_API void *link_list_remove_last(
|
FRISO_API void *link_list_remove_last(
|
||||||
friso_link_t link )
|
friso_link_t link) {
|
||||||
{
|
if(link->size > 0) {
|
||||||
if ( link->size > 0 ) {
|
return remove_node(link, link->tail->prev);
|
||||||
return remove_node( link, link->tail->prev );
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//append a node from the tail.
|
//append a node from the tail.
|
||||||
FRISO_API void link_list_add_last(
|
FRISO_API void link_list_add_last(
|
||||||
friso_link_t link,
|
friso_link_t link,
|
||||||
void *value )
|
void *value) {
|
||||||
{
|
insert_before(link, link->tail, value);
|
||||||
insert_before( link, link->tail, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//append a note just after the head.
|
//append a note just after the head.
|
||||||
FRISO_API void link_list_add_first(
|
FRISO_API void link_list_add_first(
|
||||||
friso_link_t link, void *value )
|
friso_link_t link, void *value) {
|
||||||
{
|
insert_before(link, link->head->next, value);
|
||||||
insert_before( link, link->head->next, value );
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* utf-8 handle functions implementation.
|
* utf-8 handle functions implementation.
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -21,32 +21,30 @@
|
||||||
*
|
*
|
||||||
* @date: 2014-10-16
|
* @date: 2014-10-16
|
||||||
*/
|
*/
|
||||||
__STATIC_API__ fstring create_buffer( uint_t length )
|
__STATIC_API__ fstring create_buffer(uint_t length) {
|
||||||
{
|
fstring buffer = (fstring) FRISO_MALLOC(length + 1);
|
||||||
fstring buffer = ( fstring ) FRISO_MALLOC( length + 1 );
|
if(buffer == NULL) {
|
||||||
if ( buffer == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
memset( buffer, 0x00, length + 1 );
|
memset(buffer, 0x00, length + 1);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//the __allocs should not be smaller than sb->length
|
//the __allocs should not be smaller than sb->length
|
||||||
__STATIC_API__ string_buffer_t resize_buffer(
|
__STATIC_API__ string_buffer_t resize_buffer(
|
||||||
string_buffer_t sb, uint_t __allocs )
|
string_buffer_t sb, uint_t __allocs) {
|
||||||
{
|
|
||||||
//create a new buffer.
|
//create a new buffer.
|
||||||
//if ( __allocs < sb->length ) __allocs = sb->length + 1;
|
//if ( __allocs < sb->length ) __allocs = sb->length + 1;
|
||||||
fstring str = create_buffer( __allocs );
|
fstring str = create_buffer(__allocs);
|
||||||
|
|
||||||
//register uint_t t;
|
//register uint_t t;
|
||||||
//for ( t = 0; t < sb->length; t++ ) {
|
//for ( t = 0; t < sb->length; t++ ) {
|
||||||
// str[t] = sb->buffer[t];
|
// str[t] = sb->buffer[t];
|
||||||
//}
|
//}
|
||||||
memcpy( str, sb->buffer, sb->length );
|
memcpy(str, sb->buffer, sb->length);
|
||||||
FRISO_FREE( sb->buffer );
|
FRISO_FREE(sb->buffer);
|
||||||
|
|
||||||
sb->buffer = str;
|
sb->buffer = str;
|
||||||
sb->allocs = __allocs;
|
sb->allocs = __allocs;
|
||||||
|
@ -55,21 +53,20 @@ __STATIC_API__ string_buffer_t resize_buffer(
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a new fstring buffer with a default opacity.
|
//create a new fstring buffer with a default opacity.
|
||||||
//FRISO_API string_buffer_t new_string_buffer( void )
|
//FRISO_API string_buffer_t new_string_buffer( void )
|
||||||
//{
|
//{
|
||||||
// return new_string_buffer_with_opacity( __BUFFER_DEFAULT_LENGTH__ );
|
// return new_string_buffer_with_opacity( __BUFFER_DEFAULT_LENGTH__ );
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//create a new fstring buffer with the given opacity.
|
//create a new fstring buffer with the given opacity.
|
||||||
FRISO_API string_buffer_t new_string_buffer_with_opacity( uint_t opacity )
|
FRISO_API string_buffer_t new_string_buffer_with_opacity(uint_t opacity) {
|
||||||
{
|
string_buffer_t sb = (string_buffer_t)
|
||||||
string_buffer_t sb = ( string_buffer_t )
|
FRISO_MALLOC(sizeof(string_buffer_entry));
|
||||||
FRISO_MALLOC( sizeof( string_buffer_entry ) );
|
if(sb == NULL) {
|
||||||
if ( sb == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
sb->buffer = create_buffer( opacity );
|
sb->buffer = create_buffer(opacity);
|
||||||
sb->length = 0;
|
sb->length = 0;
|
||||||
sb->allocs = opacity;
|
sb->allocs = opacity;
|
||||||
|
|
||||||
|
@ -77,18 +74,17 @@ FRISO_API string_buffer_t new_string_buffer_with_opacity( uint_t opacity )
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a buffer with the given string.
|
//create a buffer with the given string.
|
||||||
FRISO_API string_buffer_t new_string_buffer_with_string( fstring str )
|
FRISO_API string_buffer_t new_string_buffer_with_string(fstring str) {
|
||||||
{
|
|
||||||
//buffer allocations.
|
//buffer allocations.
|
||||||
string_buffer_t sb = ( string_buffer_t )
|
string_buffer_t sb = (string_buffer_t)
|
||||||
FRISO_MALLOC( sizeof( string_buffer_entry ) );
|
FRISO_MALLOC(sizeof(string_buffer_entry));
|
||||||
if ( sb == NULL ) {
|
if(sb == NULL) {
|
||||||
___ALLOCATION_ERROR___
|
___ALLOCATION_ERROR___
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize
|
//initialize
|
||||||
sb->length = strlen( str );
|
sb->length = strlen(str);
|
||||||
sb->buffer = create_buffer( sb->length + __BUFFER_DEFAULT_LENGTH__ );
|
sb->buffer = create_buffer(sb->length + __BUFFER_DEFAULT_LENGTH__);
|
||||||
sb->allocs = sb->length + __BUFFER_DEFAULT_LENGTH__;
|
sb->allocs = sb->length + __BUFFER_DEFAULT_LENGTH__;
|
||||||
|
|
||||||
//register uint_t t;
|
//register uint_t t;
|
||||||
|
@ -96,19 +92,18 @@ FRISO_API string_buffer_t new_string_buffer_with_string( fstring str )
|
||||||
//for ( t = 0; t < sb->length; t++ ) {
|
//for ( t = 0; t < sb->length; t++ ) {
|
||||||
// sb->buffer[t] = str[t];
|
// sb->buffer[t] = str[t];
|
||||||
//}
|
//}
|
||||||
memcpy( sb->buffer, str, sb->length );
|
memcpy(sb->buffer, str, sb->length);
|
||||||
|
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void string_buffer_append(
|
FRISO_API void string_buffer_append(
|
||||||
string_buffer_t sb, fstring __str )
|
string_buffer_t sb, fstring __str) {
|
||||||
{
|
register uint_t __len__ = strlen(__str);
|
||||||
register uint_t __len__ = strlen( __str );
|
|
||||||
|
|
||||||
//check the necessity to resize the buffer.
|
//check the necessity to resize the buffer.
|
||||||
if ( sb->length + __len__ > sb->allocs ) {
|
if(sb->length + __len__ > sb->allocs) {
|
||||||
sb = resize_buffer( sb, ( sb->length + __len__ ) * 2 + 1 );
|
sb = resize_buffer(sb, (sb->length + __len__) * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//register uint_t t;
|
//register uint_t t;
|
||||||
|
@ -116,26 +111,24 @@ FRISO_API void string_buffer_append(
|
||||||
//for ( t = 0; t < __len__; t++ ) {
|
//for ( t = 0; t < __len__; t++ ) {
|
||||||
// sb->buffer[ sb->length++ ] = __str[t];
|
// sb->buffer[ sb->length++ ] = __str[t];
|
||||||
//}
|
//}
|
||||||
memcpy( sb->buffer + sb->length, __str, __len__ );
|
memcpy(sb->buffer + sb->length, __str, __len__);
|
||||||
sb->length += __len__;
|
sb->length += __len__;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void string_buffer_append_char(
|
FRISO_API void string_buffer_append_char(
|
||||||
string_buffer_t sb, char ch )
|
string_buffer_t sb, char ch) {
|
||||||
{
|
|
||||||
//check the necessity to resize the buffer.
|
//check the necessity to resize the buffer.
|
||||||
if ( sb->length + 1 > sb->allocs ) {
|
if(sb->length + 1 > sb->allocs) {
|
||||||
sb = resize_buffer( sb, sb->length * 2 + 1 );
|
sb = resize_buffer(sb, sb->length * 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sb->buffer[sb->length++] = ch;
|
sb->buffer[sb->length++] = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void string_buffer_insert(
|
FRISO_API void string_buffer_insert(
|
||||||
string_buffer_t sb,
|
string_buffer_t sb,
|
||||||
uint_t idx,
|
uint_t idx,
|
||||||
fstring __str )
|
fstring __str) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -144,26 +137,25 @@ FRISO_API void string_buffer_insert(
|
||||||
*
|
*
|
||||||
* @return the new string.
|
* @return the new string.
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring string_buffer_remove(
|
FRISO_API fstring string_buffer_remove(
|
||||||
string_buffer_t sb,
|
string_buffer_t sb,
|
||||||
uint_t idx,
|
uint_t idx,
|
||||||
uint_t length )
|
uint_t length) {
|
||||||
{
|
|
||||||
uint_t t;
|
uint_t t;
|
||||||
//move the bytes after the idx + length
|
//move the bytes after the idx + length
|
||||||
for ( t = idx + length; t < sb->length; t++ ) {
|
for(t = idx + length; t < sb->length; t++) {
|
||||||
sb->buffer[t - length] = sb->buffer[t];
|
sb->buffer[t - length] = sb->buffer[t];
|
||||||
}
|
}
|
||||||
sb->buffer[t] = '\0';
|
sb->buffer[t] = '\0';
|
||||||
//memcpy( sb->buffer + idx,
|
//memcpy( sb->buffer + idx,
|
||||||
// sb->buffer + idx + length,
|
// sb->buffer + idx + length,
|
||||||
// sb->length - idx - length );
|
// sb->length - idx - length );
|
||||||
|
|
||||||
t = sb->length - idx;
|
t = sb->length - idx;
|
||||||
if ( t > 0 ) {
|
if(t > 0) {
|
||||||
sb->length -= ( t > length ) ? length : t;
|
sb->length -= (t > length) ? length : t;
|
||||||
}
|
}
|
||||||
sb->buffer[sb->length-1] = '\0';
|
sb->buffer[sb->length - 1] = '\0';
|
||||||
|
|
||||||
return sb->buffer;
|
return sb->buffer;
|
||||||
}
|
}
|
||||||
|
@ -172,25 +164,23 @@ FRISO_API fstring string_buffer_remove(
|
||||||
* turn the string_buffer to a string.
|
* turn the string_buffer to a string.
|
||||||
* or return the buffer of the string_buffer.
|
* or return the buffer of the string_buffer.
|
||||||
*/
|
*/
|
||||||
FRISO_API string_buffer_t string_buffer_trim( string_buffer_t sb )
|
FRISO_API string_buffer_t string_buffer_trim(string_buffer_t sb) {
|
||||||
{
|
|
||||||
//resize the buffer.
|
//resize the buffer.
|
||||||
if ( sb->length < sb->allocs - 1 ) {
|
if(sb->length < sb->allocs - 1) {
|
||||||
sb = resize_buffer( sb, sb->length + 1 );
|
sb = resize_buffer(sb, sb->length + 1);
|
||||||
}
|
}
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free the given fstring buffer.
|
* free the given fstring buffer.
|
||||||
* and this function will not free the allocations of the
|
* and this function will not free the allocations of the
|
||||||
* string_buffer_t->buffer, we return it to you, if there is
|
* string_buffer_t->buffer, we return it to you, if there is
|
||||||
* a necessary you could free it youself by calling free();
|
* a necessary you could free it youself by calling free();
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring string_buffer_devote( string_buffer_t sb )
|
FRISO_API fstring string_buffer_devote(string_buffer_t sb) {
|
||||||
{
|
|
||||||
fstring buffer = sb->buffer;
|
fstring buffer = sb->buffer;
|
||||||
FRISO_FREE( sb );
|
FRISO_FREE(sb);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,17 +188,15 @@ FRISO_API fstring string_buffer_devote( string_buffer_t sb )
|
||||||
* clear the given fstring buffer.
|
* clear the given fstring buffer.
|
||||||
* reset its buffer with 0 and reset its length to 0.
|
* reset its buffer with 0 and reset its length to 0.
|
||||||
*/
|
*/
|
||||||
FRISO_API void string_buffer_clear( string_buffer_t sb )
|
FRISO_API void string_buffer_clear(string_buffer_t sb) {
|
||||||
{
|
memset(sb->buffer, 0x00, sb->length);
|
||||||
memset( sb->buffer, 0x00, sb->length );
|
|
||||||
sb->length = 0;
|
sb->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//free everything of the fstring buffer.
|
//free everything of the fstring buffer.
|
||||||
FRISO_API void free_string_buffer( string_buffer_t sb )
|
FRISO_API void free_string_buffer(string_buffer_t sb) {
|
||||||
{
|
FRISO_FREE(sb->buffer);
|
||||||
FRISO_FREE( sb->buffer );
|
FRISO_FREE(sb);
|
||||||
FRISO_FREE( sb );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,15 +204,14 @@ FRISO_API void free_string_buffer( string_buffer_t sb )
|
||||||
* create a new string_split_entry.
|
* create a new string_split_entry.
|
||||||
*
|
*
|
||||||
* @param source
|
* @param source
|
||||||
* @return string_split_t;
|
* @return string_split_t;
|
||||||
*/
|
*/
|
||||||
FRISO_API string_split_t new_string_split(
|
FRISO_API string_split_t new_string_split(
|
||||||
fstring delimiter,
|
fstring delimiter,
|
||||||
fstring source )
|
fstring source) {
|
||||||
{
|
string_split_t e = (string_split_t)
|
||||||
string_split_t e = ( string_split_t )
|
FRISO_MALLOC(sizeof(string_split_entry));
|
||||||
FRISO_MALLOC( sizeof( string_split_entry ) );
|
if(e == NULL) {
|
||||||
if ( e == NULL ) {
|
|
||||||
___ALLOCATION_ERROR___;
|
___ALLOCATION_ERROR___;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,70 +224,65 @@ FRISO_API string_split_t new_string_split(
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void string_split_reset(
|
FRISO_API void string_split_reset(
|
||||||
string_split_t sst,
|
string_split_t sst,
|
||||||
fstring delimiter,
|
fstring delimiter,
|
||||||
fstring source )
|
fstring source) {
|
||||||
{
|
|
||||||
sst->delimiter = delimiter;
|
sst->delimiter = delimiter;
|
||||||
sst->delLen = strlen(delimiter);
|
sst->delLen = strlen(delimiter);
|
||||||
sst->source = source;
|
|
||||||
sst->srcLen = strlen(source);
|
|
||||||
sst->idx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FRISO_API void string_split_set_source(
|
|
||||||
string_split_t sst, fstring source )
|
|
||||||
{
|
|
||||||
sst->source = source;
|
sst->source = source;
|
||||||
sst->srcLen = strlen(source);
|
sst->srcLen = strlen(source);
|
||||||
sst->idx = 0;
|
sst->idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void string_split_set_delimiter(
|
FRISO_API void string_split_set_source(
|
||||||
string_split_t sst, fstring delimiter )
|
string_split_t sst, fstring source) {
|
||||||
{
|
sst->source = source;
|
||||||
sst->delimiter = delimiter;
|
sst->srcLen = strlen(source);
|
||||||
sst->delLen = strlen( delimiter );
|
|
||||||
sst->idx = 0;
|
sst->idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRISO_API void free_string_split( string_split_t sst )
|
FRISO_API void string_split_set_delimiter(
|
||||||
{
|
string_split_t sst, fstring delimiter) {
|
||||||
|
sst->delimiter = delimiter;
|
||||||
|
sst->delLen = strlen(delimiter);
|
||||||
|
sst->idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FRISO_API void free_string_split(string_split_t sst) {
|
||||||
FRISO_FREE(sst);
|
FRISO_FREE(sst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the next split fstring, and copy the
|
* get the next split fstring, and copy the
|
||||||
* splited fstring into the __dst buffer .
|
* splited fstring into the __dst buffer .
|
||||||
*
|
*
|
||||||
* @param string_split_t
|
* @param string_split_t
|
||||||
* @param __dst
|
* @param __dst
|
||||||
* @return fstring (NULL if reach the end of the source
|
* @return fstring (NULL if reach the end of the source
|
||||||
* or there is no more segmentation)
|
* or there is no more segmentation)
|
||||||
*/
|
*/
|
||||||
FRISO_API fstring string_split_next(
|
FRISO_API fstring string_split_next(
|
||||||
string_split_t sst, fstring __dst)
|
string_split_t sst, fstring __dst) {
|
||||||
{
|
|
||||||
uint_t i, _ok;
|
uint_t i, _ok;
|
||||||
fstring _dst = __dst;
|
fstring _dst = __dst;
|
||||||
|
|
||||||
//check if reach the end of the fstring
|
//check if reach the end of the fstring
|
||||||
if ( sst->idx >= sst->srcLen ) return NULL;
|
if(sst->idx >= sst->srcLen) return NULL;
|
||||||
|
|
||||||
while ( 1 ) {
|
while(1) {
|
||||||
_ok = 1;
|
_ok = 1;
|
||||||
for ( i = 0; i < sst->delLen
|
for(i = 0; i < sst->delLen
|
||||||
&& (sst->idx + i < sst->srcLen); i++ ) {
|
&& (sst->idx + i < sst->srcLen); i++) {
|
||||||
if ( sst->source[sst->idx+i] != sst->delimiter[i] ) {
|
if(sst->source[sst->idx + i] != sst->delimiter[i]) {
|
||||||
_ok = 0;
|
_ok = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find the delimiter here,
|
//find the delimiter here,
|
||||||
//break the loop and self plus the sst->idx, then return the buffer .
|
//break the loop and self plus the sst->idx, then return the buffer .
|
||||||
if ( _ok == 1 ) {
|
if(_ok == 1) {
|
||||||
sst->idx += sst->delLen;
|
sst->idx += sst->delLen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +290,7 @@ FRISO_API fstring string_split_next(
|
||||||
//coy the char to the buffer
|
//coy the char to the buffer
|
||||||
*_dst++ = sst->source[sst->idx++];
|
*_dst++ = sst->source[sst->idx++];
|
||||||
//check if reach the end of the fstring
|
//check if reach the end of the fstring
|
||||||
if ( sst->idx >= sst->srcLen ) break;
|
if(sst->idx >= sst->srcLen) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*_dst = '\0';
|
*_dst = '\0';
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main( int argc, char **args ) {
|
int main(int argc, char **args) {
|
||||||
|
|
||||||
//create a new array list.
|
//create a new array list.
|
||||||
friso_array_t array = new_array_list();
|
friso_array_t array = new_array_list();
|
||||||
fstring keys[] = {
|
fstring keys[] = {
|
||||||
"chenmanwen", "yangqinghua",
|
"chenmanwen", "yangqinghua",
|
||||||
"chenxin", "luojiangyan", "xiaoyanzi", "bibi",
|
"chenxin", "luojiangyan", "xiaoyanzi", "bibi",
|
||||||
|
@ -20,31 +20,31 @@ int main( int argc, char **args ) {
|
||||||
"chenpei", "liheng", "zhangzhigang", "zhgangyishao", "yangjiangbo",
|
"chenpei", "liheng", "zhangzhigang", "zhgangyishao", "yangjiangbo",
|
||||||
"caizaili", "panpan", "xiaolude", "yintanwen"
|
"caizaili", "panpan", "xiaolude", "yintanwen"
|
||||||
};
|
};
|
||||||
int j, idx = 2, len = sizeof( keys ) / sizeof( fstring );
|
int j, idx = 2, len = sizeof(keys) / sizeof(fstring);
|
||||||
|
|
||||||
for ( j = 0; j < len; j++ ) {
|
for(j = 0; j < len; j++) {
|
||||||
array_list_add( array, keys[j] );
|
array_list_add(array, keys[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("length=%d, allocations=%d\n", array->length, array->allocs );
|
printf("length=%d, allocations=%d\n", array->length, array->allocs);
|
||||||
array_list_trim( array );
|
array_list_trim(array);
|
||||||
printf("after tirm length=%d, allocations=%d\n", array->length, array->allocs );
|
printf("after tirm length=%d, allocations=%d\n", array->length, array->allocs);
|
||||||
printf("idx=%d, value=%s\n", idx, ( fstring ) array_list_get( array, idx ) );
|
printf("idx=%d, value=%s\n", idx, (fstring) array_list_get(array, idx));
|
||||||
|
|
||||||
printf("\nAfter set %dth item.\n", idx );
|
printf("\nAfter set %dth item.\n", idx);
|
||||||
array_list_set( array, idx, "chenxin__" );
|
array_list_set(array, idx, "chenxin__");
|
||||||
printf("idx=%d, value=%s\n", idx, ( fstring ) array_list_get( array, idx ) );
|
printf("idx=%d, value=%s\n", idx, (fstring) array_list_get(array, idx));
|
||||||
|
|
||||||
printf("\nAfter remove %dth item.\n", idx );
|
printf("\nAfter remove %dth item.\n", idx);
|
||||||
array_list_remove( array, idx );
|
array_list_remove(array, idx);
|
||||||
printf("length=%d, allocations=%d\n", array->length, array->allocs );
|
printf("length=%d, allocations=%d\n", array->length, array->allocs);
|
||||||
printf("idx=%d, value=%s\n", idx, ( fstring ) array_list_get( array, idx ) );
|
printf("idx=%d, value=%s\n", idx, (fstring) array_list_get(array, idx));
|
||||||
|
|
||||||
printf("\nInsert a item at %dth\n", idx );
|
printf("\nInsert a item at %dth\n", idx);
|
||||||
array_list_insert( array, idx, "*chenxin*" );
|
array_list_insert(array, idx, "*chenxin*");
|
||||||
printf("idx=%d, value=%s\n", idx, ( fstring ) array_list_get( array, idx ) );
|
printf("idx=%d, value=%s\n", idx, (fstring) array_list_get(array, idx));
|
||||||
|
|
||||||
free_array_list( array );
|
free_array_list(array);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,19 +32,18 @@ break;
|
||||||
println("+---------------------------------------------------------------+");
|
println("+---------------------------------------------------------------+");
|
||||||
|
|
||||||
//read a line from a command line.
|
//read a line from a command line.
|
||||||
static fstring getLine( FILE *fp, fstring __dst )
|
static fstring getLine(FILE *fp, fstring __dst) {
|
||||||
{
|
|
||||||
register int c;
|
register int c;
|
||||||
register fstring cs;
|
register fstring cs;
|
||||||
|
|
||||||
cs = __dst;
|
cs = __dst;
|
||||||
while ( ( c = getc( fp ) ) != EOF ) {
|
while((c = getc(fp)) != EOF) {
|
||||||
if ( c == '\n' ) break;
|
if(c == '\n') break;
|
||||||
*cs++ = c;
|
*cs++ = c;
|
||||||
}
|
}
|
||||||
*cs = '\0';
|
*cs = '\0';
|
||||||
|
|
||||||
return ( c == EOF && cs == __dst ) ? NULL : __dst;
|
return (c == EOF && cs == __dst) ? NULL : __dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static void printcode( fstring str ) {
|
/*static void printcode( fstring str ) {
|
||||||
|
@ -57,8 +56,7 @@ static fstring getLine( FILE *fp, fstring __dst )
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
|
|
||||||
clock_t s_time, e_time;
|
clock_t s_time, e_time;
|
||||||
char line[__INPUT_LENGTH__] = {0};
|
char line[__INPUT_LENGTH__] = {0};
|
||||||
|
@ -70,13 +68,13 @@ int main(int argc, char **argv)
|
||||||
friso_task_t task;
|
friso_task_t task;
|
||||||
|
|
||||||
// get the lexicon directory from command line arguments
|
// get the lexicon directory from command line arguments
|
||||||
for ( i = 0; i < argc; i++ ) {
|
for(i = 0; i < argc; i++) {
|
||||||
if ( strcasecmp( "-init", argv[i] ) == 0 ) {
|
if(strcasecmp("-init", argv[i]) == 0) {
|
||||||
__path__ = argv[i+1];
|
__path__ = argv[i + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( __path__ == NULL ) {
|
if(__path__ == NULL) {
|
||||||
println("Usage: friso -init lexicon path");
|
println("Usage: friso -init lexicon path");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -90,12 +88,12 @@ int main(int argc, char **argv)
|
||||||
friso_dic_load_from_ifile( dic, __path__, __LENGTH__ );
|
friso_dic_load_from_ifile( dic, __path__, __LENGTH__ );
|
||||||
friso_set_dic( friso, dic );
|
friso_set_dic( friso, dic );
|
||||||
friso_set_mode( friso, __FRISO_COMPLEX_MODE__ );*/
|
friso_set_mode( friso, __FRISO_COMPLEX_MODE__ );*/
|
||||||
if ( friso_init_from_ifile(friso, config, __path__) != 1 ) {
|
if(friso_init_from_ifile(friso, config, __path__) != 1) {
|
||||||
printf("fail to initialize friso and config.\n");
|
printf("fail to initialize friso and config.\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( config->mode ) {
|
switch(config->mode) {
|
||||||
case __FRISO_SIMPLE_MODE__:
|
case __FRISO_SIMPLE_MODE__:
|
||||||
mode = "Simple";
|
mode = "Simple";
|
||||||
break;
|
break;
|
||||||
|
@ -114,41 +112,41 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
|
|
||||||
printf("Initialized in %fsec\n", (double) ( e_time - s_time ) / CLOCKS_PER_SEC );
|
printf("Initialized in %fsec\n", (double)(e_time - s_time) / CLOCKS_PER_SEC);
|
||||||
printf("Mode: %s\n", mode);
|
printf("Mode: %s\n", mode);
|
||||||
printf("+-Version: %s (%s)\n", friso_version(), friso->charset == FRISO_UTF8 ? "UTF-8" : "GBK" );
|
printf("+-Version: %s (%s)\n", friso_version(), friso->charset == FRISO_UTF8 ? "UTF-8" : "GBK");
|
||||||
___ABOUT___;
|
___ABOUT___;
|
||||||
|
|
||||||
//set the task.
|
//set the task.
|
||||||
task = friso_new_task();
|
task = friso_new_task();
|
||||||
|
|
||||||
while ( 1 ) {
|
while(1) {
|
||||||
print("friso>> ");
|
print("friso>> ");
|
||||||
getLine( stdin, line );
|
getLine(stdin, line);
|
||||||
//exit the programe
|
//exit the programe
|
||||||
if (strcasecmp( line, "quit") == 0) {
|
if(strcasecmp(line, "quit") == 0) {
|
||||||
___EXIT_INFO___
|
___EXIT_INFO___
|
||||||
}
|
}
|
||||||
|
|
||||||
//for ( i = 0; i < 1000000; i++ ) {
|
//for ( i = 0; i < 1000000; i++ ) {
|
||||||
//set the task text.
|
//set the task text.
|
||||||
friso_set_text( task, line );
|
friso_set_text(task, line);
|
||||||
println("分词结果:");
|
println("分词结果:");
|
||||||
|
|
||||||
s_time = clock();
|
s_time = clock();
|
||||||
while ( ( config->next_token( friso, config, task ) ) != NULL ) {
|
while((config->next_token(friso, config, task)) != NULL) {
|
||||||
printf(
|
printf(
|
||||||
"%s[%d, %d, %d] ",
|
"%s[%d, %d, %d] ",
|
||||||
task->token->word,
|
task->token->word,
|
||||||
task->token->offset,
|
task->token->offset,
|
||||||
task->token->length,
|
task->token->length,
|
||||||
task->token->rlen
|
task->token->rlen
|
||||||
);
|
);
|
||||||
// printf("%s ", task->token->word);
|
// printf("%s ", task->token->word);
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
printf("\nDone, cost < %fsec\n", ( (double)(e_time - s_time) ) / CLOCKS_PER_SEC );
|
printf("\nDone, cost < %fsec\n", ((double)(e_time - s_time)) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
/**
|
/**
|
||||||
* hashmap testing program
|
* hashmap testing program
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "friso_API.h"
|
#include "friso_API.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void print_hash_info( friso_hash_t _hash ) {
|
void print_hash_info(friso_hash_t _hash) {
|
||||||
printf("info:length=%d, size=%d, facotr=%f, threshold=%d\n", _hash->length, \
|
printf("info:length=%d, size=%d, facotr=%f, threshold=%d\n", _hash->length, \
|
||||||
_hash->size, _hash->factor, _hash->threshold);
|
_hash->size, _hash->factor, _hash->threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
friso_hash_t _hash = new_hash_table();
|
friso_hash_t _hash = new_hash_table();
|
||||||
char *names[] = {
|
char *names[] = {
|
||||||
"陈满文", "阳清华",
|
"陈满文", "阳清华",
|
||||||
|
@ -31,13 +30,13 @@ int main(int argc, char **argv)
|
||||||
"周安", "郭桥安",
|
"周安", "郭桥安",
|
||||||
"刘敏", "黄广华",
|
"刘敏", "黄广华",
|
||||||
"李胜", "黄海清"
|
"李胜", "黄海清"
|
||||||
};
|
};
|
||||||
//char *str[] = {"陈鑫", "张仁芳", "比比"};
|
//char *str[] = {"陈鑫", "张仁芳", "比比"};
|
||||||
char **str = names;
|
char **str = names;
|
||||||
int j, len = 30;
|
int j, len = 30;
|
||||||
|
|
||||||
print_hash_info( _hash );
|
print_hash_info(_hash);
|
||||||
for (j = 0; j < len; j++) {
|
for(j = 0; j < len; j++) {
|
||||||
hash_put_mapping(_hash, names[j], names[j]);
|
hash_put_mapping(_hash, names[j], names[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ int main(int argc, char **argv)
|
||||||
getchar();
|
getchar();
|
||||||
|
|
||||||
//remove mappings
|
//remove mappings
|
||||||
for (j = 0; j < len; j++) {
|
for(j = 0; j < len; j++) {
|
||||||
printf("Exist %s?%2d\n", str[j], hash_exist_mapping(_hash, str[j]));
|
printf("Exist %s?%2d\n", str[j], hash_exist_mapping(_hash, str[j]));
|
||||||
printf("Now, remove %s\n", str[j]);
|
printf("Now, remove %s\n", str[j]);
|
||||||
hash_remove_mapping(_hash, str[j]);
|
hash_remove_mapping(_hash, str[j]);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* lex functions test program.
|
* lex functions test program.
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@
|
||||||
printf("3. other search the words in the dictionary.\n"); \
|
printf("3. other search the words in the dictionary.\n"); \
|
||||||
printf("4. quit exit the programe.\n");
|
printf("4. quit exit the programe.\n");
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
lex_entry_t e;
|
lex_entry_t e;
|
||||||
int lex = __LEX_CJK_WORDS__;
|
int lex = __LEX_CJK_WORDS__;
|
||||||
char _line[__LENGTH__];
|
char _line[__LENGTH__];
|
||||||
|
@ -59,42 +58,42 @@ int main(int argc, char **argv)
|
||||||
//__CN_DNAME2__
|
//__CN_DNAME2__
|
||||||
friso_dic_load(friso, config, __LEX_CN_DNAME2__, "../vendors/dict/UTF-8/lex-dname-2.lex", __LENGTH__);
|
friso_dic_load(friso, config, __LEX_CN_DNAME2__, "../vendors/dict/UTF-8/lex-dname-2.lex", __LENGTH__);
|
||||||
//__CN_LNA__
|
//__CN_LNA__
|
||||||
friso_dic_load(friso, config, __LEX_CN_LNA__, "../vendors/dict/UTF-8/lex-ln-adorn.lex", __LENGTH__ );
|
friso_dic_load(friso, config, __LEX_CN_LNA__, "../vendors/dict/UTF-8/lex-ln-adorn.lex", __LENGTH__);
|
||||||
|
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
printf(
|
printf(
|
||||||
"Done, cost: %f sec, size=%d\n",
|
"Done, cost: %f sec, size=%d\n",
|
||||||
(double) (e_time - s_time) / CLOCKS_PER_SEC,
|
(double)(e_time - s_time) / CLOCKS_PER_SEC,
|
||||||
friso_all_dic_size(friso->dic)
|
friso_all_dic_size(friso->dic)
|
||||||
);
|
);
|
||||||
|
|
||||||
while (1) {
|
while(1) {
|
||||||
printf("friso-%d>> ", lex);
|
printf("friso-%d>> ", lex);
|
||||||
if (scanf("%s", _line) != 1) {
|
if(scanf("%s", _line) != 1) {
|
||||||
printf("Invalid input\n");
|
printf("Invalid input\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp( _line, "quit" ) == 0) {
|
if(strcmp(_line, "quit") == 0) {
|
||||||
break;
|
break;
|
||||||
} else if ( strcmp(_line, "help") == 0 ) {
|
} else if(strcmp(_line, "help") == 0) {
|
||||||
___PRINT_HELP_INFO___
|
___PRINT_HELP_INFO___
|
||||||
} else if ( strcmp( _line, "#set" ) == 0 ) {
|
} else if(strcmp(_line, "#set") == 0) {
|
||||||
printf("lex_t>> ");
|
printf("lex_t>> ");
|
||||||
if (scanf("%d", &lex) != 1) {
|
if(scanf("%d", &lex) != 1) {
|
||||||
printf("Warning: Invalid lex type input\n");
|
printf("Warning: Invalid lex type input\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s_time = clock();
|
s_time = clock();
|
||||||
e = friso_dic_get( friso->dic, lex, _line );
|
e = friso_dic_get(friso->dic, lex, _line);
|
||||||
e_time = clock();
|
e_time = clock();
|
||||||
if (e != NULL) {
|
if(e != NULL) {
|
||||||
printf(
|
printf(
|
||||||
"word=%s, syn=%s, fre=%d, cost:%fsec\n",
|
"word=%s, syn=%s, fre=%d, cost:%fsec\n",
|
||||||
e->word, e->syn==NULL? "NULL" : (char *)e->syn->items[0],
|
e->word, e->syn == NULL ? "NULL" : (char *)e->syn->items[0],
|
||||||
e->fre,
|
e->fre,
|
||||||
(double) (e_time - s_time) / CLOCKS_PER_SEC
|
(double)(e_time - s_time) / CLOCKS_PER_SEC
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
printf("%s was not found.\n", _line);
|
printf("%s was not found.\n", _line);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* link list test programe.
|
* link list test programe.
|
||||||
*
|
*
|
||||||
* @author lionsoul<chenxin619315@gmail.com>
|
* @author lionsoul<chenxin619315@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main( int argc, char **args ) {
|
int main(int argc, char **args) {
|
||||||
|
|
||||||
friso_link_t link;
|
friso_link_t link;
|
||||||
fstring keys[] = {
|
fstring keys[] = {
|
||||||
|
@ -19,32 +19,32 @@ int main( int argc, char **args ) {
|
||||||
"chenpei", "liheng", "zhangzhigang", "zhgangyishao", "yangjiangbo",
|
"chenpei", "liheng", "zhangzhigang", "zhgangyishao", "yangjiangbo",
|
||||||
"caizaili", "panpan", "xiaolude", "yintanwen"
|
"caizaili", "panpan", "xiaolude", "yintanwen"
|
||||||
};
|
};
|
||||||
int j, len = sizeof( keys ) / sizeof( fstring );
|
int j, len = sizeof(keys) / sizeof(fstring);
|
||||||
|
|
||||||
link = new_link_list();
|
link = new_link_list();
|
||||||
|
|
||||||
//print the size of the link
|
//print the size of the link
|
||||||
printf("size=%d\n", link->size );
|
printf("size=%d\n", link->size);
|
||||||
|
|
||||||
for ( j = 0; j < len; j++ ) {
|
for(j = 0; j < len; j++) {
|
||||||
//link_add( link, keys[j] );
|
//link_add( link, keys[j] );
|
||||||
link_list_add_last( link, keys[j] );
|
link_list_add_last(link, keys[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("size=%d\n", link->size );
|
printf("size=%d\n", link->size);
|
||||||
|
|
||||||
for ( j = 0; j < len / 2; j++ ) {
|
for(j = 0; j < len / 2; j++) {
|
||||||
//printf("idx=%d, remove %s\n", j, ( fstring ) link_remove( link, 0 ) );
|
//printf("idx=%d, remove %s\n", j, ( fstring ) link_remove( link, 0 ) );
|
||||||
printf("idx=%d, remove %s\n", j, ( fstring ) link_list_remove_first( link ) );
|
printf("idx=%d, remove %s\n", j, (fstring) link_list_remove_first(link));
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("size=%d\n", link->size );
|
printf("size=%d\n", link->size);
|
||||||
|
|
||||||
//clear all the nodes
|
//clear all the nodes
|
||||||
link_list_clear( link );
|
link_list_clear(link);
|
||||||
printf("size=%d, head->next->value=%s\n", link->size, ( fstring ) link->head->next->value );
|
printf("size=%d, head->next->value=%s\n", link->size, (fstring) link->head->next->value);
|
||||||
|
|
||||||
free_link_list( link );
|
free_link_list(link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main ( int argc, char **args )
|
int main(int argc, char **args) {
|
||||||
{
|
fstring source = ",I am a chinese,,my name is Lion,and i am the author of friso,bug report email chenxin619315@gmail.com,qq:1187582057";
|
||||||
fstring source = ",I am a chinese,,my name is Lion,and i am the author of friso,bug report email chenxin619315@gmail.com,qq:1187582057";
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
string_split_t split = new_string_split(",", source );
|
string_split_t split = new_string_split(",", source);
|
||||||
|
|
||||||
printf("sst->idx=%d\n", split->idx);
|
printf("sst->idx=%d\n", split->idx);
|
||||||
printf("sst->srcLen=%d\n", split->srcLen);
|
printf("sst->srcLen=%d\n", split->srcLen);
|
||||||
printf("sst->delLen=%d\n", split->delLen);
|
printf("sst->delLen=%d\n", split->delLen);
|
||||||
|
|
||||||
while ( string_split_next(split, buffer) != NULL) {
|
while(string_split_next(split, buffer) != NULL) {
|
||||||
printf("buffer:%s\n", buffer);
|
printf("buffer:%s\n", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,39 +9,39 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int main( int argc, char **args ) {
|
int main(int argc, char **args) {
|
||||||
|
|
||||||
fstring str = "康熙字典部首, 符号和标点, 统一表意符号扩展 A ,CJK㈩兼Ⅱ容形式⑩.";
|
fstring str = "康熙字典部首, 符号和标点, 统一表意符号扩展 A ,CJK㈩兼Ⅱ容形式⑩.";
|
||||||
char word[4];
|
char word[4];
|
||||||
int bytes, t, j, length = strlen( str );
|
int bytes, t, j, length = strlen(str);
|
||||||
string_buffer_t sb = new_string_buffer();
|
string_buffer_t sb = new_string_buffer();
|
||||||
|
|
||||||
printf("str=%s, length=%d\n", str, length );
|
printf("str=%s, length=%d\n", str, length);
|
||||||
|
|
||||||
|
|
||||||
for (t = 0; t < length; t += bytes) {
|
for(t = 0; t < length; t += bytes) {
|
||||||
bytes = get_utf8_bytes(*(str + t));
|
bytes = get_utf8_bytes(*(str + t));
|
||||||
if ( bytes == 0 ) {
|
if(bytes == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = 0; j < bytes; j++ ) {
|
for(j = 0; j < bytes; j++) {
|
||||||
word[j] = *(str + t + j );
|
word[j] = *(str + t + j);
|
||||||
}
|
}
|
||||||
|
|
||||||
word[j] = '\0';
|
word[j] = '\0';
|
||||||
string_buffer_append( sb, word );
|
string_buffer_append(sb, word);
|
||||||
printf("word=%s\n", word );
|
printf("word=%s\n", word);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("length=%d, buffer=%s\n", sb->length, sb->buffer );
|
printf("length=%d, buffer=%s\n", sb->length, sb->buffer);
|
||||||
string_buffer_remove( sb, 0, 3 );
|
string_buffer_remove(sb, 0, 3);
|
||||||
printf("length=%d, buffer=%s\n", sb->length, sb->buffer );
|
printf("length=%d, buffer=%s\n", sb->length, sb->buffer);
|
||||||
string_buffer_remove( sb, 0, 3 );
|
string_buffer_remove(sb, 0, 3);
|
||||||
printf("length=%d, buffer=%s\n", sb->length, sb->buffer );
|
printf("length=%d, buffer=%s\n", sb->length, sb->buffer);
|
||||||
string_buffer_remove( sb, sb->length - 3, 6 );
|
string_buffer_remove(sb, sb->length - 3, 6);
|
||||||
sb = string_buffer_trim( sb );
|
sb = string_buffer_trim(sb);
|
||||||
printf("length=%d, buffer=%s\n", sb->length, string_buffer_devote( sb ) );
|
printf("length=%d, buffer=%s\n", sb->length, string_buffer_devote(sb));
|
||||||
|
|
||||||
//00011110 - yuan ma
|
//00011110 - yuan ma
|
||||||
//11100001 - fa ma
|
//11100001 - fa ma
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
|
|
||||||
static AppMatch *app_match_Class = nullptr;
|
static AppMatch *app_match_Class = nullptr;
|
||||||
|
|
||||||
AppMatch *AppMatch::getAppMatch()
|
AppMatch *AppMatch::getAppMatch() {
|
||||||
{
|
if(!app_match_Class) {
|
||||||
if (!app_match_Class) {
|
|
||||||
app_match_Class = new AppMatch;
|
app_match_Class = new AppMatch;
|
||||||
}
|
}
|
||||||
return app_match_Class;
|
return app_match_Class;
|
||||||
|
@ -33,141 +32,130 @@ AppMatch *AppMatch::getAppMatch()
|
||||||
AppMatch::AppMatch(QObject *parent) : QThread(parent)
|
AppMatch::AppMatch(QObject *parent) : QThread(parent)
|
||||||
// m_versionCommand(new QProcess(this))
|
// m_versionCommand(new QProcess(this))
|
||||||
{
|
{
|
||||||
m_watchAppDir=new QFileSystemWatcher(this);
|
m_watchAppDir = new QFileSystemWatcher(this);
|
||||||
m_watchAppDir->addPath("/usr/share/applications/");
|
m_watchAppDir->addPath("/usr/share/applications/");
|
||||||
QDir androidPath(QDir::homePath()+"/.local/share/applications/");
|
QDir androidPath(QDir::homePath() + "/.local/share/applications/");
|
||||||
if(androidPath.exists()){
|
if(androidPath.exists()) {
|
||||||
m_watchAppDir->addPath(QDir::homePath()+"/.local/share/applications/");
|
m_watchAppDir->addPath(QDir::homePath() + "/.local/share/applications/");
|
||||||
}
|
}
|
||||||
qDBusRegisterMetaType<QMap<QString,QString>>();
|
qDBusRegisterMetaType<QMap<QString, QString>>();
|
||||||
qDBusRegisterMetaType<QList<QMap<QString,QString>>>();
|
qDBusRegisterMetaType<QList<QMap<QString, QString>>>();
|
||||||
m_interFace=new QDBusInterface ("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults",
|
m_interFace = new QDBusInterface("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults",
|
||||||
"com.kylin.getsearchresults",
|
"com.kylin.getsearchresults",
|
||||||
QDBusConnection::sessionBus());
|
QDBusConnection::sessionBus());
|
||||||
if (!m_interFace->isValid())
|
if(!m_interFace->isValid()) {
|
||||||
{
|
|
||||||
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
|
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
|
||||||
}
|
}
|
||||||
qDebug()<<"AppMatch is new";
|
qDebug() << "AppMatch is new";
|
||||||
}
|
}
|
||||||
|
|
||||||
AppMatch::~AppMatch(){
|
AppMatch::~AppMatch() {
|
||||||
if(m_interFace){
|
if(m_interFace) {
|
||||||
delete m_interFace;
|
delete m_interFace;
|
||||||
}
|
}
|
||||||
m_interFace=NULL;
|
m_interFace = NULL;
|
||||||
if(m_watchAppDir){
|
if(m_watchAppDir) {
|
||||||
delete m_watchAppDir;
|
delete m_watchAppDir;
|
||||||
}
|
}
|
||||||
m_watchAppDir=NULL;
|
m_watchAppDir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::startMatchApp(QString input,QMap<NameString,QStringList> &installed,QMap<NameString,QStringList> &softwarereturn){
|
void AppMatch::startMatchApp(QString input, QMap<NameString, QStringList> &installed, QMap<NameString, QStringList> &softwarereturn) {
|
||||||
m_sourceText=input;
|
m_sourceText = input;
|
||||||
getAppName(installed);
|
getAppName(installed);
|
||||||
softWareCenterSearch(softwarereturn);
|
softWareCenterSearch(softwarereturn);
|
||||||
qDebug()<<"match app is successful!";
|
qDebug() << "match app is successful!";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief AppMatch::getAllDesktopFilePath 遍历所有desktop文件
|
* @brief AppMatch::getAllDesktopFilePath 遍历所有desktop文件
|
||||||
* @param path 存放desktop文件夹
|
* @param path 存放desktop文件夹
|
||||||
*/
|
*/
|
||||||
void AppMatch::getAllDesktopFilePath(QString path){
|
void AppMatch::getAllDesktopFilePath(QString path) {
|
||||||
|
|
||||||
char* name;
|
char* name;
|
||||||
char* icon;
|
char* icon;
|
||||||
QStringList applist;
|
QStringList applist;
|
||||||
|
|
||||||
GKeyFileFlags flags=G_KEY_FILE_NONE;
|
GKeyFileFlags flags = G_KEY_FILE_NONE;
|
||||||
GKeyFile* keyfile=g_key_file_new ();
|
GKeyFile* keyfile = g_key_file_new();
|
||||||
|
|
||||||
QDir dir(path);
|
QDir dir(path);
|
||||||
if (!dir.exists()) {
|
if(!dir.exists()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||||
dir.setSorting(QDir::DirsFirst);
|
dir.setSorting(QDir::DirsFirst);
|
||||||
QFileInfoList list = dir.entryInfoList();
|
QFileInfoList list = dir.entryInfoList();
|
||||||
list.removeAll(QFileInfo("/usr/share/applications/screensavers"));
|
list.removeAll(QFileInfo("/usr/share/applications/screensavers"));
|
||||||
if(list.size()< 1 ) {
|
if(list.size() < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i=0;
|
int i = 0;
|
||||||
//递归算法的核心部分
|
//递归算法的核心部分
|
||||||
do{
|
do {
|
||||||
QFileInfo fileInfo = list.at(i);
|
QFileInfo fileInfo = list.at(i);
|
||||||
//如果是文件夹,递归
|
//如果是文件夹,递归
|
||||||
bool isDir = fileInfo.isDir();
|
bool isDir = fileInfo.isDir();
|
||||||
if(isDir) {
|
if(isDir) {
|
||||||
getAllDesktopFilePath(fileInfo.filePath());
|
getAllDesktopFilePath(fileInfo.filePath());
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
//过滤LXQt、KDE
|
//过滤LXQt、KDE
|
||||||
QString filePathStr=fileInfo.filePath();
|
QString filePathStr = fileInfo.filePath();
|
||||||
if(filePathStr.contains("KDE",Qt::CaseInsensitive)||
|
if(filePathStr.contains("KDE", Qt::CaseInsensitive) ||
|
||||||
// filePathStr.contains("mate",Qt::CaseInsensitive)||
|
// filePathStr.contains("mate",Qt::CaseInsensitive)||
|
||||||
filePathStr.contains("LX",Qt::CaseInsensitive) ){
|
filePathStr.contains("LX", Qt::CaseInsensitive)) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//过滤后缀不是.desktop的文件
|
//过滤后缀不是.desktop的文件
|
||||||
if(!filePathStr.endsWith(".desktop"))
|
if(!filePathStr.endsWith(".desktop")) {
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QByteArray fpbyte=filePathStr.toLocal8Bit();
|
QByteArray fpbyte = filePathStr.toLocal8Bit();
|
||||||
char* filepath=fpbyte.data();
|
char* filepath = fpbyte.data();
|
||||||
g_key_file_load_from_file(keyfile,filepath,flags,nullptr);
|
g_key_file_load_from_file(keyfile, filepath, flags, nullptr);
|
||||||
char* ret_1=g_key_file_get_locale_string(keyfile,"Desktop Entry","NoDisplay", nullptr, nullptr);
|
char* ret_1 = g_key_file_get_locale_string(keyfile, "Desktop Entry", "NoDisplay", nullptr, nullptr);
|
||||||
if(ret_1!=nullptr)
|
if(ret_1 != nullptr) {
|
||||||
{
|
QString str = QString::fromLocal8Bit(ret_1);
|
||||||
QString str=QString::fromLocal8Bit(ret_1);
|
if(str.contains("true")) {
|
||||||
if(str.contains("true"))
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* ret_2=g_key_file_get_locale_string(keyfile,"Desktop Entry","NotShowIn", nullptr, nullptr);
|
char* ret_2 = g_key_file_get_locale_string(keyfile, "Desktop Entry", "NotShowIn", nullptr, nullptr);
|
||||||
if(ret_2!=nullptr)
|
if(ret_2 != nullptr) {
|
||||||
{
|
QString str = QString::fromLocal8Bit(ret_2);
|
||||||
QString str=QString::fromLocal8Bit(ret_2);
|
if(str.contains("UKUI")) {
|
||||||
if(str.contains("UKUI"))
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//过滤中英文名为空的情况
|
//过滤中英文名为空的情况
|
||||||
QLocale cn;
|
QLocale cn;
|
||||||
QString language=cn.languageToString(cn.language());
|
QString language = cn.languageToString(cn.language());
|
||||||
if(QString::compare(language,"Chinese")==0)
|
if(QString::compare(language, "Chinese") == 0) {
|
||||||
{
|
char* nameCh = g_key_file_get_string(keyfile, "Desktop Entry", "Name[zh_CN]", nullptr);
|
||||||
char* nameCh=g_key_file_get_string(keyfile,"Desktop Entry","Name[zh_CN]", nullptr);
|
char* nameEn = g_key_file_get_string(keyfile, "Desktop Entry", "Name", nullptr);
|
||||||
char* nameEn=g_key_file_get_string(keyfile,"Desktop Entry","Name", nullptr);
|
if(QString::fromLocal8Bit(nameCh).isEmpty() && QString::fromLocal8Bit(nameEn).isEmpty()) {
|
||||||
if(QString::fromLocal8Bit(nameCh).isEmpty() && QString::fromLocal8Bit(nameEn).isEmpty())
|
i++;
|
||||||
{
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char* name = g_key_file_get_string(keyfile, "Desktop Entry", "Name", nullptr);
|
||||||
|
if(QString::fromLocal8Bit(name).isEmpty()) {
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
name = g_key_file_get_locale_string(keyfile, "Desktop Entry", "Name", nullptr, nullptr);
|
||||||
char* name=g_key_file_get_string(keyfile,"Desktop Entry","Name", nullptr);
|
icon = g_key_file_get_locale_string(keyfile, "Desktop Entry", "Icon", nullptr, nullptr);
|
||||||
if(QString::fromLocal8Bit(name).isEmpty())
|
if(!m_filePathList.contains(filePathStr)) {
|
||||||
{
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name=g_key_file_get_locale_string(keyfile,"Desktop Entry","Name", nullptr, nullptr);
|
|
||||||
icon=g_key_file_get_locale_string(keyfile,"Desktop Entry","Icon", nullptr, nullptr);
|
|
||||||
if(!m_filePathList.contains(filePathStr)){
|
|
||||||
NameString appname;
|
NameString appname;
|
||||||
appname.app_name = QString::fromLocal8Bit(name);
|
appname.app_name = QString::fromLocal8Bit(name);
|
||||||
m_installAppMap.insert(appname,applist<<filePathStr<<QString::fromLocal8Bit(icon)<<""<<"");
|
m_installAppMap.insert(appname, applist << filePathStr << QString::fromLocal8Bit(icon) << "" << "");
|
||||||
applist.clear();
|
applist.clear();
|
||||||
}
|
}
|
||||||
// m_filePathList.append(filePathStr);
|
// m_filePathList.append(filePathStr);
|
||||||
}
|
}
|
||||||
|
@ -181,8 +169,7 @@ void AppMatch::getAllDesktopFilePath(QString path){
|
||||||
* @brief AppMatch::getDesktopFilePath
|
* @brief AppMatch::getDesktopFilePath
|
||||||
* 对遍历结果处理
|
* 对遍历结果处理
|
||||||
*/
|
*/
|
||||||
void AppMatch::getDesktopFilePath()
|
void AppMatch::getDesktopFilePath() {
|
||||||
{
|
|
||||||
m_filePathList.clear();
|
m_filePathList.clear();
|
||||||
m_installAppMap.clear();
|
m_installAppMap.clear();
|
||||||
m_filePathList.append("/usr/share/applications/software-properties-livepatch.desktop");
|
m_filePathList.append("/usr/share/applications/software-properties-livepatch.desktop");
|
||||||
|
@ -239,13 +226,12 @@ void AppMatch::getDesktopFilePath()
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::getAppName(QMap<NameString,QStringList> &installed)
|
void AppMatch::getAppName(QMap<NameString, QStringList> &installed) {
|
||||||
{
|
|
||||||
QMap<NameString, QStringList>::const_iterator i;
|
QMap<NameString, QStringList>::const_iterator i;
|
||||||
for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){
|
for(i = m_installAppMap.constBegin(); i != m_installAppMap.constEnd(); ++i) {
|
||||||
appNameMatch(i.key().app_name,installed);
|
appNameMatch(i.key().app_name, installed);
|
||||||
}
|
}
|
||||||
qDebug()<<"installed app match is successful!";
|
qDebug() << "installed app match is successful!";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,67 +240,63 @@ void AppMatch::getAppName(QMap<NameString,QStringList> &installed)
|
||||||
* @param appname
|
* @param appname
|
||||||
* 应用名字
|
* 应用名字
|
||||||
*/
|
*/
|
||||||
void AppMatch::appNameMatch(QString appname,QMap<NameString,QStringList> &installed){
|
void AppMatch::appNameMatch(QString appname, QMap<NameString, QStringList> &installed) {
|
||||||
NameString name{appname};
|
NameString name{appname};
|
||||||
QStringList list;
|
QStringList list;
|
||||||
QStringList pinyinlist;
|
QStringList pinyinlist;
|
||||||
pinyinlist=FileUtils::findMultiToneWords(appname);
|
pinyinlist = FileUtils::findMultiToneWords(appname);
|
||||||
QMapIterator<NameString,QStringList> iter(m_installAppMap);
|
QMapIterator<NameString, QStringList> iter(m_installAppMap);
|
||||||
while(iter.hasNext())
|
while(iter.hasNext()) {
|
||||||
{
|
|
||||||
iter.next();
|
iter.next();
|
||||||
if (iter.key().app_name == appname) {
|
if(iter.key().app_name == appname) {
|
||||||
list = iter.value();
|
list = iter.value();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(appname.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(appname.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
// installed.insert(name,m_installAppMap.value(name));
|
// installed.insert(name,m_installAppMap.value(name));
|
||||||
installed.insert(name,list);
|
installed.insert(name, list);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(int i = 0;i<pinyinlist.size()/2;i++){
|
for(int i = 0; i < pinyinlist.size() / 2; i++) {
|
||||||
QString shouzimu=pinyinlist.at(2*i+1);// 中文转首字母
|
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
|
||||||
if(shouzimu.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(shouzimu.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
// installed.insert(name,m_installAppMap.value(name));
|
// installed.insert(name,m_installAppMap.value(name));
|
||||||
installed.insert(name,list);
|
installed.insert(name, list);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(m_sourceText.size()<2)
|
if(m_sourceText.size() < 2)
|
||||||
return;
|
return;
|
||||||
QString pinyin=pinyinlist.at(2*i);// 中文转拼音
|
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
|
||||||
if(pinyin.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(pinyin.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
// installed.insert(name,m_installAppMap.value(name));
|
// installed.insert(name,m_installAppMap.value(name));
|
||||||
installed.insert(name,list);
|
installed.insert(name, list);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::softWareCenterSearch(QMap<NameString,QStringList> &softwarereturn){
|
void AppMatch::softWareCenterSearch(QMap<NameString, QStringList> &softwarereturn) {
|
||||||
if(m_interFace->timeout()!=-1){
|
if(m_interFace->timeout() != -1) {
|
||||||
qWarning()<<"softWareCente Dbus is timeout !";
|
qWarning() << "softWareCente Dbus is timeout !";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
slotDBusCallFinished(softwarereturn);
|
slotDBusCallFinished(softwarereturn);
|
||||||
qDebug()<<"softWareCenter match app is successful!";
|
qDebug() << "softWareCenter match app is successful!";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::slotDBusCallFinished(QMap<NameString,QStringList> &softwarereturn){
|
void AppMatch::slotDBusCallFinished(QMap<NameString, QStringList> &softwarereturn) {
|
||||||
QDBusReply<QList<QMap<QString,QString>>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。
|
QDBusReply<QList<QMap<QString, QString>>> reply = m_interFace->call("get_search_result", m_sourceText); //阻塞,直到远程方法调用完成。
|
||||||
// QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call;
|
// QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call;
|
||||||
if (reply.isValid())
|
if(reply.isValid()) {
|
||||||
{
|
parseSoftWareCenterReturn(reply.value(), softwarereturn);
|
||||||
parseSoftWareCenterReturn(reply.value(),softwarereturn);
|
} else {
|
||||||
}
|
qWarning() << "value method called failed!";
|
||||||
else
|
}
|
||||||
{
|
|
||||||
qWarning() << "value method called failed!";
|
|
||||||
}
|
|
||||||
// call->deleteLater();
|
// call->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<NameString,QStringList> &softwarereturn){
|
void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString, QString>> list, QMap<NameString, QStringList> &softwarereturn) {
|
||||||
// qWarning()<<list;
|
// qWarning()<<list;
|
||||||
QString appname;
|
QString appname;
|
||||||
NameString name;
|
NameString name;
|
||||||
|
@ -323,24 +305,24 @@ void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<
|
||||||
QStringList applist;
|
QStringList applist;
|
||||||
QLocale locale;
|
QLocale locale;
|
||||||
QString pkgname;
|
QString pkgname;
|
||||||
for(int i=0;i<list.size();i++){
|
for(int i = 0; i < list.size(); i++) {
|
||||||
// qWarning()<<list.at(i).keys();
|
// qWarning()<<list.at(i).keys();
|
||||||
if(locale.language()==QLocale::Chinese){
|
if(locale.language() == QLocale::Chinese) {
|
||||||
appname=list.at(i).value("displayname_cn");
|
appname = list.at(i).value("displayname_cn");
|
||||||
pkgname = list.at(i).value("appname");
|
pkgname = list.at(i).value("appname");
|
||||||
}
|
}
|
||||||
if(locale.language()==QLocale::English){
|
if(locale.language() == QLocale::English) {
|
||||||
appname=list.at(i).value("appname");
|
appname = list.at(i).value("appname");
|
||||||
}
|
}
|
||||||
appdiscription=list.at(i).value("discription");
|
appdiscription = list.at(i).value("discription");
|
||||||
appicon=list.at(i).value("icon");
|
appicon = list.at(i).value("icon");
|
||||||
name.app_name = appname;
|
name.app_name = appname;
|
||||||
pkgname.isEmpty() ? softwarereturn.insert(name,applist<<""<<appicon<<""<<appdiscription) : softwarereturn.insert(name,applist<<""<<appicon<<pkgname<<appdiscription);
|
pkgname.isEmpty() ? softwarereturn.insert(name, applist << "" << appicon << "" << appdiscription) : softwarereturn.insert(name, applist << "" << appicon << pkgname << appdiscription);
|
||||||
applist.clear();
|
applist.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::getInstalledAppsVersion(QString appname){
|
void AppMatch::getInstalledAppsVersion(QString appname) {
|
||||||
// qWarning()<<"apt show "+appname;
|
// qWarning()<<"apt show "+appname;
|
||||||
// m_versionCommand->start("apt show "+appname);
|
// m_versionCommand->start("apt show "+appname);
|
||||||
// m_versionCommand->startDetached(m_versionCommand->program());
|
// m_versionCommand->startDetached(m_versionCommand->program());
|
||||||
|
@ -360,21 +342,21 @@ void AppMatch::getInstalledAppsVersion(QString appname){
|
||||||
// m_versionCommand->close();
|
// m_versionCommand->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppMatch::run(){
|
void AppMatch::run() {
|
||||||
qDebug()<<"AppMatch is run";
|
qDebug() << "AppMatch is run";
|
||||||
this->getDesktopFilePath();
|
this->getDesktopFilePath();
|
||||||
this->getAllDesktopFilePath("/usr/share/applications/");
|
this->getAllDesktopFilePath("/usr/share/applications/");
|
||||||
QDir androidPath(QDir::homePath()+"/.local/share/applications/");
|
QDir androidPath(QDir::homePath() + "/.local/share/applications/");
|
||||||
if(androidPath.exists())
|
if(androidPath.exists())
|
||||||
this->getAllDesktopFilePath(QDir::homePath()+"/.local/share/applications/");
|
this->getAllDesktopFilePath(QDir::homePath() + "/.local/share/applications/");
|
||||||
connect(m_watchAppDir,&QFileSystemWatcher::directoryChanged,this,[=](const QString &path){
|
connect(m_watchAppDir, &QFileSystemWatcher::directoryChanged, this, [ = ](const QString & path) {
|
||||||
this->getDesktopFilePath();
|
this->getDesktopFilePath();
|
||||||
if(path=="/usr/share/applications/"){
|
if(path == "/usr/share/applications/") {
|
||||||
this->getAllDesktopFilePath("/usr/share/applications/");
|
this->getAllDesktopFilePath("/usr/share/applications/");
|
||||||
}
|
}
|
||||||
if(androidPath.exists()){
|
if(androidPath.exists()) {
|
||||||
if(path==QDir::homePath()+"/.local/share/applications/"){
|
if(path == QDir::homePath() + "/.local/share/applications/") {
|
||||||
this->getAllDesktopFilePath(QDir::homePath()+"/.local/share/applications/");
|
this->getAllDesktopFilePath(QDir::homePath() + "/.local/share/applications/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
class NameString
|
class NameString {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit NameString(const QString &str_) : app_name(str_) {}
|
explicit NameString(const QString &str_) : app_name(str_) {}
|
||||||
NameString() = default;
|
NameString() = default;
|
||||||
|
@ -52,25 +51,24 @@ public:
|
||||||
// }
|
// }
|
||||||
//};
|
//};
|
||||||
|
|
||||||
class AppMatch : public QThread
|
class AppMatch : public QThread {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static AppMatch *getAppMatch();
|
static AppMatch *getAppMatch();
|
||||||
void startMatchApp(QString input,QMap<NameString,QStringList> &installed,QMap<NameString,QStringList> &softwarereturn);
|
void startMatchApp(QString input, QMap<NameString, QStringList> &installed, QMap<NameString, QStringList> &softwarereturn);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit AppMatch(QObject *parent = nullptr);
|
explicit AppMatch(QObject *parent = nullptr);
|
||||||
~AppMatch();
|
~AppMatch();
|
||||||
void getAllDesktopFilePath(QString path);
|
void getAllDesktopFilePath(QString path);
|
||||||
void getDesktopFilePath();
|
void getDesktopFilePath();
|
||||||
void getAppName(QMap<NameString,QStringList> &installed);
|
void getAppName(QMap<NameString, QStringList> &installed);
|
||||||
// void appNameMatch(QString appname,QString desktoppath,QString appicon);
|
// void appNameMatch(QString appname,QString desktoppath,QString appicon);
|
||||||
void appNameMatch(QString appname,QMap<NameString,QStringList> &installed);
|
void appNameMatch(QString appname, QMap<NameString, QStringList> &installed);
|
||||||
|
|
||||||
void softWareCenterSearch(QMap<NameString,QStringList> &softwarereturn);
|
void softWareCenterSearch(QMap<NameString, QStringList> &softwarereturn);
|
||||||
|
|
||||||
void parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<NameString,QStringList> &softwarereturn);
|
void parseSoftWareCenterReturn(QList<QMap<QString, QString>> list, QMap<NameString, QStringList> &softwarereturn);
|
||||||
|
|
||||||
void getInstalledAppsVersion(QString appname);
|
void getInstalledAppsVersion(QString appname);
|
||||||
|
|
||||||
|
@ -78,12 +76,12 @@ private:
|
||||||
QString m_sourceText;
|
QString m_sourceText;
|
||||||
QStringList m_filePathList;
|
QStringList m_filePathList;
|
||||||
|
|
||||||
QDBusInterface *m_interFace=nullptr;
|
QDBusInterface *m_interFace = nullptr;
|
||||||
QFileSystemWatcher *m_watchAppDir=nullptr;
|
QFileSystemWatcher *m_watchAppDir = nullptr;
|
||||||
QMap<NameString,QStringList> m_installAppMap;
|
QMap<NameString, QStringList> m_installAppMap;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotDBusCallFinished(QMap<NameString,QStringList> &softwarereturn);
|
void slotDBusCallFinished(QMap<NameString, QStringList> &softwarereturn);
|
||||||
|
|
||||||
//Q_SIGNALS:
|
//Q_SIGNALS:
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,11 @@ unsigned short FileUtils::_index_status = 0;
|
||||||
FileUtils::SearchMethod FileUtils::searchMethod = FileUtils::SearchMethod::DIRECTSEARCH;
|
FileUtils::SearchMethod FileUtils::searchMethod = FileUtils::SearchMethod::DIRECTSEARCH;
|
||||||
QMap<QString, QStringList> FileUtils::map_chinese2pinyin = QMap<QString, QStringList>();
|
QMap<QString, QStringList> FileUtils::map_chinese2pinyin = QMap<QString, QStringList>();
|
||||||
|
|
||||||
FileUtils::FileUtils()
|
FileUtils::FileUtils() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileUtils::makeDocUterm(QString path)
|
std::string FileUtils::makeDocUterm(QString path) {
|
||||||
{
|
return QCryptographicHash::hash(path.toUtf8(), QCryptographicHash::Md5).toHex().toStdString();
|
||||||
return QCryptographicHash::hash(path.toUtf8(),QCryptographicHash::Md5).toHex().toStdString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,30 +41,29 @@ std::string FileUtils::makeDocUterm(QString path)
|
||||||
* @param checkValid
|
* @param checkValid
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QIcon FileUtils::getFileIcon(const QString &uri, bool checkValid)
|
QIcon FileUtils::getFileIcon(const QString &uri, bool checkValid) {
|
||||||
{
|
|
||||||
auto file = wrapGFile(g_file_new_for_uri(uri.toUtf8().constData()));
|
auto file = wrapGFile(g_file_new_for_uri(uri.toUtf8().constData()));
|
||||||
auto info = wrapGFileInfo(g_file_query_info(file.get()->get(),
|
auto info = wrapGFileInfo(g_file_query_info(file.get()->get(),
|
||||||
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
||||||
G_FILE_QUERY_INFO_NONE,
|
G_FILE_QUERY_INFO_NONE,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr));
|
nullptr));
|
||||||
if (!G_IS_FILE_INFO (info.get()->get()))
|
if(!G_IS_FILE_INFO(info.get()->get()))
|
||||||
return QIcon::fromTheme("unknown");
|
return QIcon::fromTheme("unknown");
|
||||||
GIcon *g_icon = g_file_info_get_icon (info.get()->get());
|
GIcon *g_icon = g_file_info_get_icon(info.get()->get());
|
||||||
QString icon_name;
|
QString icon_name;
|
||||||
//do not unref the GIcon from info.
|
//do not unref the GIcon from info.
|
||||||
if (G_IS_ICON(g_icon)) {
|
if(G_IS_ICON(g_icon)) {
|
||||||
const gchar* const* icon_names = g_themed_icon_get_names(G_THEMED_ICON (g_icon));
|
const gchar* const* icon_names = g_themed_icon_get_names(G_THEMED_ICON(g_icon));
|
||||||
if (icon_names) {
|
if(icon_names) {
|
||||||
auto p = icon_names;
|
auto p = icon_names;
|
||||||
if (*p)
|
if(*p)
|
||||||
icon_name = QString (*p);
|
icon_name = QString(*p);
|
||||||
if (checkValid) {
|
if(checkValid) {
|
||||||
while (*p) {
|
while(*p) {
|
||||||
QIcon icon = QIcon::fromTheme(*p);
|
QIcon icon = QIcon::fromTheme(*p);
|
||||||
if (!icon.isNull()) {
|
if(!icon.isNull()) {
|
||||||
icon_name = QString (*p);
|
icon_name = QString(*p);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
p++;
|
p++;
|
||||||
|
@ -75,7 +72,7 @@ QIcon FileUtils::getFileIcon(const QString &uri, bool checkValid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QIcon::fromTheme(icon_name).isNull()) {
|
if(QIcon::fromTheme(icon_name).isNull()) {
|
||||||
return QIcon::fromTheme("unknown");
|
return QIcon::fromTheme("unknown");
|
||||||
}
|
}
|
||||||
return QIcon::fromTheme(icon_name);
|
return QIcon::fromTheme(icon_name);
|
||||||
|
@ -91,13 +88,13 @@ QIcon FileUtils::getAppIcon(const QString &path) {
|
||||||
ba = path.toUtf8();
|
ba = path.toUtf8();
|
||||||
GKeyFile * keyfile;
|
GKeyFile * keyfile;
|
||||||
keyfile = g_key_file_new();
|
keyfile = g_key_file_new();
|
||||||
if (!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)){
|
if(!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)) {
|
||||||
g_key_file_free (keyfile);
|
g_key_file_free(keyfile);
|
||||||
return QIcon::fromTheme("unknown");
|
return QIcon::fromTheme("unknown");
|
||||||
}
|
}
|
||||||
QString icon = QString(g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL));
|
QString icon = QString(g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL));
|
||||||
g_key_file_free(keyfile);
|
g_key_file_free(keyfile);
|
||||||
if (QIcon::fromTheme(icon).isNull()) {
|
if(QIcon::fromTheme(icon).isNull()) {
|
||||||
return QIcon(":/res/icons/desktop.png");
|
return QIcon(":/res/icons/desktop.png");
|
||||||
}
|
}
|
||||||
return QIcon::fromTheme(icon);
|
return QIcon::fromTheme(icon);
|
||||||
|
@ -111,17 +108,17 @@ QIcon FileUtils::getAppIcon(const QString &path) {
|
||||||
*/
|
*/
|
||||||
QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
|
QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
|
||||||
QString name = setting.left(setting.indexOf("/"));
|
QString name = setting.left(setting.indexOf("/"));
|
||||||
if (! name.isEmpty()) {
|
if(! name.isEmpty()) {
|
||||||
name.replace(QString(name.at(0)), QString(name.at(0).toUpper()));
|
name.replace(QString(name.at(0)), QString(name.at(0).toUpper()));
|
||||||
}
|
}
|
||||||
QString path;
|
QString path;
|
||||||
if (is_white) {
|
if(is_white) {
|
||||||
path = QString("/usr/share/ukui-control-center/shell/res/secondaryleftmenu/%1White.svg").arg(name);
|
path = QString("/usr/share/ukui-control-center/shell/res/secondaryleftmenu/%1White.svg").arg(name);
|
||||||
} else {
|
} else {
|
||||||
path = QString("/usr/share/ukui-control-center/shell/res/secondaryleftmenu/%1.svg").arg(name);
|
path = QString("/usr/share/ukui-control-center/shell/res/secondaryleftmenu/%1.svg").arg(name);
|
||||||
}
|
}
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (file.exists()) {
|
if(file.exists()) {
|
||||||
return QIcon(path);
|
return QIcon(path);
|
||||||
} else {
|
} else {
|
||||||
return QIcon::fromTheme("ukui-control-center"); //无插件图标时,返回控制面板应用图标
|
return QIcon::fromTheme("ukui-control-center"); //无插件图标时,返回控制面板应用图标
|
||||||
|
@ -140,7 +137,7 @@ QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
|
||||||
*/
|
*/
|
||||||
QString FileUtils::getFileName(const QString& uri) {
|
QString FileUtils::getFileName(const QString& uri) {
|
||||||
QFileInfo info(uri);
|
QFileInfo info(uri);
|
||||||
if (info.exists()) {
|
if(info.exists()) {
|
||||||
return info.fileName();
|
return info.fileName();
|
||||||
} else {
|
} else {
|
||||||
return "Unknown File";
|
return "Unknown File";
|
||||||
|
@ -162,8 +159,8 @@ QString FileUtils::getAppName(const QString& path) {
|
||||||
ba = path.toUtf8();
|
ba = path.toUtf8();
|
||||||
GKeyFile * keyfile;
|
GKeyFile * keyfile;
|
||||||
keyfile = g_key_file_new();
|
keyfile = g_key_file_new();
|
||||||
if (!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)){
|
if(!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)) {
|
||||||
g_key_file_free (keyfile);
|
g_key_file_free(keyfile);
|
||||||
return "Unknown App";
|
return "Unknown App";
|
||||||
}
|
}
|
||||||
QString name = QString(g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL));
|
QString name = QString(g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL));
|
||||||
|
@ -181,10 +178,9 @@ QString FileUtils::getSettingName(const QString& setting) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileUtils::loadHanziTable(const QString &fileName)
|
void FileUtils::loadHanziTable(const QString &fileName) {
|
||||||
{
|
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if(!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
qDebug("File: '%s' open failed!", file.fileName().toStdString().c_str());
|
qDebug("File: '%s' open failed!", file.fileName().toStdString().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -200,25 +196,23 @@ void FileUtils::loadHanziTable(const QString &fileName)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMimeType FileUtils::getMimetype(QString &path)
|
QMimeType FileUtils::getMimetype(QString &path) {
|
||||||
{
|
|
||||||
QMimeDatabase mdb;
|
QMimeDatabase mdb;
|
||||||
QMimeType type = mdb.mimeTypeForFile(path,QMimeDatabase::MatchContent);
|
QMimeType type = mdb.mimeTypeForFile(path, QMimeDatabase::MatchContent);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
//aborted
|
//aborted
|
||||||
QString FileUtils::find(const QString &hanzi)
|
QString FileUtils::find(const QString &hanzi) {
|
||||||
{
|
|
||||||
// static QMap<QString, QStringList> map = loadHanziTable("://index/pinyinWithoutTone.txt");
|
// static QMap<QString, QStringList> map = loadHanziTable("://index/pinyinWithoutTone.txt");
|
||||||
// static QMap<QString, QStringList> map;
|
// static QMap<QString, QStringList> map;
|
||||||
QString output;
|
QString output;
|
||||||
QStringList stringList = hanzi.split("");
|
QStringList stringList = hanzi.split("");
|
||||||
|
|
||||||
/* 遍历查找汉字-拼音对照表的内容并将汉字替换为拼音 */
|
/* 遍历查找汉字-拼音对照表的内容并将汉字替换为拼音 */
|
||||||
for (const QString &str : stringList) {
|
for(const QString &str : stringList) {
|
||||||
if (FileUtils::map_chinese2pinyin.contains(str))
|
if(FileUtils::map_chinese2pinyin.contains(str))
|
||||||
output += FileUtils::map_chinese2pinyin[str].first();
|
output += FileUtils::map_chinese2pinyin[str].first();
|
||||||
else
|
else
|
||||||
output += str;
|
output += str;
|
||||||
|
@ -228,93 +222,88 @@ QString FileUtils::find(const QString &hanzi)
|
||||||
}
|
}
|
||||||
|
|
||||||
//DFS多音字太多直接GG
|
//DFS多音字太多直接GG
|
||||||
void stitchMultiToneWordsDFS(const QString& hanzi, const QString& resultAllPinYin, const QString& resultFirst, QStringList& resultList){
|
void stitchMultiToneWordsDFS(const QString& hanzi, const QString& resultAllPinYin, const QString& resultFirst, QStringList& resultList) {
|
||||||
if (hanzi.size() == 0){
|
if(hanzi.size() == 0) {
|
||||||
resultList.append(resultAllPinYin);
|
resultList.append(resultAllPinYin);
|
||||||
resultList.append(resultFirst);
|
resultList.append(resultFirst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (FileUtils::map_chinese2pinyin.contains(hanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(hanzi.at(0))) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[hanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[hanzi.at(0)]) {
|
||||||
stitchMultiToneWordsDFS(hanzi.right(hanzi.size() - 1), resultAllPinYin + i, resultFirst + i.at(0), resultList);
|
stitchMultiToneWordsDFS(hanzi.right(hanzi.size() - 1), resultAllPinYin + i, resultFirst + i.at(0), resultList);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
stitchMultiToneWordsDFS(hanzi.right(hanzi.size() - 1), resultAllPinYin + hanzi.at(0), resultFirst + hanzi.at(0), resultList);
|
stitchMultiToneWordsDFS(hanzi.right(hanzi.size() - 1), resultAllPinYin + hanzi.at(0), resultFirst + hanzi.at(0), resultList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//BFS+Stack多音字太多会爆栈
|
//BFS+Stack多音字太多会爆栈
|
||||||
void stitchMultiToneWordsBFSStack(const QString& hanzi, QStringList& resultList){
|
void stitchMultiToneWordsBFSStack(const QString& hanzi, QStringList& resultList) {
|
||||||
QString tempHanzi, resultAllPinYin, resultFirst;
|
QString tempHanzi, resultAllPinYin, resultFirst;
|
||||||
QQueue<QString> tempQueue;
|
QQueue<QString> tempQueue;
|
||||||
tempHanzi = hanzi;
|
tempHanzi = hanzi;
|
||||||
int tempQueueSize = 0;
|
int tempQueueSize = 0;
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue.enqueue(i);
|
tempQueue.enqueue(i);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
tempQueue.enqueue(tempHanzi.at(0));
|
tempQueue.enqueue(tempHanzi.at(0));
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
while (tempHanzi.size() != 0) {
|
while(tempHanzi.size() != 0) {
|
||||||
tempQueueSize = tempQueue.size();
|
tempQueueSize = tempQueue.size();
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue.enqueue(tempQueue.head() + i);
|
tempQueue.enqueue(tempQueue.head() + i);
|
||||||
}
|
}
|
||||||
tempQueue.dequeue();
|
tempQueue.dequeue();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
|
||||||
tempQueue.enqueue(tempQueue.head() + tempHanzi.at(0));
|
tempQueue.enqueue(tempQueue.head() + tempHanzi.at(0));
|
||||||
tempQueue.dequeue();
|
tempQueue.dequeue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
}
|
}
|
||||||
while(!tempQueue.empty()){
|
while(!tempQueue.empty()) {
|
||||||
resultList.append(tempQueue.dequeue());
|
resultList.append(tempQueue.dequeue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//BFS+Heap,多音字太多会耗尽内存
|
//BFS+Heap,多音字太多会耗尽内存
|
||||||
void stitchMultiToneWordsBFSHeap(const QString& hanzi, QStringList& resultList){
|
void stitchMultiToneWordsBFSHeap(const QString& hanzi, QStringList& resultList) {
|
||||||
QString tempHanzi, resultAllPinYin, resultFirst;
|
QString tempHanzi, resultAllPinYin, resultFirst;
|
||||||
QQueue<QString>* tempQueue = new QQueue<QString>;
|
QQueue<QString>* tempQueue = new QQueue<QString>;
|
||||||
tempHanzi = hanzi;
|
tempHanzi = hanzi;
|
||||||
int tempQueueSize = 0;
|
int tempQueueSize = 0;
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue->enqueue(i);
|
tempQueue->enqueue(i);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
tempQueue->enqueue(tempHanzi.at(0));
|
tempQueue->enqueue(tempHanzi.at(0));
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
while (tempHanzi.size() != 0) {
|
while(tempHanzi.size() != 0) {
|
||||||
tempQueueSize = tempQueue->size();
|
tempQueueSize = tempQueue->size();
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue->enqueue(tempQueue->head() + i);
|
tempQueue->enqueue(tempQueue->head() + i);
|
||||||
}
|
}
|
||||||
tempQueue->dequeue();
|
tempQueue->dequeue();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
|
||||||
tempQueue->enqueue(tempQueue->head() + tempHanzi.at(0));
|
tempQueue->enqueue(tempQueue->head() + tempHanzi.at(0));
|
||||||
tempQueue->dequeue();
|
tempQueue->dequeue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
}
|
}
|
||||||
while(!tempQueue->empty()){
|
while(!tempQueue->empty()) {
|
||||||
resultList.append(tempQueue->dequeue());
|
resultList.append(tempQueue->dequeue());
|
||||||
}
|
}
|
||||||
delete tempQueue;
|
delete tempQueue;
|
||||||
|
@ -322,28 +311,27 @@ void stitchMultiToneWordsBFSHeap(const QString& hanzi, QStringList& resultList){
|
||||||
}
|
}
|
||||||
|
|
||||||
//BFS+Heap+超过3个多音字只建一个索引,比较折中的方案
|
//BFS+Heap+超过3个多音字只建一个索引,比较折中的方案
|
||||||
void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultList){
|
void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultList) {
|
||||||
QString tempHanzi, resultAllPinYin, resultFirst;
|
QString tempHanzi, resultAllPinYin, resultFirst;
|
||||||
QQueue<QString>* tempQueue = new QQueue<QString>;
|
QQueue<QString>* tempQueue = new QQueue<QString>;
|
||||||
QQueue<QString>* tempQueueFirst = new QQueue<QString>;
|
QQueue<QString>* tempQueueFirst = new QQueue<QString>;
|
||||||
tempHanzi = hanzi;
|
tempHanzi = hanzi;
|
||||||
int tempQueueSize = 0;
|
int tempQueueSize = 0;
|
||||||
int multiToneWordNum = 0;
|
int multiToneWordNum = 0;
|
||||||
for (auto i : hanzi){
|
for(auto i : hanzi) {
|
||||||
if (FileUtils::map_chinese2pinyin.contains(i)){
|
if(FileUtils::map_chinese2pinyin.contains(i)) {
|
||||||
if (FileUtils::map_chinese2pinyin[i].size() > 1){
|
if(FileUtils::map_chinese2pinyin[i].size() > 1) {
|
||||||
++multiToneWordNum;
|
++multiToneWordNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (multiToneWordNum > 3){
|
if(multiToneWordNum > 3) {
|
||||||
QString oneResult, oneResultFirst;
|
QString oneResult, oneResultFirst;
|
||||||
for (auto i : hanzi){
|
for(auto i : hanzi) {
|
||||||
if (FileUtils::map_chinese2pinyin.contains(i)){
|
if(FileUtils::map_chinese2pinyin.contains(i)) {
|
||||||
oneResult += FileUtils::map_chinese2pinyin[i].first();
|
oneResult += FileUtils::map_chinese2pinyin[i].first();
|
||||||
oneResultFirst += FileUtils::map_chinese2pinyin[i].first().at(0);
|
oneResultFirst += FileUtils::map_chinese2pinyin[i].first().at(0);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
oneResult += i;
|
oneResult += i;
|
||||||
oneResultFirst += i;
|
oneResultFirst += i;
|
||||||
}
|
}
|
||||||
|
@ -353,31 +341,29 @@ void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultL
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue->enqueue(i);
|
tempQueue->enqueue(i);
|
||||||
tempQueueFirst->enqueue(i.at(0));
|
tempQueueFirst->enqueue(i.at(0));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
tempQueue->enqueue(tempHanzi.at(0));
|
tempQueue->enqueue(tempHanzi.at(0));
|
||||||
tempQueueFirst->enqueue(tempHanzi.at(0));
|
tempQueueFirst->enqueue(tempHanzi.at(0));
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
while (tempHanzi.size() != 0) {
|
while(tempHanzi.size() != 0) {
|
||||||
tempQueueSize = tempQueue->size();
|
tempQueueSize = tempQueue->size();
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue->enqueue(tempQueue->head() + i);
|
tempQueue->enqueue(tempQueue->head() + i);
|
||||||
tempQueueFirst->enqueue(tempQueueFirst->head() + i.at(0));
|
tempQueueFirst->enqueue(tempQueueFirst->head() + i.at(0));
|
||||||
}
|
}
|
||||||
tempQueue->dequeue();
|
tempQueue->dequeue();
|
||||||
tempQueueFirst->dequeue();
|
tempQueueFirst->dequeue();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
|
||||||
tempQueue->enqueue(tempQueue->head() + tempHanzi.at(0));
|
tempQueue->enqueue(tempQueue->head() + tempHanzi.at(0));
|
||||||
tempQueueFirst->enqueue(tempQueueFirst->head() + tempHanzi.at(0));
|
tempQueueFirst->enqueue(tempQueueFirst->head() + tempHanzi.at(0));
|
||||||
tempQueue->dequeue();
|
tempQueue->dequeue();
|
||||||
|
@ -386,7 +372,7 @@ void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultL
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
}
|
}
|
||||||
while(!tempQueue->empty()){
|
while(!tempQueue->empty()) {
|
||||||
resultList.append(tempQueue->dequeue());
|
resultList.append(tempQueue->dequeue());
|
||||||
resultList.append(tempQueueFirst->dequeue());
|
resultList.append(tempQueueFirst->dequeue());
|
||||||
}
|
}
|
||||||
|
@ -398,28 +384,27 @@ void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultL
|
||||||
}
|
}
|
||||||
|
|
||||||
//BFS+Stack+超过3个多音字只建一个索引,比较折中的方案
|
//BFS+Stack+超过3个多音字只建一个索引,比较折中的方案
|
||||||
void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& resultList){
|
void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& resultList) {
|
||||||
QString tempHanzi, resultAllPinYin, resultFirst;
|
QString tempHanzi, resultAllPinYin, resultFirst;
|
||||||
QQueue<QString> tempQueue;
|
QQueue<QString> tempQueue;
|
||||||
QQueue<QString> tempQueueFirst;
|
QQueue<QString> tempQueueFirst;
|
||||||
tempHanzi = hanzi;
|
tempHanzi = hanzi;
|
||||||
int tempQueueSize = 0;
|
int tempQueueSize = 0;
|
||||||
int multiToneWordNum = 0;
|
int multiToneWordNum = 0;
|
||||||
for (auto i : hanzi){
|
for(auto i : hanzi) {
|
||||||
if (FileUtils::map_chinese2pinyin.contains(i)){
|
if(FileUtils::map_chinese2pinyin.contains(i)) {
|
||||||
if (FileUtils::map_chinese2pinyin[i].size() > 1){
|
if(FileUtils::map_chinese2pinyin[i].size() > 1) {
|
||||||
++multiToneWordNum;
|
++multiToneWordNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (multiToneWordNum > 3){
|
if(multiToneWordNum > 3) {
|
||||||
QString oneResult, oneResultFirst;
|
QString oneResult, oneResultFirst;
|
||||||
for (auto i : hanzi){
|
for(auto i : hanzi) {
|
||||||
if (FileUtils::map_chinese2pinyin.contains(i)){
|
if(FileUtils::map_chinese2pinyin.contains(i)) {
|
||||||
oneResult += FileUtils::map_chinese2pinyin[i].first();
|
oneResult += FileUtils::map_chinese2pinyin[i].first();
|
||||||
oneResultFirst += FileUtils::map_chinese2pinyin[i].first().at(0);
|
oneResultFirst += FileUtils::map_chinese2pinyin[i].first().at(0);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
oneResult += i;
|
oneResult += i;
|
||||||
oneResultFirst += i;
|
oneResultFirst += i;
|
||||||
}
|
}
|
||||||
|
@ -429,31 +414,29 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue.enqueue(i);
|
tempQueue.enqueue(i);
|
||||||
tempQueueFirst.enqueue(i.at(0));
|
tempQueueFirst.enqueue(i.at(0));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
tempQueue.enqueue(tempHanzi.at(0));
|
tempQueue.enqueue(tempHanzi.at(0));
|
||||||
tempQueueFirst.enqueue(tempHanzi.at(0));
|
tempQueueFirst.enqueue(tempHanzi.at(0));
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
while (tempHanzi.size() != 0) {
|
while(tempHanzi.size() != 0) {
|
||||||
tempQueueSize = tempQueue.size();
|
tempQueueSize = tempQueue.size();
|
||||||
if (FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))){
|
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]){
|
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
|
||||||
tempQueue.enqueue(tempQueue.head() + i);
|
tempQueue.enqueue(tempQueue.head() + i);
|
||||||
tempQueueFirst.enqueue(tempQueueFirst.head() + i.at(0));
|
tempQueueFirst.enqueue(tempQueueFirst.head() + i.at(0));
|
||||||
}
|
}
|
||||||
tempQueue.dequeue();
|
tempQueue.dequeue();
|
||||||
tempQueueFirst.dequeue();
|
tempQueueFirst.dequeue();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
for(int j = 0; j < tempQueueSize; ++j) {
|
||||||
for (int j = 0; j < tempQueueSize; ++j){
|
|
||||||
tempQueue.enqueue(tempQueue.head() + tempHanzi.at(0));
|
tempQueue.enqueue(tempQueue.head() + tempHanzi.at(0));
|
||||||
tempQueueFirst.enqueue(tempQueueFirst.head() + tempHanzi.at(0));
|
tempQueueFirst.enqueue(tempQueueFirst.head() + tempHanzi.at(0));
|
||||||
tempQueue.dequeue();
|
tempQueue.dequeue();
|
||||||
|
@ -462,7 +445,7 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
|
||||||
}
|
}
|
||||||
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
|
||||||
}
|
}
|
||||||
while(!tempQueue.empty()){
|
while(!tempQueue.empty()) {
|
||||||
resultList.append(tempQueue.dequeue());
|
resultList.append(tempQueue.dequeue());
|
||||||
resultList.append(tempQueueFirst.dequeue());
|
resultList.append(tempQueueFirst.dequeue());
|
||||||
}
|
}
|
||||||
|
@ -473,8 +456,7 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList FileUtils::findMultiToneWords(const QString& hanzi)
|
QStringList FileUtils::findMultiToneWords(const QString& hanzi) {
|
||||||
{
|
|
||||||
// QStringList* output = new QStringList();
|
// QStringList* output = new QStringList();
|
||||||
QStringList output;
|
QStringList output;
|
||||||
QString tempAllPinYin, tempFirst;
|
QString tempAllPinYin, tempFirst;
|
||||||
|
@ -491,17 +473,16 @@ QStringList FileUtils::findMultiToneWords(const QString& hanzi)
|
||||||
* @param path: abs path
|
* @param path: abs path
|
||||||
* @return docx to QString
|
* @return docx to QString
|
||||||
*/
|
*/
|
||||||
void FileUtils::getDocxTextContent(QString &path,QString &textcontent)
|
void FileUtils::getDocxTextContent(QString &path, QString &textcontent) {
|
||||||
{
|
|
||||||
//fix me :optimized by xpath??
|
//fix me :optimized by xpath??
|
||||||
QFileInfo info = QFileInfo(path);
|
QFileInfo info = QFileInfo(path);
|
||||||
if(!info.exists()||info.isDir())
|
if(!info.exists() || info.isDir())
|
||||||
return;
|
return;
|
||||||
QuaZip file(path);
|
QuaZip file(path);
|
||||||
if(!file.open(QuaZip::mdUnzip))
|
if(!file.open(QuaZip::mdUnzip))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!file.setCurrentFile("word/document.xml",QuaZip::csSensitive))
|
if(!file.setCurrentFile("word/document.xml", QuaZip::csSensitive))
|
||||||
return;
|
return;
|
||||||
QuaZipFile fileR(&file);
|
QuaZipFile fileR(&file);
|
||||||
|
|
||||||
|
@ -512,18 +493,14 @@ void FileUtils::getDocxTextContent(QString &path,QString &textcontent)
|
||||||
fileR.close();
|
fileR.close();
|
||||||
QDomElement first = doc.firstChildElement("w:document");
|
QDomElement first = doc.firstChildElement("w:document");
|
||||||
QDomElement body = first.firstChildElement("w:body");
|
QDomElement body = first.firstChildElement("w:body");
|
||||||
while(!body.isNull())
|
while(!body.isNull()) {
|
||||||
{
|
QDomElement wp = body.firstChildElement("w:p");
|
||||||
QDomElement wp= body.firstChildElement("w:p");
|
while(!wp.isNull()) {
|
||||||
while(!wp.isNull())
|
QDomElement wr = wp.firstChildElement("w:r");
|
||||||
{
|
while(!wr.isNull()) {
|
||||||
QDomElement wr= wp.firstChildElement("w:r");
|
|
||||||
while(!wr.isNull())
|
|
||||||
{
|
|
||||||
QDomElement wt = wr.firstChildElement("w:t");
|
QDomElement wt = wr.firstChildElement("w:t");
|
||||||
textcontent.append(wt.text().replace("\n",""));
|
textcontent.append(wt.text().replace("\n", ""));
|
||||||
if(textcontent.length() >= MAX_CONTENT_LENGTH/3)
|
if(textcontent.length() >= MAX_CONTENT_LENGTH / 3) {
|
||||||
{
|
|
||||||
file.close();
|
file.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -537,20 +514,18 @@ void FileUtils::getDocxTextContent(QString &path,QString &textcontent)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileUtils::getPptxTextContent(QString &path, QString &textcontent)
|
void FileUtils::getPptxTextContent(QString &path, QString &textcontent) {
|
||||||
{
|
|
||||||
QFileInfo info = QFileInfo(path);
|
QFileInfo info = QFileInfo(path);
|
||||||
if(!info.exists()||info.isDir())
|
if(!info.exists() || info.isDir())
|
||||||
return;
|
return;
|
||||||
QuaZip file(path);
|
QuaZip file(path);
|
||||||
if(!file.open(QuaZip::mdUnzip))
|
if(!file.open(QuaZip::mdUnzip))
|
||||||
return;
|
return;
|
||||||
QString prefix("ppt/slides/slide");
|
QString prefix("ppt/slides/slide");
|
||||||
QStringList fileList;
|
QStringList fileList;
|
||||||
for(QString i : file.getFileNameList())
|
for(QString i : file.getFileNameList()) {
|
||||||
{
|
|
||||||
if(i.startsWith(prefix))
|
if(i.startsWith(prefix))
|
||||||
fileList<<i;
|
fileList << i;
|
||||||
}
|
}
|
||||||
if(fileList.isEmpty())
|
if(fileList.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -562,11 +537,9 @@ void FileUtils::getPptxTextContent(QString &path, QString &textcontent)
|
||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
QDomElement at;
|
QDomElement at;
|
||||||
// QDomNodeList atList;
|
// QDomNodeList atList;
|
||||||
for(int i =0;i<fileList.size();++i)
|
for(int i = 0; i < fileList.size(); ++i) {
|
||||||
{
|
QString name = prefix + QString::number(i + 1) + ".xml";
|
||||||
QString name = prefix + QString::number(i+1) + ".xml";
|
if(!file.setCurrentFile(name)) {
|
||||||
if(!file.setCurrentFile(name))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QuaZipFile fileR(&file);
|
QuaZipFile fileR(&file);
|
||||||
|
@ -595,24 +568,18 @@ void FileUtils::getPptxTextContent(QString &path, QString &textcontent)
|
||||||
// }
|
// }
|
||||||
//This is ugly but seems more efficient when handel a large file.
|
//This is ugly but seems more efficient when handel a large file.
|
||||||
sptree = doc.firstChildElement("p:sld").firstChildElement("p:cSld").firstChildElement("p:spTree");
|
sptree = doc.firstChildElement("p:sld").firstChildElement("p:cSld").firstChildElement("p:spTree");
|
||||||
while(!sptree.isNull())
|
while(!sptree.isNull()) {
|
||||||
{
|
sp = sptree.firstChildElement("p:sp");
|
||||||
sp= sptree.firstChildElement("p:sp");
|
while(!sp.isNull()) {
|
||||||
while(!sp.isNull())
|
txbody = sp.firstChildElement("p:txBody");
|
||||||
{
|
while(!txbody.isNull()) {
|
||||||
txbody= sp.firstChildElement("p:txBody");
|
|
||||||
while(!txbody.isNull())
|
|
||||||
{
|
|
||||||
ap = txbody.firstChildElement("a:p");
|
ap = txbody.firstChildElement("a:p");
|
||||||
while(!ap.isNull())
|
while(!ap.isNull()) {
|
||||||
{
|
|
||||||
ar = ap.firstChildElement("a:r");
|
ar = ap.firstChildElement("a:r");
|
||||||
while(!ar.isNull())
|
while(!ar.isNull()) {
|
||||||
{
|
|
||||||
at = ar.firstChildElement("a:t");
|
at = ar.firstChildElement("a:t");
|
||||||
textcontent.append(at.text().replace("\r","")).replace("\t","");
|
textcontent.append(at.text().replace("\r", "")).replace("\t", "");
|
||||||
if(textcontent.length() >= MAX_CONTENT_LENGTH/3)
|
if(textcontent.length() >= MAX_CONTENT_LENGTH / 3) {
|
||||||
{
|
|
||||||
file.close();
|
file.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -631,16 +598,15 @@ void FileUtils::getPptxTextContent(QString &path, QString &textcontent)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileUtils::getXlsxTextContent(QString &path, QString &textcontent)
|
void FileUtils::getXlsxTextContent(QString &path, QString &textcontent) {
|
||||||
{
|
|
||||||
QFileInfo info = QFileInfo(path);
|
QFileInfo info = QFileInfo(path);
|
||||||
if(!info.exists()||info.isDir())
|
if(!info.exists() || info.isDir())
|
||||||
return;
|
return;
|
||||||
QuaZip file(path);
|
QuaZip file(path);
|
||||||
if(!file.open(QuaZip::mdUnzip))
|
if(!file.open(QuaZip::mdUnzip))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!file.setCurrentFile("xl/sharedStrings.xml",QuaZip::csSensitive))
|
if(!file.setCurrentFile("xl/sharedStrings.xml", QuaZip::csSensitive))
|
||||||
return;
|
return;
|
||||||
QuaZipFile fileR(&file);
|
QuaZipFile fileR(&file);
|
||||||
|
|
||||||
|
@ -653,25 +619,19 @@ void FileUtils::getXlsxTextContent(QString &path, QString &textcontent)
|
||||||
QDomElement si;
|
QDomElement si;
|
||||||
QDomElement r;
|
QDomElement r;
|
||||||
QDomElement t;
|
QDomElement t;
|
||||||
while(!sst.isNull())
|
while(!sst.isNull()) {
|
||||||
{
|
si = sst.firstChildElement("si");
|
||||||
si= sst.firstChildElement("si");
|
while(!si.isNull()) {
|
||||||
while(!si.isNull())
|
r = si.firstChildElement("r");
|
||||||
{
|
if(r.isNull()) {
|
||||||
r= si.firstChildElement("r");
|
t = si.firstChildElement("t");
|
||||||
if(r.isNull())
|
} else {
|
||||||
{
|
|
||||||
t= si.firstChildElement("t");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t = r.firstChildElement("t");
|
t = r.firstChildElement("t");
|
||||||
}
|
}
|
||||||
if(t.isNull())
|
if(t.isNull())
|
||||||
continue;
|
continue;
|
||||||
textcontent.append(t.text().replace("\r","").replace("\n",""));
|
textcontent.append(t.text().replace("\r", "").replace("\n", ""));
|
||||||
if(textcontent.length() >= MAX_CONTENT_LENGTH/3)
|
if(textcontent.length() >= MAX_CONTENT_LENGTH / 3) {
|
||||||
{
|
|
||||||
file.close();
|
file.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -683,46 +643,43 @@ void FileUtils::getXlsxTextContent(QString &path, QString &textcontent)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileUtils::getPdfTextContent(QString &path, QString &textcontent)
|
void FileUtils::getPdfTextContent(QString &path, QString &textcontent) {
|
||||||
{
|
|
||||||
Poppler::Document *doc = Poppler::Document::load(path);
|
Poppler::Document *doc = Poppler::Document::load(path);
|
||||||
if(doc->isLocked())
|
if(doc->isLocked())
|
||||||
return;
|
return;
|
||||||
const QRectF qf;
|
const QRectF qf;
|
||||||
int pageNum = doc->numPages();
|
int pageNum = doc->numPages();
|
||||||
for(int i = 0; i<pageNum; ++i)
|
for(int i = 0; i < pageNum; ++i) {
|
||||||
{
|
textcontent.append(doc->page(i)->text(qf).replace("\n", ""));
|
||||||
textcontent.append(doc->page(i)->text(qf).replace("\n",""));
|
if(textcontent.length() >= MAX_CONTENT_LENGTH / 3)
|
||||||
if(textcontent.length() >= MAX_CONTENT_LENGTH/3)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete doc;
|
delete doc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileUtils::getTxtContent(QString &path, QString &textcontent)
|
void FileUtils::getTxtContent(QString &path, QString &textcontent) {
|
||||||
{
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
|
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QByteArray encodedString = file.read(MAX_CONTENT_LENGTH);
|
QByteArray encodedString = file.read(MAX_CONTENT_LENGTH);
|
||||||
|
|
||||||
uchardet_t chardet = uchardet_new();
|
uchardet_t chardet = uchardet_new();
|
||||||
if(uchardet_handle_data(chardet,encodedString.constData(),encodedString.size()) !=0)
|
if(uchardet_handle_data(chardet, encodedString.constData(), encodedString.size()) != 0)
|
||||||
qWarning()<<"Txt file encoding format detect fail!"<<path;
|
qWarning() << "Txt file encoding format detect fail!" << path;
|
||||||
|
|
||||||
uchardet_data_end(chardet);
|
uchardet_data_end(chardet);
|
||||||
const char *codec = uchardet_get_charset(chardet);
|
const char *codec = uchardet_get_charset(chardet);
|
||||||
|
|
||||||
if(QTextCodec::codecForName(codec) == 0)
|
if(QTextCodec::codecForName(codec) == 0)
|
||||||
qWarning()<<"Unsupported Text encoding format"<<path<<QString::fromLocal8Bit(codec);
|
qWarning() << "Unsupported Text encoding format" << path << QString::fromLocal8Bit(codec);
|
||||||
|
|
||||||
QTextStream stream(encodedString,QIODevice::ReadOnly);
|
QTextStream stream(encodedString, QIODevice::ReadOnly);
|
||||||
stream.setCodec(codec);
|
stream.setCodec(codec);
|
||||||
uchardet_delete(chardet);
|
uchardet_delete(chardet);
|
||||||
|
|
||||||
textcontent = stream.readAll().replace("\n","");
|
textcontent = stream.readAll().replace("\n", "");
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
encodedString.clear();
|
encodedString.clear();
|
||||||
|
|
|
@ -59,10 +59,9 @@
|
||||||
#define UKUI_SEARCH_PIPE_PATH (QDir::homePath()+"/.config/org.ukui/ukui-search/ukuisearch").toLocal8Bit().constData()
|
#define UKUI_SEARCH_PIPE_PATH (QDir::homePath()+"/.config/org.ukui/ukui-search/ukuisearch").toLocal8Bit().constData()
|
||||||
|
|
||||||
|
|
||||||
class LIBSEARCH_EXPORT FileUtils
|
class LIBSEARCH_EXPORT FileUtils {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static std::string makeDocUterm(QString );
|
static std::string makeDocUterm(QString);
|
||||||
static QIcon getFileIcon(const QString &, bool checkValid = true);
|
static QIcon getFileIcon(const QString &, bool checkValid = true);
|
||||||
static QIcon getAppIcon(const QString &);
|
static QIcon getAppIcon(const QString &);
|
||||||
static QIcon getSettingIcon(const QString &, const bool&);
|
static QIcon getSettingIcon(const QString &, const bool&);
|
||||||
|
@ -88,7 +87,7 @@ public:
|
||||||
static size_t _current_index_count; //this one has been Abandoned,do not use it.
|
static size_t _current_index_count; //this one has been Abandoned,do not use it.
|
||||||
static unsigned short _index_status;
|
static unsigned short _index_status;
|
||||||
|
|
||||||
enum class SearchMethod{ DIRECTSEARCH = 0, INDEXSEARCH = 1};
|
enum class SearchMethod { DIRECTSEARCH = 0, INDEXSEARCH = 1};
|
||||||
static SearchMethod searchMethod;
|
static SearchMethod searchMethod;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -25,43 +25,40 @@
|
||||||
|
|
||||||
static GlobalSettings *global_instance_of_global_settings = nullptr;
|
static GlobalSettings *global_instance_of_global_settings = nullptr;
|
||||||
|
|
||||||
GlobalSettings *GlobalSettings::getInstance()
|
GlobalSettings *GlobalSettings::getInstance() {
|
||||||
{
|
if(!global_instance_of_global_settings) {
|
||||||
if (!global_instance_of_global_settings) {
|
|
||||||
global_instance_of_global_settings = new GlobalSettings;
|
global_instance_of_global_settings = new GlobalSettings;
|
||||||
}
|
}
|
||||||
return global_instance_of_global_settings;
|
return global_instance_of_global_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalSettings::GlobalSettings(QObject *parent) : QObject(parent)
|
GlobalSettings::GlobalSettings(QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
m_settings = new QSettings(MAIN_SETTINGS, QSettings::IniFormat, this);
|
m_settings = new QSettings(MAIN_SETTINGS, QSettings::IniFormat, this);
|
||||||
// m_settings->setAtomicSyncRequired(false);
|
// m_settings->setAtomicSyncRequired(false);
|
||||||
m_block_dirs_settings = new QSettings(BLOCK_DIRS,QSettings::IniFormat, this);
|
m_block_dirs_settings = new QSettings(BLOCK_DIRS, QSettings::IniFormat, this);
|
||||||
m_block_dirs_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));
|
m_block_dirs_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
m_search_record_settings = new QSettings(SEARCH_HISTORY, QSettings::IniFormat , this);
|
m_search_record_settings = new QSettings(SEARCH_HISTORY, QSettings::IniFormat, this);
|
||||||
m_search_record_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));
|
m_search_record_settings->setIniCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
for(QString i:m_search_record_settings->allKeys())
|
for(QString i : m_search_record_settings->allKeys()) {
|
||||||
{
|
|
||||||
m_history.append(QUrl::fromPercentEncoding(i.toLocal8Bit()));
|
m_history.append(QUrl::fromPercentEncoding(i.toLocal8Bit()));
|
||||||
}
|
}
|
||||||
if(!QDBusConnection::sessionBus().connect("org.kylinssoclient.dbus",
|
if(!QDBusConnection::sessionBus().connect("org.kylinssoclient.dbus",
|
||||||
"/org/kylinssoclient/path",
|
"/org/kylinssoclient/path",
|
||||||
"org.freedesktop.kylinssoclient.interface",
|
"org.freedesktop.kylinssoclient.interface",
|
||||||
"keyChanged",
|
"keyChanged",
|
||||||
this, SLOT(updateSearchHistory(QString))))
|
this, SLOT(updateSearchHistory(QString))))
|
||||||
|
|
||||||
qWarning()<<"Kylinssoclient Dbus connect fail!";
|
qWarning() << "Kylinssoclient Dbus connect fail!";
|
||||||
|
|
||||||
this->forceSync();
|
this->forceSync();
|
||||||
//the default number of transparency in mainwindow is 0.7
|
//the default number of transparency in mainwindow is 0.7
|
||||||
//if someone changes the num in mainwindow, here should be modified too
|
//if someone changes the num in mainwindow, here should be modified too
|
||||||
m_cache.insert(TRANSPARENCY_KEY, 0.7);
|
m_cache.insert(TRANSPARENCY_KEY, 0.7);
|
||||||
if (QGSettings::isSchemaInstalled(CONTROL_CENTER_PERSONALISE_GSETTINGS_ID)) {
|
if(QGSettings::isSchemaInstalled(CONTROL_CENTER_PERSONALISE_GSETTINGS_ID)) {
|
||||||
m_trans_gsettings = new QGSettings(CONTROL_CENTER_PERSONALISE_GSETTINGS_ID, QByteArray(), this);
|
m_trans_gsettings = new QGSettings(CONTROL_CENTER_PERSONALISE_GSETTINGS_ID, QByteArray(), this);
|
||||||
connect(m_trans_gsettings, &QGSettings::changed, this, [=](const QString& key) {
|
connect(m_trans_gsettings, &QGSettings::changed, this, [ = ](const QString & key) {
|
||||||
if (key == TRANSPARENCY_KEY) {
|
if(key == TRANSPARENCY_KEY) {
|
||||||
m_cache.remove(TRANSPARENCY_KEY);
|
m_cache.remove(TRANSPARENCY_KEY);
|
||||||
m_cache.insert(TRANSPARENCY_KEY, m_trans_gsettings->get(TRANSPARENCY_KEY).toDouble());
|
m_cache.insert(TRANSPARENCY_KEY, m_trans_gsettings->get(TRANSPARENCY_KEY).toDouble());
|
||||||
qApp->paletteChanged(qApp->palette());
|
qApp->paletteChanged(qApp->palette());
|
||||||
|
@ -73,15 +70,15 @@ GlobalSettings::GlobalSettings(QObject *parent) : QObject(parent)
|
||||||
|
|
||||||
m_cache.insert(STYLE_NAME_KEY, "ukui-light");
|
m_cache.insert(STYLE_NAME_KEY, "ukui-light");
|
||||||
m_cache.insert(FONT_SIZE_KEY, 11);
|
m_cache.insert(FONT_SIZE_KEY, 11);
|
||||||
if (QGSettings::isSchemaInstalled(THEME_GSETTINGS_ID)) {
|
if(QGSettings::isSchemaInstalled(THEME_GSETTINGS_ID)) {
|
||||||
m_theme_gsettings = new QGSettings(THEME_GSETTINGS_ID, QByteArray(), this);
|
m_theme_gsettings = new QGSettings(THEME_GSETTINGS_ID, QByteArray(), this);
|
||||||
connect(m_theme_gsettings, &QGSettings::changed, this, [=](const QString& key) {
|
connect(m_theme_gsettings, &QGSettings::changed, this, [ = ](const QString & key) {
|
||||||
if (key == STYLE_NAME_KEY) {
|
if(key == STYLE_NAME_KEY) {
|
||||||
//当前主题改变时也发出paletteChanged信号,通知主界面刷新
|
//当前主题改变时也发出paletteChanged信号,通知主界面刷新
|
||||||
qApp->paletteChanged(qApp->palette());
|
qApp->paletteChanged(qApp->palette());
|
||||||
m_cache.remove(STYLE_NAME_KEY);
|
m_cache.remove(STYLE_NAME_KEY);
|
||||||
m_cache.insert(STYLE_NAME_KEY, m_theme_gsettings->get(STYLE_NAME_KEY).toString());
|
m_cache.insert(STYLE_NAME_KEY, m_theme_gsettings->get(STYLE_NAME_KEY).toString());
|
||||||
} else if (key == FONT_SIZE_KEY) {
|
} else if(key == FONT_SIZE_KEY) {
|
||||||
qApp->paletteChanged(qApp->palette());
|
qApp->paletteChanged(qApp->palette());
|
||||||
m_cache.remove(FONT_SIZE_KEY);
|
m_cache.remove(FONT_SIZE_KEY);
|
||||||
m_cache.insert(FONT_SIZE_KEY, m_theme_gsettings->get(FONT_SIZE_KEY).toDouble());
|
m_cache.insert(FONT_SIZE_KEY, m_theme_gsettings->get(FONT_SIZE_KEY).toDouble());
|
||||||
|
@ -94,38 +91,34 @@ GlobalSettings::GlobalSettings(QObject *parent) : QObject(parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariant GlobalSettings::getValue(const QString &key)
|
const QVariant GlobalSettings::getValue(const QString &key) {
|
||||||
{
|
|
||||||
return m_cache.value(key);
|
return m_cache.value(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalSettings::isExist(const QString &key)
|
bool GlobalSettings::isExist(const QString &key) {
|
||||||
{
|
|
||||||
return !m_cache.value(key).isNull();
|
return !m_cache.value(key).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSettings::reset(const QString &key)
|
void GlobalSettings::reset(const QString &key) {
|
||||||
{
|
|
||||||
m_cache.remove(key);
|
m_cache.remove(key);
|
||||||
QtConcurrent::run([=]() {
|
QtConcurrent::run([ = ]() {
|
||||||
// if (m_mutex.tryLock(1000)) {
|
// if (m_mutex.tryLock(1000)) {
|
||||||
m_settings->remove(key);
|
m_settings->remove(key);
|
||||||
m_settings->sync();
|
m_settings->sync();
|
||||||
// m_mutex.unlock();
|
// m_mutex.unlock();
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
Q_EMIT this->valueChanged(key);
|
Q_EMIT this->valueChanged(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSettings::resetAll()
|
void GlobalSettings::resetAll() {
|
||||||
{
|
|
||||||
QStringList tmp = m_cache.keys();
|
QStringList tmp = m_cache.keys();
|
||||||
m_cache.clear();
|
m_cache.clear();
|
||||||
for (auto key : tmp) {
|
for(auto key : tmp) {
|
||||||
Q_EMIT this->valueChanged(key);
|
Q_EMIT this->valueChanged(key);
|
||||||
}
|
}
|
||||||
QtConcurrent::run([=]() {
|
QtConcurrent::run([ = ]() {
|
||||||
if (m_mutex.tryLock(1000)) {
|
if(m_mutex.tryLock(1000)) {
|
||||||
m_settings->clear();
|
m_settings->clear();
|
||||||
m_settings->sync();
|
m_settings->sync();
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
|
@ -133,12 +126,9 @@ void GlobalSettings::resetAll()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalSettings::setBlockDirs(const QString &path, int &returnCode, bool remove)
|
bool GlobalSettings::setBlockDirs(const QString &path, int &returnCode, bool remove) {
|
||||||
{
|
if(remove) {
|
||||||
if(remove)
|
if(path.isEmpty()) {
|
||||||
{
|
|
||||||
if(path.isEmpty())
|
|
||||||
{
|
|
||||||
returnCode = PATH_EMPTY;
|
returnCode = PATH_EMPTY;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -146,21 +136,18 @@ bool GlobalSettings::setBlockDirs(const QString &path, int &returnCode, bool rem
|
||||||
m_block_dirs_settings->remove(path);
|
m_block_dirs_settings->remove(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(!path.startsWith("/home"))
|
if(!path.startsWith("/home")) {
|
||||||
{
|
|
||||||
// returnCode = QString(tr("I can only search your user directory, it doesn't make any sense if you block an directory which is not in user directory!"));
|
// returnCode = QString(tr("I can only search your user directory, it doesn't make any sense if you block an directory which is not in user directory!"));
|
||||||
returnCode = PATH_NOT_IN_HOME;
|
returnCode = PATH_NOT_IN_HOME;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//why QSetting's key can't start with "/"??
|
//why QSetting's key can't start with "/"??
|
||||||
QString pathKey = path.right(path.length()-1);
|
QString pathKey = path.right(path.length() - 1);
|
||||||
|
|
||||||
QStringList blockDirs = m_block_dirs_settings->allKeys();
|
QStringList blockDirs = m_block_dirs_settings->allKeys();
|
||||||
for(QString i:blockDirs)
|
for(QString i : blockDirs) {
|
||||||
{
|
if(pathKey.startsWith(i)) {
|
||||||
if(pathKey.startsWith(i))
|
|
||||||
{
|
|
||||||
// returnCode = QString(tr("My parent folder has been blocked!"));
|
// returnCode = QString(tr("My parent folder has been blocked!"));
|
||||||
returnCode = PATH_PARENT_BLOCKED;
|
returnCode = PATH_PARENT_BLOCKED;
|
||||||
return false;
|
return false;
|
||||||
|
@ -169,12 +156,11 @@ bool GlobalSettings::setBlockDirs(const QString &path, int &returnCode, bool rem
|
||||||
if(i.startsWith(pathKey))
|
if(i.startsWith(pathKey))
|
||||||
m_block_dirs_settings->remove(i);
|
m_block_dirs_settings->remove(i);
|
||||||
}
|
}
|
||||||
m_block_dirs_settings->setValue(pathKey,"0");
|
m_block_dirs_settings->setValue(pathKey, "0");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GlobalSettings::getBlockDirs()
|
QStringList GlobalSettings::getBlockDirs() {
|
||||||
{
|
|
||||||
return m_block_dirs_settings->allKeys();
|
return m_block_dirs_settings->allKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,19 +184,17 @@ QStringList GlobalSettings::getBlockDirs()
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void GlobalSettings::setSearchRecord(const QString &word, const QDateTime &time)
|
void GlobalSettings::setSearchRecord(const QString &word, const QDateTime &time) {
|
||||||
{
|
|
||||||
QStringList keys = m_search_record_settings->allKeys();
|
QStringList keys = m_search_record_settings->allKeys();
|
||||||
if(keys.contains(QString(QUrl::toPercentEncoding(word))))
|
if(keys.contains(QString(QUrl::toPercentEncoding(word))))
|
||||||
m_history.removeOne(word);
|
m_history.removeOne(word);
|
||||||
m_search_record_settings->setValue(QString(QUrl::toPercentEncoding(word)), time.toString("yyyy-MM-dd hh:mm:ss"));
|
m_search_record_settings->setValue(QString(QUrl::toPercentEncoding(word)), time.toString("yyyy-MM-dd hh:mm:ss"));
|
||||||
if(keys.size() >= 20)
|
if(keys.size() >= 20)
|
||||||
m_search_record_settings->remove(QString(QUrl::toPercentEncoding(m_history.takeFirst())));
|
m_search_record_settings->remove(QString(QUrl::toPercentEncoding(m_history.takeFirst())));
|
||||||
m_history.append(word);
|
m_history.append(word);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GlobalSettings::getSearchRecord()
|
QStringList GlobalSettings::getSearchRecord() {
|
||||||
{
|
|
||||||
return m_history;
|
return m_history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,12 +247,11 @@ QStringList GlobalSettings::getSearchRecord()
|
||||||
|
|
||||||
//here should be override
|
//here should be override
|
||||||
//MouseZhangZh
|
//MouseZhangZh
|
||||||
void GlobalSettings::setValue(const QString &key, const QVariant &value)
|
void GlobalSettings::setValue(const QString &key, const QVariant &value) {
|
||||||
{
|
|
||||||
// qDebug()<<"setvalue========"<<key<<":"<<value;
|
// qDebug()<<"setvalue========"<<key<<":"<<value;
|
||||||
m_cache.insert(key, value);
|
m_cache.insert(key, value);
|
||||||
// m_settings->sync();
|
// m_settings->sync();
|
||||||
QtConcurrent::run([=]() {
|
QtConcurrent::run([ = ]() {
|
||||||
// qDebug()<<m_settings->status();
|
// qDebug()<<m_settings->status();
|
||||||
// if (m_mutex.tryLock(1000)) {
|
// if (m_mutex.tryLock(1000)) {
|
||||||
// m_mutex.lock();
|
// m_mutex.lock();
|
||||||
|
@ -281,12 +264,11 @@ void GlobalSettings::setValue(const QString &key, const QVariant &value)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSettings::forceSync(const QString &key)
|
void GlobalSettings::forceSync(const QString &key) {
|
||||||
{
|
|
||||||
m_settings->sync();
|
m_settings->sync();
|
||||||
if (key.isNull()) {
|
if(key.isNull()) {
|
||||||
m_cache.clear();
|
m_cache.clear();
|
||||||
for (auto key : m_settings->allKeys()) {
|
for(auto key : m_settings->allKeys()) {
|
||||||
m_cache.insert(key, m_settings->value(key));
|
m_cache.insert(key, m_settings->value(key));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -295,14 +277,11 @@ void GlobalSettings::forceSync(const QString &key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalSettings::updateSearchHistory(QString key)
|
void GlobalSettings::updateSearchHistory(QString key) {
|
||||||
{
|
if(key == "search") {
|
||||||
if(key == "search")
|
|
||||||
{
|
|
||||||
m_search_record_settings->sync();
|
m_search_record_settings->sync();
|
||||||
m_history.clear();
|
m_history.clear();
|
||||||
for(QString i:m_search_record_settings->allKeys())
|
for(QString i : m_search_record_settings->allKeys()) {
|
||||||
{
|
|
||||||
m_history.append(QUrl::fromPercentEncoding(i.toLocal8Bit()));
|
m_history.append(QUrl::fromPercentEncoding(i.toLocal8Bit()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,7 @@
|
||||||
//#define CLOUD_HISTORY "history"
|
//#define CLOUD_HISTORY "history"
|
||||||
//#define CLOUD_APPLICATIONS "applications"
|
//#define CLOUD_APPLICATIONS "applications"
|
||||||
|
|
||||||
class LIBSEARCH_EXPORT GlobalSettings : public QObject
|
class LIBSEARCH_EXPORT GlobalSettings : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static GlobalSettings *getInstance();
|
static GlobalSettings *getInstance();
|
||||||
|
@ -65,8 +64,8 @@ public:
|
||||||
bool isExist(const QString&);
|
bool isExist(const QString&);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void valueChanged (const QString&);
|
void valueChanged(const QString&);
|
||||||
void transparencyChanged (const double&);
|
void transparencyChanged(const double&);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setValue(const QString&, const QVariant&);
|
void setValue(const QString&, const QVariant&);
|
||||||
|
@ -80,7 +79,7 @@ public Q_SLOTS:
|
||||||
* @param true to remove blocking,false to set blocking,default set false.
|
* @param true to remove blocking,false to set blocking,default set false.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool setBlockDirs(const QString& path, int &returnCode,bool remove = false);
|
bool setBlockDirs(const QString& path, int &returnCode, bool remove = false);
|
||||||
QStringList getBlockDirs();
|
QStringList getBlockDirs();
|
||||||
// void appendCloudData(const QString& key, const QString& value);
|
// void appendCloudData(const QString& key, const QString& value);
|
||||||
void setSearchRecord(const QString &word, const QDateTime &time);
|
void setSearchRecord(const QString &word, const QDateTime &time);
|
||||||
|
|
|
@ -25,21 +25,20 @@
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
||||||
class gobjecttemplate
|
class gobjecttemplate {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
//do not use this constructor.
|
//do not use this constructor.
|
||||||
gobjecttemplate();
|
gobjecttemplate();
|
||||||
gobjecttemplate(T *obj, bool ref = false) {
|
gobjecttemplate(T *obj, bool ref = false) {
|
||||||
m_obj = obj;
|
m_obj = obj;
|
||||||
if (ref) {
|
if(ref) {
|
||||||
g_object_ref(obj);
|
g_object_ref(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~gobjecttemplate() {
|
~gobjecttemplate() {
|
||||||
//qDebug()<<"~GObjectTemplate";
|
//qDebug()<<"~GObjectTemplate";
|
||||||
if (m_obj)
|
if(m_obj)
|
||||||
g_object_unref(m_obj);
|
g_object_unref(m_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,14 @@
|
||||||
//extern QList<Document> *_doc_list_path;
|
//extern QList<Document> *_doc_list_path;
|
||||||
//extern QMutex _mutex_doc_list_path;
|
//extern QMutex _mutex_doc_list_path;
|
||||||
|
|
||||||
ConstructDocumentForPath::ConstructDocumentForPath(QVector<QString> list)
|
ConstructDocumentForPath::ConstructDocumentForPath(QVector<QString> list) {
|
||||||
{
|
|
||||||
this->setAutoDelete(true);
|
this->setAutoDelete(true);
|
||||||
m_list = std::move(list);
|
m_list = std::move(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstructDocumentForPath::run()
|
void ConstructDocumentForPath::run() {
|
||||||
{
|
|
||||||
// qDebug()<<"ConstructDocumentForPath";
|
// qDebug()<<"ConstructDocumentForPath";
|
||||||
if (!_doc_list_path)
|
if(!_doc_list_path)
|
||||||
_doc_list_path = new QList<Document>;
|
_doc_list_path = new QList<Document>;
|
||||||
// qDebug()<<_doc_list_path->size();
|
// qDebug()<<_doc_list_path->size();
|
||||||
QString index_text = m_list.at(0).toLower();
|
QString index_text = m_list.at(0).toLower();
|
||||||
|
@ -45,7 +43,7 @@ void ConstructDocumentForPath::run()
|
||||||
|
|
||||||
//多音字版
|
//多音字版
|
||||||
//现加入首字母
|
//现加入首字母
|
||||||
QStringList pinyin_text_list = FileUtils::findMultiToneWords(QString(m_list.at(0)).replace(".",""));
|
QStringList pinyin_text_list = FileUtils::findMultiToneWords(QString(m_list.at(0)).replace(".", ""));
|
||||||
// if(!pinyin_text_list.isEmpty())
|
// if(!pinyin_text_list.isEmpty())
|
||||||
// {
|
// {
|
||||||
// for (QString& i : pinyin_text_list){
|
// for (QString& i : pinyin_text_list){
|
||||||
|
@ -56,7 +54,7 @@ void ConstructDocumentForPath::run()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath));
|
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath));
|
||||||
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep)));
|
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
|
||||||
// qDebug()<<"sourcePath"<<sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
|
// qDebug()<<"sourcePath"<<sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
|
||||||
// qDebug() << "sourcePath ---------------------------: " << sourcePath;
|
// qDebug() << "sourcePath ---------------------------: " << sourcePath;
|
||||||
// qDebug() << "sourcePath.section -------------------: " << sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
|
// qDebug() << "sourcePath.section -------------------: " << sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep);
|
||||||
|
@ -68,24 +66,21 @@ void ConstructDocumentForPath::run()
|
||||||
doc.setUniqueTerm(uniqueterm);
|
doc.setUniqueTerm(uniqueterm);
|
||||||
doc.addTerm(upTerm);
|
doc.addTerm(upTerm);
|
||||||
doc.addValue(m_list.at(2));
|
doc.addValue(m_list.at(2));
|
||||||
/* QStringList temp;
|
/* QStringList temp;
|
||||||
// temp.append(index_text);
|
// temp.append(index_text);
|
||||||
temp.append(pinyin_text_list)*/;
|
temp.append(pinyin_text_list)*/;
|
||||||
int postingCount = 0;
|
int postingCount = 0;
|
||||||
while(postingCount < index_text.size())
|
while(postingCount < index_text.size()) {
|
||||||
{
|
|
||||||
// QVector<size_t> p;
|
// QVector<size_t> p;
|
||||||
// p.append(postingCount);
|
// p.append(postingCount);
|
||||||
doc.addPosting(QUrl::toPercentEncoding(index_text.at(postingCount)).toStdString(),postingCount);
|
doc.addPosting(QUrl::toPercentEncoding(index_text.at(postingCount)).toStdString(), postingCount);
|
||||||
++postingCount;
|
++postingCount;
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (QString& s : pinyin_text_list)
|
for(QString& s : pinyin_text_list) {
|
||||||
{
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while(i < s.size())
|
while(i < s.size()) {
|
||||||
{
|
doc.addPosting(QUrl::toPercentEncoding(s.at(i)).toStdString(), postingCount);
|
||||||
doc.addPosting(QUrl::toPercentEncoding(s.at(i)).toStdString(),postingCount);
|
|
||||||
++postingCount;
|
++postingCount;
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -99,24 +94,22 @@ void ConstructDocumentForPath::run()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstructDocumentForContent::ConstructDocumentForContent(QString path)
|
ConstructDocumentForContent::ConstructDocumentForContent(QString path) {
|
||||||
{
|
|
||||||
this->setAutoDelete(true);
|
this->setAutoDelete(true);
|
||||||
m_path = std::move(path);
|
m_path = std::move(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstructDocumentForContent::run()
|
void ConstructDocumentForContent::run() {
|
||||||
{
|
|
||||||
// qDebug() << "ConstructDocumentForContent currentThreadId()" << QThread::currentThreadId();
|
// qDebug() << "ConstructDocumentForContent currentThreadId()" << QThread::currentThreadId();
|
||||||
// 构造文本索引的document
|
// 构造文本索引的document
|
||||||
if (!_doc_list_content)
|
if(!_doc_list_content)
|
||||||
_doc_list_content = new QList<Document>;
|
_doc_list_content = new QList<Document>;
|
||||||
QString content;
|
QString content;
|
||||||
FileReader::getTextContent(m_path,content);
|
FileReader::getTextContent(m_path, content);
|
||||||
if(content.isEmpty())
|
if(content.isEmpty())
|
||||||
return;
|
return;
|
||||||
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(m_path));
|
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(m_path));
|
||||||
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(m_path.section("/",0,-2,QString::SectionIncludeLeadingSep)));
|
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(m_path.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
|
||||||
|
|
||||||
QVector<SKeyWord> term = ChineseSegmentation::getInstance()->callSegement(content.left(20480000));
|
QVector<SKeyWord> term = ChineseSegmentation::getInstance()->callSegement(content.left(20480000));
|
||||||
|
|
||||||
|
@ -125,9 +118,8 @@ void ConstructDocumentForContent::run()
|
||||||
doc.setUniqueTerm(uniqueterm);
|
doc.setUniqueTerm(uniqueterm);
|
||||||
doc.addTerm(upTerm);
|
doc.addTerm(upTerm);
|
||||||
doc.addValue(m_path);
|
doc.addValue(m_path);
|
||||||
for(int i = 0;i<term.size();++i)
|
for(int i = 0; i < term.size(); ++i) {
|
||||||
{
|
doc.addPosting(term.at(i).word, term.at(i).offsets, static_cast<int>(term.at(i).weight));
|
||||||
doc.addPosting(term.at(i).word,term.at(i).offsets,static_cast<int>(term.at(i).weight));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
//extern QList<Document> *_doc_list_path;
|
//extern QList<Document> *_doc_list_path;
|
||||||
//extern QMutex _mutex_doc_list_path;
|
//extern QMutex _mutex_doc_list_path;
|
||||||
class IndexGenerator;
|
class IndexGenerator;
|
||||||
class ConstructDocumentForPath : public QRunnable
|
class ConstructDocumentForPath : public QRunnable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit ConstructDocumentForPath(QVector<QString> list);
|
explicit ConstructDocumentForPath(QVector<QString> list);
|
||||||
~ConstructDocumentForPath() = default;
|
~ConstructDocumentForPath() = default;
|
||||||
|
@ -39,8 +38,7 @@ private:
|
||||||
QVector<QString> m_list;
|
QVector<QString> m_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstructDocumentForContent : public QRunnable
|
class ConstructDocumentForContent : public QRunnable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit ConstructDocumentForContent(QString path);
|
explicit ConstructDocumentForContent(QString path);
|
||||||
~ConstructDocumentForContent() = default;
|
~ConstructDocumentForContent() = default;
|
||||||
|
|
|
@ -20,50 +20,43 @@
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
void Document::setData(QString data)
|
void Document::setData(QString data) {
|
||||||
{
|
|
||||||
if(data.isEmpty())
|
if(data.isEmpty())
|
||||||
return;
|
return;
|
||||||
m_document.set_data(data.toStdString());
|
m_document.set_data(data.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::addPosting(std::string term,QVector<size_t> offset, int weight)
|
void Document::addPosting(std::string term, QVector<size_t> offset, int weight) {
|
||||||
{
|
|
||||||
if(term == "")
|
if(term == "")
|
||||||
return;
|
return;
|
||||||
if(term.length() > 240)
|
if(term.length() > 240)
|
||||||
term = QString::fromStdString(term).left(30).toStdString();
|
term = QString::fromStdString(term).left(30).toStdString();
|
||||||
|
|
||||||
for(size_t i : offset)
|
for(size_t i : offset) {
|
||||||
{
|
m_document.add_posting(term, i, weight);
|
||||||
m_document.add_posting(term,i,weight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::addPosting(std::string term, unsigned int offset, int weight)
|
void Document::addPosting(std::string term, unsigned int offset, int weight) {
|
||||||
{
|
|
||||||
if(term == "")
|
if(term == "")
|
||||||
return;
|
return;
|
||||||
if(term.length() > 240)
|
if(term.length() > 240)
|
||||||
term = QString::fromStdString(term).left(30).toStdString();
|
term = QString::fromStdString(term).left(30).toStdString();
|
||||||
|
|
||||||
m_document.add_posting(term,offset,weight);
|
m_document.add_posting(term, offset, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::addTerm(QString term)
|
void Document::addTerm(QString term) {
|
||||||
{
|
|
||||||
if(term.isEmpty())
|
if(term.isEmpty())
|
||||||
return;
|
return;
|
||||||
m_document.add_term(term.toStdString());
|
m_document.add_term(term.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::addValue(QString value)
|
void Document::addValue(QString value) {
|
||||||
{
|
m_document.add_value(1, value.toStdString());
|
||||||
m_document.add_value(1,value.toStdString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::setUniqueTerm(QString term)
|
void Document::setUniqueTerm(QString term) {
|
||||||
{
|
|
||||||
if(term.isEmpty())
|
if(term.isEmpty())
|
||||||
return;
|
return;
|
||||||
m_document.add_term(term.toStdString());
|
m_document.add_term(term.toStdString());
|
||||||
|
@ -71,26 +64,22 @@ void Document::setUniqueTerm(QString term)
|
||||||
// m_unique_term = new QString(term);
|
// m_unique_term = new QString(term);
|
||||||
m_unique_term = std::move(term);
|
m_unique_term = std::move(term);
|
||||||
}
|
}
|
||||||
std::string Document::getUniqueTerm()
|
std::string Document::getUniqueTerm() {
|
||||||
{
|
|
||||||
// qDebug()<<"m_unique_term!"<<*m_unique_term;
|
// qDebug()<<"m_unique_term!"<<*m_unique_term;
|
||||||
// qDebug() << QString::fromStdString(m_unique_term.toStdString());
|
// qDebug() << QString::fromStdString(m_unique_term.toStdString());
|
||||||
return m_unique_term.toStdString();
|
return m_unique_term.toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::setIndexText(QStringList indexText)
|
void Document::setIndexText(QStringList indexText) {
|
||||||
{
|
|
||||||
// QStringList indexTextList = indexText;
|
// QStringList indexTextList = indexText;
|
||||||
// m_index_text = new QStringList(indexText);
|
// m_index_text = new QStringList(indexText);
|
||||||
m_index_text = std::move(indexText);
|
m_index_text = std::move(indexText);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Document::getIndexText()
|
QStringList Document::getIndexText() {
|
||||||
{
|
|
||||||
return m_index_text;
|
return m_index_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xapian::Document Document::getXapianDocument()
|
Xapian::Document Document::getXapianDocument() {
|
||||||
{
|
|
||||||
return m_document;
|
return m_document;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,24 +25,23 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class Document
|
class Document {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Document() = default;
|
Document() = default;
|
||||||
~Document(){}
|
~Document() {}
|
||||||
Document(const Document& other){
|
Document(const Document& other) {
|
||||||
m_document = other.m_document;
|
m_document = other.m_document;
|
||||||
m_index_text = other.m_index_text;
|
m_index_text = other.m_index_text;
|
||||||
m_unique_term = other.m_unique_term;
|
m_unique_term = other.m_unique_term;
|
||||||
}
|
}
|
||||||
void operator=(const Document& other){
|
void operator=(const Document& other) {
|
||||||
m_document = other.m_document;
|
m_document = other.m_document;
|
||||||
m_index_text = other.m_index_text;
|
m_index_text = other.m_index_text;
|
||||||
m_unique_term = other.m_unique_term;
|
m_unique_term = other.m_unique_term;
|
||||||
}
|
}
|
||||||
void setData(QString data);
|
void setData(QString data);
|
||||||
void addPosting(std::string term, QVector<size_t> offset, int weight =1);
|
void addPosting(std::string term, QVector<size_t> offset, int weight = 1);
|
||||||
void addPosting(std::string term, unsigned int offset, int weight =1);
|
void addPosting(std::string term, unsigned int offset, int weight = 1);
|
||||||
void addTerm(QString term);
|
void addTerm(QString term);
|
||||||
void addValue(QString value);
|
void addValue(QString value);
|
||||||
void setUniqueTerm(QString term);
|
void setUniqueTerm(QString term);
|
||||||
|
|
|
@ -21,48 +21,36 @@
|
||||||
#include "file-utils.h"
|
#include "file-utils.h"
|
||||||
#include "binary-parser.h"
|
#include "binary-parser.h"
|
||||||
|
|
||||||
FileReader::FileReader(QObject *parent) : QObject(parent)
|
FileReader::FileReader(QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileReader::getTextContent(QString path, QString &textContent)
|
void FileReader::getTextContent(QString path, QString &textContent) {
|
||||||
{
|
|
||||||
QMimeType type = FileUtils::getMimetype(path);
|
QMimeType type = FileUtils::getMimetype(path);
|
||||||
QString name = type.name();
|
QString name = type.name();
|
||||||
QFileInfo file(path);
|
QFileInfo file(path);
|
||||||
QString strsfx = file.suffix();
|
QString strsfx = file.suffix();
|
||||||
if(name== "application/zip")
|
if(name == "application/zip") {
|
||||||
{
|
if(strsfx.endsWith("docx"))
|
||||||
if(strsfx.endsWith( "docx"))
|
FileUtils::getDocxTextContent(path, textContent);
|
||||||
FileUtils::getDocxTextContent(path,textContent);
|
if(strsfx.endsWith("pptx"))
|
||||||
if(strsfx.endsWith( "pptx"))
|
FileUtils::getPptxTextContent(path, textContent);
|
||||||
FileUtils::getPptxTextContent(path,textContent);
|
if(strsfx.endsWith("xlsx"))
|
||||||
if(strsfx.endsWith( "xlsx"))
|
FileUtils::getXlsxTextContent(path, textContent);
|
||||||
FileUtils::getXlsxTextContent(path,textContent);
|
} else if(name == "text/plain") {
|
||||||
}
|
if(strsfx.endsWith("txt"))
|
||||||
else if(name == "text/plain")
|
FileUtils::getTxtContent(path, textContent);
|
||||||
{
|
} else if(type.inherits("application/msword") || type.name() == "application/x-ole-storage") {
|
||||||
if(strsfx.endsWith( "txt"))
|
if(strsfx.endsWith("doc") || strsfx.endsWith("dot") || strsfx.endsWith("wps") || strsfx.endsWith("ppt") ||
|
||||||
FileUtils::getTxtContent(path,textContent);
|
strsfx.endsWith("pps") || strsfx.endsWith("dps") || strsfx.endsWith("et") || strsfx.endsWith("xls")) {
|
||||||
}
|
|
||||||
else if(type.inherits("application/msword") || type.name() == "application/x-ole-storage")
|
|
||||||
{
|
|
||||||
if (strsfx.endsWith("doc") || strsfx.endsWith("dot") || strsfx.endsWith("wps") || strsfx.endsWith("ppt") ||
|
|
||||||
strsfx.endsWith("pps") ||strsfx.endsWith("dps") || strsfx.endsWith("et") || strsfx.endsWith("xls"))
|
|
||||||
{
|
|
||||||
KBinaryParser searchdata;
|
KBinaryParser searchdata;
|
||||||
searchdata.RunParser(path,textContent);
|
searchdata.RunParser(path, textContent);
|
||||||
}
|
}
|
||||||
}
|
} else if(name == "application/pdf") {
|
||||||
else if(name == "application/pdf")
|
if(strsfx.endsWith("pdf"))
|
||||||
{
|
FileUtils::getPdfTextContent(path, textContent);
|
||||||
if(strsfx.endsWith( "pdf"))
|
} else {
|
||||||
FileUtils::getPdfTextContent(path,textContent);
|
qWarning() << "Unsupport format:[" << path << "][" << type.name() << "]";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning()<<"Unsupport format:["<<path<<"]["<<type.name()<<"]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,12 +23,11 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
class FileReader : public QObject
|
class FileReader : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FileReader(QObject *parent = nullptr);
|
explicit FileReader(QObject *parent = nullptr);
|
||||||
~FileReader()=default;
|
~FileReader() = default;
|
||||||
static void getTextContent(QString path, QString &textContent);
|
static void getTextContent(QString path, QString &textContent);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,30 +32,23 @@ size_t FileSearcher::uniqueSymbol3 = 0;
|
||||||
QMutex FileSearcher::m_mutex1;
|
QMutex FileSearcher::m_mutex1;
|
||||||
QMutex FileSearcher::m_mutex2;
|
QMutex FileSearcher::m_mutex2;
|
||||||
QMutex FileSearcher::m_mutex3;
|
QMutex FileSearcher::m_mutex3;
|
||||||
FileSearcher::FileSearcher(QObject *parent) : QObject(parent)
|
FileSearcher::FileSearcher(QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSearcher::~FileSearcher()
|
FileSearcher::~FileSearcher() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearcher::getCurrentIndexCount()
|
int FileSearcher::getCurrentIndexCount() {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
Xapian::Database db(INDEX_PATH);
|
Xapian::Database db(INDEX_PATH);
|
||||||
return db.get_doccount();
|
return db.get_doccount();
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
{
|
|
||||||
qWarning() <<QString::fromStdString(e.get_description());
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResultFile,QQueue<QString> *searchResultDir,QQueue<QPair<QString,QStringList>> *searchResultContent)
|
void FileSearcher::onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, QQueue<QPair<QString, QStringList>> *searchResultContent) {
|
||||||
{
|
|
||||||
m_mutex1.lock();
|
m_mutex1.lock();
|
||||||
++uniqueSymbol1;
|
++uniqueSymbol1;
|
||||||
m_mutex1.unlock();
|
m_mutex1.unlock();
|
||||||
|
@ -71,16 +64,15 @@ void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResult
|
||||||
m_search_result_content = searchResultContent;
|
m_search_result_content = searchResultContent;
|
||||||
|
|
||||||
//file
|
//file
|
||||||
QtConcurrent::run([&, uniqueSymbol1, keyword](){
|
QtConcurrent::run([&, uniqueSymbol1, keyword]() {
|
||||||
if(!m_search_result_file->isEmpty())
|
if(!m_search_result_file->isEmpty())
|
||||||
m_search_result_file->clear();
|
m_search_result_file->clear();
|
||||||
int begin = 0;
|
int begin = 0;
|
||||||
int num = 5;
|
int num = 5;
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
while(total < 100)
|
while(total < 100) {
|
||||||
{
|
resultCount = keywordSearchfile(uniqueSymbol1, keyword, "0", 1, begin, num);
|
||||||
resultCount = keywordSearchfile(uniqueSymbol1,keyword,"0",1,begin,num);
|
|
||||||
if(resultCount == 0 || resultCount == -1)
|
if(resultCount == 0 || resultCount == -1)
|
||||||
break;
|
break;
|
||||||
total += resultCount;
|
total += resultCount;
|
||||||
|
@ -90,16 +82,15 @@ void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResult
|
||||||
});
|
});
|
||||||
// Q_EMIT this->resultFile(m_search_result_file);
|
// Q_EMIT this->resultFile(m_search_result_file);
|
||||||
//dir
|
//dir
|
||||||
QtConcurrent::run([&, uniqueSymbol2, keyword](){
|
QtConcurrent::run([&, uniqueSymbol2, keyword]() {
|
||||||
if(!m_search_result_dir->isEmpty())
|
if(!m_search_result_dir->isEmpty())
|
||||||
m_search_result_dir->clear();
|
m_search_result_dir->clear();
|
||||||
int begin = 0;
|
int begin = 0;
|
||||||
int num = 5;
|
int num = 5;
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
while(total<100)
|
while(total < 100) {
|
||||||
{
|
resultCount = keywordSearchfile(uniqueSymbol2, keyword, "1", 1, begin, num);
|
||||||
resultCount = keywordSearchfile(uniqueSymbol2,keyword,"1",1,begin,num);
|
|
||||||
if(resultCount == 0 || resultCount == -1)
|
if(resultCount == 0 || resultCount == -1)
|
||||||
break;
|
break;
|
||||||
total += resultCount;
|
total += resultCount;
|
||||||
|
@ -109,7 +100,7 @@ void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResult
|
||||||
});
|
});
|
||||||
// Q_EMIT this->resultDir(m_search_result_dir);
|
// Q_EMIT this->resultDir(m_search_result_dir);
|
||||||
//content
|
//content
|
||||||
QtConcurrent::run([&, uniqueSymbol3, keyword](){
|
QtConcurrent::run([&, uniqueSymbol3, keyword]() {
|
||||||
if(!m_search_result_content->isEmpty())
|
if(!m_search_result_content->isEmpty())
|
||||||
m_search_result_content->clear();
|
m_search_result_content->clear();
|
||||||
int begin = 0;
|
int begin = 0;
|
||||||
|
@ -117,9 +108,8 @@ void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResult
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
||||||
while(total<50)
|
while(total < 50) {
|
||||||
{
|
resultCount = keywordSearchContent(uniqueSymbol3, keyword, begin, num);
|
||||||
resultCount = keywordSearchContent(uniqueSymbol3,keyword,begin,num);
|
|
||||||
if(resultCount == 0 || resultCount == -1)
|
if(resultCount == 0 || resultCount == -1)
|
||||||
break;
|
break;
|
||||||
total += resultCount;
|
total += resultCount;
|
||||||
|
@ -130,54 +120,45 @@ void FileSearcher::onKeywordSearch(QString keyword,QQueue<QString> *searchResult
|
||||||
// Q_EMIT this->resultContent(m_search_result_content);
|
// Q_EMIT this->resultContent(m_search_result_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearcher::keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value, unsigned slot, int begin, int num)
|
int FileSearcher::keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value, unsigned slot, int begin, int num) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
qDebug() << "--keywordSearchfile start--";
|
qDebug() << "--keywordSearchfile start--";
|
||||||
Xapian::Database db(INDEX_PATH);
|
Xapian::Database db(INDEX_PATH);
|
||||||
Xapian::Query query = creatQueryForFileSearch(keyword,db);
|
Xapian::Query query = creatQueryForFileSearch(keyword, db);
|
||||||
Xapian::Enquire enquire(db);
|
Xapian::Enquire enquire(db);
|
||||||
|
|
||||||
Xapian::Query queryFile;
|
Xapian::Query queryFile;
|
||||||
if(!value.isEmpty())
|
if(!value.isEmpty()) {
|
||||||
{
|
|
||||||
std::string slotValue = value.toStdString();
|
std::string slotValue = value.toStdString();
|
||||||
Xapian::Query queryValue = Xapian::Query(Xapian::Query::OP_VALUE_RANGE,slot,slotValue,slotValue);
|
Xapian::Query queryValue = Xapian::Query(Xapian::Query::OP_VALUE_RANGE, slot, slotValue, slotValue);
|
||||||
queryFile = Xapian::Query(Xapian::Query::OP_AND,query,queryValue);
|
queryFile = Xapian::Query(Xapian::Query::OP_AND, query, queryValue);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
queryFile = query;
|
queryFile = query;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "keywordSearchfile:"<<QString::fromStdString(queryFile.get_description());
|
qDebug() << "keywordSearchfile:" << QString::fromStdString(queryFile.get_description());
|
||||||
|
|
||||||
enquire.set_query(queryFile);
|
enquire.set_query(queryFile);
|
||||||
Xapian::MSet result = enquire.get_mset(begin, num);
|
Xapian::MSet result = enquire.get_mset(begin, num);
|
||||||
int resultCount = result.size();
|
int resultCount = result.size();
|
||||||
qDebug()<< "keywordSearchfile results count=" <<resultCount;
|
qDebug() << "keywordSearchfile results count=" << resultCount;
|
||||||
if(result.size() == 0)
|
if(result.size() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if(getResult(uniqueSymbol, result, value) == -1)
|
if(getResult(uniqueSymbol, result, value) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
qDebug()<< "--keywordSearchfile finish--";
|
qDebug() << "--keywordSearchfile finish--";
|
||||||
return resultCount;
|
return resultCount;
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
{
|
qDebug() << "--keywordSearchfile finish--";
|
||||||
qWarning() <<QString::fromStdString(e.get_description());
|
|
||||||
qDebug()<< "--keywordSearchfile finish--";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearcher::keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin, int num)
|
int FileSearcher::keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin, int num) {
|
||||||
{
|
try {
|
||||||
try
|
qDebug() << "--keywordSearchContent search start--";
|
||||||
{
|
|
||||||
qDebug()<<"--keywordSearchContent search start--";
|
|
||||||
|
|
||||||
Xapian::Database db(CONTENT_INDEX_PATH);
|
Xapian::Database db(CONTENT_INDEX_PATH);
|
||||||
Xapian::Enquire enquire(db);
|
Xapian::Enquire enquire(db);
|
||||||
|
@ -188,8 +169,7 @@ int FileSearcher::keywordSearchContent(size_t uniqueSymbol, QString keyword, int
|
||||||
QVector<SKeyWord> sKeyWord = ChineseSegmentation::getInstance()->callSegement(keyword);
|
QVector<SKeyWord> sKeyWord = ChineseSegmentation::getInstance()->callSegement(keyword);
|
||||||
//Creat a query
|
//Creat a query
|
||||||
std::string words;
|
std::string words;
|
||||||
for(int i=0;i<sKeyWord.size();i++)
|
for(int i = 0; i < sKeyWord.size(); i++) {
|
||||||
{
|
|
||||||
words.append(sKeyWord.at(i).word).append(" ");
|
words.append(sKeyWord.at(i).word).append(" ");
|
||||||
}
|
}
|
||||||
Xapian::Query query = qp.parse_query(words);
|
Xapian::Query query = qp.parse_query(words);
|
||||||
|
@ -201,7 +181,7 @@ int FileSearcher::keywordSearchContent(size_t uniqueSymbol, QString keyword, int
|
||||||
// qDebug()<<QString::fromStdString(sKeyWord.at(i).word);
|
// qDebug()<<QString::fromStdString(sKeyWord.at(i).word);
|
||||||
// }
|
// }
|
||||||
// Xapian::Query queryPhrase =Xapian::Query(Xapian::Query::OP_AND, v.begin(), v.end());
|
// Xapian::Query queryPhrase =Xapian::Query(Xapian::Query::OP_AND, v.begin(), v.end());
|
||||||
qDebug()<<"keywordSearchContent:"<<QString::fromStdString(query.get_description());
|
qDebug() << "keywordSearchContent:" << QString::fromStdString(query.get_description());
|
||||||
|
|
||||||
enquire.set_query(query);
|
enquire.set_query(query);
|
||||||
|
|
||||||
|
@ -209,23 +189,20 @@ int FileSearcher::keywordSearchContent(size_t uniqueSymbol, QString keyword, int
|
||||||
int resultCount = result.size();
|
int resultCount = result.size();
|
||||||
if(result.size() == 0)
|
if(result.size() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
qDebug()<< "keywordSearchContent results count=" <<resultCount;
|
qDebug() << "keywordSearchContent results count=" << resultCount;
|
||||||
|
|
||||||
if(getContentResult(uniqueSymbol, result, words) == -1)
|
if(getContentResult(uniqueSymbol, result, words) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
qDebug()<< "--keywordSearchContent search finish--";
|
qDebug() << "--keywordSearchContent search finish--";
|
||||||
return resultCount;
|
return resultCount;
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
{
|
qDebug() << "--keywordSearchContent search finish--";
|
||||||
qWarning() <<QString::fromStdString(e.get_description());
|
|
||||||
qDebug()<< "--keywordSearchContent search finish--";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Xapian::Query FileSearcher::creatQueryForFileSearch(QString keyword, Xapian::Database &db)
|
Xapian::Query FileSearcher::creatQueryForFileSearch(QString keyword, Xapian::Database &db) {
|
||||||
{
|
|
||||||
// Xapian::QueryParser qp;
|
// Xapian::QueryParser qp;
|
||||||
// qp.set_default_op(Xapian::Query::OP_PHRASE);
|
// qp.set_default_op(Xapian::Query::OP_PHRASE);
|
||||||
// qp.set_database(db);
|
// qp.set_database(db);
|
||||||
|
@ -241,12 +218,11 @@ Xapian::Query FileSearcher::creatQueryForFileSearch(QString keyword, Xapian::Dat
|
||||||
//Creat a query
|
//Creat a query
|
||||||
// Xapian::Query queryPhrase = qp.parse_query(userInput.toStdString(),Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_SYNONYM);
|
// Xapian::Query queryPhrase = qp.parse_query(userInput.toStdString(),Xapian::QueryParser::FLAG_PHRASE|Xapian::QueryParser::FLAG_SYNONYM);
|
||||||
std::vector<Xapian::Query> v;
|
std::vector<Xapian::Query> v;
|
||||||
for(int i=0;i<userInput.size();i++)
|
for(int i = 0; i < userInput.size(); i++) {
|
||||||
{
|
|
||||||
v.push_back(Xapian::Query(QUrl::toPercentEncoding(userInput.at(i)).toStdString()));
|
v.push_back(Xapian::Query(QUrl::toPercentEncoding(userInput.at(i)).toStdString()));
|
||||||
// qDebug()<<QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
// qDebug()<<QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
||||||
}
|
}
|
||||||
Xapian::Query queryPhrase =Xapian::Query(Xapian::Query::OP_PHRASE, v.begin(), v.end());
|
Xapian::Query queryPhrase = Xapian::Query(Xapian::Query::OP_PHRASE, v.begin(), v.end());
|
||||||
// Xapian::Query queryNear =Xapian::Query(Xapian::Query::OP_NEAR, v.begin(), v.end());
|
// Xapian::Query queryNear =Xapian::Query(Xapian::Query::OP_NEAR, v.begin(), v.end());
|
||||||
|
|
||||||
// Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND,queryNear,queryPhrase);
|
// Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND,queryNear,queryPhrase);
|
||||||
|
@ -254,20 +230,17 @@ Xapian::Query FileSearcher::creatQueryForFileSearch(QString keyword, Xapian::Dat
|
||||||
return queryPhrase;
|
return queryPhrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
Xapian::Query FileSearcher::creatQueryForContentSearch(QString keyword, Xapian::Database &db)
|
Xapian::Query FileSearcher::creatQueryForContentSearch(QString keyword, Xapian::Database &db) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearcher::getResult(size_t uniqueSymbol, Xapian::MSet &result, QString value)
|
int FileSearcher::getResult(size_t uniqueSymbol, Xapian::MSet &result, QString value) {
|
||||||
{
|
|
||||||
//QStringList *pathTobeDelete = new QStringList;
|
//QStringList *pathTobeDelete = new QStringList;
|
||||||
//Delete those path doc which is not already exist.
|
//Delete those path doc which is not already exist.
|
||||||
|
|
||||||
// QStringList searchResult = QStringList();
|
// QStringList searchResult = QStringList();
|
||||||
|
|
||||||
for (auto it = result.begin(); it != result.end(); ++it)
|
for(auto it = result.begin(); it != result.end(); ++it) {
|
||||||
{
|
|
||||||
Xapian::Document doc = it.get_document();
|
Xapian::Document doc = it.get_document();
|
||||||
std::string data = doc.get_data();
|
std::string data = doc.get_data();
|
||||||
Xapian::weight docScoreWeight = it.get_weight();
|
Xapian::weight docScoreWeight = it.get_weight();
|
||||||
|
@ -279,24 +252,17 @@ int FileSearcher::getResult(size_t uniqueSymbol, Xapian::MSet &result, QString v
|
||||||
|
|
||||||
QFileInfo info(path);
|
QFileInfo info(path);
|
||||||
|
|
||||||
if(!info.exists())
|
if(!info.exists()) {
|
||||||
{
|
|
||||||
// pathTobeDelete->append(QString::fromStdString(data));
|
// pathTobeDelete->append(QString::fromStdString(data));
|
||||||
qDebug()<<path<<"is not exist!!";
|
qDebug() << path << "is not exist!!";
|
||||||
}
|
} else {
|
||||||
else
|
switch(value.toInt()) {
|
||||||
{
|
|
||||||
switch (value.toInt())
|
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
m_mutex1.lock();
|
m_mutex1.lock();
|
||||||
if(uniqueSymbol == FileSearcher::uniqueSymbol1)
|
if(uniqueSymbol == FileSearcher::uniqueSymbol1) {
|
||||||
{
|
|
||||||
m_search_result_dir->enqueue(path);
|
m_search_result_dir->enqueue(path);
|
||||||
m_mutex1.unlock();
|
m_mutex1.unlock();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
m_mutex1.unlock();
|
m_mutex1.unlock();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -304,13 +270,10 @@ int FileSearcher::getResult(size_t uniqueSymbol, Xapian::MSet &result, QString v
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
m_mutex2.lock();
|
m_mutex2.lock();
|
||||||
if(uniqueSymbol == FileSearcher::uniqueSymbol2)
|
if(uniqueSymbol == FileSearcher::uniqueSymbol2) {
|
||||||
{
|
|
||||||
m_search_result_file->enqueue(path);
|
m_search_result_file->enqueue(path);
|
||||||
m_mutex2.unlock();
|
m_mutex2.unlock();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
m_mutex2.unlock();
|
m_mutex2.unlock();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -320,27 +283,25 @@ int FileSearcher::getResult(size_t uniqueSymbol, Xapian::MSet &result, QString v
|
||||||
}
|
}
|
||||||
// searchResult.append(path);
|
// searchResult.append(path);
|
||||||
}
|
}
|
||||||
qDebug()<< "doc="<< path << ",weight=" <<docScoreWeight << ",percent=" << docScorePercent;
|
qDebug() << "doc=" << path << ",weight=" << docScoreWeight << ",percent=" << docScorePercent;
|
||||||
}
|
}
|
||||||
// if(!pathTobeDelete->isEmpty())
|
// if(!pathTobeDelete->isEmpty())
|
||||||
// deleteAllIndex(pathTobeDelete)
|
// deleteAllIndex(pathTobeDelete)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearcher::getContentResult(size_t uniqueSymbol, Xapian::MSet &result, std::string &keyWord)
|
int FileSearcher::getContentResult(size_t uniqueSymbol, Xapian::MSet &result, std::string &keyWord) {
|
||||||
{
|
|
||||||
//QStringList *pathTobeDelete = new QStringList;
|
//QStringList *pathTobeDelete = new QStringList;
|
||||||
//Delete those path doc which is not already exist.
|
//Delete those path doc which is not already exist.
|
||||||
|
|
||||||
QString wordTobeFound = QString::fromStdString(keyWord).section(" ",0,0);
|
QString wordTobeFound = QString::fromStdString(keyWord).section(" ", 0, 0);
|
||||||
int size = wordTobeFound.size();
|
int size = wordTobeFound.size();
|
||||||
int totalSize = QString::fromStdString(keyWord).size();
|
int totalSize = QString::fromStdString(keyWord).size();
|
||||||
if(totalSize < 5)
|
if(totalSize < 5)
|
||||||
totalSize = 5;
|
totalSize = 5;
|
||||||
// QMap<QString,QStringList> searchResult;
|
// QMap<QString,QStringList> searchResult;
|
||||||
|
|
||||||
for (auto it = result.begin(); it != result.end(); ++it)
|
for(auto it = result.begin(); it != result.end(); ++it) {
|
||||||
{
|
|
||||||
Xapian::Document doc = it.get_document();
|
Xapian::Document doc = it.get_document();
|
||||||
std::string data = doc.get_data();
|
std::string data = doc.get_data();
|
||||||
double docScoreWeight = it.get_weight();
|
double docScoreWeight = it.get_weight();
|
||||||
|
@ -352,50 +313,43 @@ int FileSearcher::getContentResult(size_t uniqueSymbol, Xapian::MSet &result, st
|
||||||
|
|
||||||
QFileInfo info(path);
|
QFileInfo info(path);
|
||||||
|
|
||||||
if(!info.exists())
|
if(!info.exists()) {
|
||||||
{
|
|
||||||
// pathTobeDelete->append(QString::fromStdString(data));
|
// pathTobeDelete->append(QString::fromStdString(data));
|
||||||
qDebug()<<path<<"is not exist!!";
|
qDebug() << path << "is not exist!!";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Construct snippets containing keyword.
|
// Construct snippets containing keyword.
|
||||||
QStringList snippets;
|
QStringList snippets;
|
||||||
auto term = doc.termlist_begin();
|
auto term = doc.termlist_begin();
|
||||||
term.skip_to(wordTobeFound.toStdString());
|
term.skip_to(wordTobeFound.toStdString());
|
||||||
int count =0;
|
int count = 0;
|
||||||
for(auto pos = term.positionlist_begin();pos != term.positionlist_end()&&count < 6;++pos)
|
for(auto pos = term.positionlist_begin(); pos != term.positionlist_end() && count < 6; ++pos) {
|
||||||
{
|
|
||||||
QByteArray snippetByte = QByteArray::fromStdString(data);
|
QByteArray snippetByte = QByteArray::fromStdString(data);
|
||||||
QString snippet = "..."+QString(snippetByte.left(*pos)).right(size +totalSize) + QString(snippetByte.mid(*pos,-1)).left(size+totalSize) + "...";
|
QString snippet = "..." + QString(snippetByte.left(*pos)).right(size + totalSize) + QString(snippetByte.mid(*pos, -1)).left(size + totalSize) + "...";
|
||||||
// qDebug()<<snippet;
|
// qDebug()<<snippet;
|
||||||
snippets.append(snippet);
|
snippets.append(snippet);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
m_mutex3.lock();
|
m_mutex3.lock();
|
||||||
if(uniqueSymbol == FileSearcher::uniqueSymbol3)
|
if(uniqueSymbol == FileSearcher::uniqueSymbol3) {
|
||||||
{
|
|
||||||
|
|
||||||
m_search_result_content->enqueue(qMakePair(path,snippets));
|
m_search_result_content->enqueue(qMakePair(path, snippets));
|
||||||
m_mutex3.unlock();
|
m_mutex3.unlock();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
m_mutex3.unlock();
|
m_mutex3.unlock();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// searchResult.insert(path,snippets);
|
// searchResult.insert(path,snippets);
|
||||||
qDebug()<< "path="<< path << ",weight=" <<docScoreWeight << ",percent=" << docScorePercent;
|
qDebug() << "path=" << path << ",weight=" << docScoreWeight << ",percent=" << docScorePercent;
|
||||||
}
|
}
|
||||||
// if(!pathTobeDelete->isEmpty())
|
// if(!pathTobeDelete->isEmpty())
|
||||||
// deleteAllIndex(pathTobeDelete)
|
// deleteAllIndex(pathTobeDelete)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSearcher::isBlocked(QString &path)
|
bool FileSearcher::isBlocked(QString &path) {
|
||||||
{
|
|
||||||
QStringList blockList = GlobalSettings::getInstance()->getBlockDirs();
|
QStringList blockList = GlobalSettings::getInstance()->getBlockDirs();
|
||||||
for(QString i : blockList)
|
for(QString i : blockList) {
|
||||||
{
|
|
||||||
if(path.startsWith(i.prepend("/")))
|
if(path.startsWith(i.prepend("/")))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
|
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
|
||||||
|
|
||||||
|
|
||||||
class FileSearcher : public QObject
|
class FileSearcher : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FileSearcher(QObject *parent = nullptr);
|
explicit FileSearcher(QObject *parent = nullptr);
|
||||||
|
@ -49,14 +48,14 @@ public:
|
||||||
static QMutex m_mutex3;
|
static QMutex m_mutex3;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onKeywordSearch(QString keyword,QQueue<QString> *searchResultFile,QQueue<QString> *searchResultDir,QQueue<QPair<QString,QStringList>> *searchResultContent);
|
void onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, QQueue<QPair<QString, QStringList>> *searchResultContent);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void resultFile(QQueue<QString> *);
|
void resultFile(QQueue<QString> *);
|
||||||
void resultDir(QQueue<QString> *);
|
void resultDir(QQueue<QString> *);
|
||||||
void resultContent(QQueue<QPair<QString,QStringList>> *);
|
void resultContent(QQueue<QPair<QString, QStringList>> *);
|
||||||
private:
|
private:
|
||||||
int keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value,unsigned slot = 1,int begin = 0, int num = 20);
|
int keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value, unsigned slot = 1, int begin = 0, int num = 20);
|
||||||
int keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
int keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,13 +69,13 @@ private:
|
||||||
Xapian::Query creatQueryForContentSearch(QString keyword, Xapian::Database &db);
|
Xapian::Query creatQueryForContentSearch(QString keyword, Xapian::Database &db);
|
||||||
|
|
||||||
int getResult(size_t uniqueSymbol, Xapian::MSet &result, QString value);
|
int getResult(size_t uniqueSymbol, Xapian::MSet &result, QString value);
|
||||||
int getContentResult(size_t uniqueSymbol, Xapian::MSet &result,std::string &keyWord);
|
int getContentResult(size_t uniqueSymbol, Xapian::MSet &result, std::string &keyWord);
|
||||||
|
|
||||||
bool isBlocked(QString &path);
|
bool isBlocked(QString &path);
|
||||||
|
|
||||||
QQueue<QString> *m_search_result_file = nullptr;
|
QQueue<QString> *m_search_result_file = nullptr;
|
||||||
QQueue<QString> *m_search_result_dir = nullptr;
|
QQueue<QString> *m_search_result_dir = nullptr;
|
||||||
QQueue<QPair<QString,QStringList>> *m_search_result_content = nullptr;
|
QQueue<QPair<QString, QStringList>> *m_search_result_content = nullptr;
|
||||||
bool m_searching = false;
|
bool m_searching = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,10 @@
|
||||||
#define NEW_QUEUE(a) a = new QQueue<QString>(); qDebug("---------------------------%s %s %s new at %d..",__FILE__,__FUNCTION__,#a,__LINE__);
|
#define NEW_QUEUE(a) a = new QQueue<QString>(); qDebug("---------------------------%s %s %s new at %d..",__FILE__,__FUNCTION__,#a,__LINE__);
|
||||||
//#define DELETE_QUEUE(a )
|
//#define DELETE_QUEUE(a )
|
||||||
|
|
||||||
FirstIndex::FirstIndex()
|
FirstIndex::FirstIndex() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstIndex::~FirstIndex()
|
FirstIndex::~FirstIndex() {
|
||||||
{
|
|
||||||
qDebug() << "~FirstIndex";
|
qDebug() << "~FirstIndex";
|
||||||
if(this->q_index)
|
if(this->q_index)
|
||||||
delete this->q_index;
|
delete this->q_index;
|
||||||
|
@ -38,38 +36,37 @@ FirstIndex::~FirstIndex()
|
||||||
if(this->q_content_index)
|
if(this->q_content_index)
|
||||||
delete this->q_content_index;
|
delete this->q_content_index;
|
||||||
this->q_content_index = nullptr;
|
this->q_content_index = nullptr;
|
||||||
if (this->p_indexGenerator)
|
if(this->p_indexGenerator)
|
||||||
delete this->p_indexGenerator;
|
delete this->p_indexGenerator;
|
||||||
this->p_indexGenerator = nullptr;
|
this->p_indexGenerator = nullptr;
|
||||||
qDebug() << "~FirstIndex end";
|
qDebug() << "~FirstIndex end";
|
||||||
}
|
}
|
||||||
|
|
||||||
void FirstIndex::DoSomething(const QFileInfo& fileInfo){
|
void FirstIndex::DoSomething(const QFileInfo& fileInfo) {
|
||||||
// qDebug() << "there are some shit here"<<fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(fileInfo.isDir() ? "1" : "0");
|
// qDebug() << "there are some shit here"<<fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(fileInfo.isDir() ? "1" : "0");
|
||||||
this->q_index->enqueue(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString((fileInfo.isDir() && (!fileInfo.isSymLink())) ? "1" : "0"));
|
this->q_index->enqueue(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString((fileInfo.isDir() && (!fileInfo.isSymLink())) ? "1" : "0"));
|
||||||
if ((fileInfo.fileName().split(".", QString::SkipEmptyParts).length() > 1) && (true == targetFileTypeMap[fileInfo.fileName().split(".").last()])){
|
if((fileInfo.fileName().split(".", QString::SkipEmptyParts).length() > 1) && (true == targetFileTypeMap[fileInfo.fileName().split(".").last()])) {
|
||||||
this->q_content_index->enqueue(fileInfo.absoluteFilePath());
|
this->q_content_index->enqueue(fileInfo.absoluteFilePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FirstIndex::run(){
|
void FirstIndex::run() {
|
||||||
QTime t1 = QTime::currentTime();
|
QTime t1 = QTime::currentTime();
|
||||||
|
|
||||||
// Create a fifo at ~/.config/org.ukui/ukui-search, the fifo is used to control the order of child processes' running.
|
// Create a fifo at ~/.config/org.ukui/ukui-search, the fifo is used to control the order of child processes' running.
|
||||||
QDir fifoDir = QDir(QDir::homePath()+"/.config/org.ukui/ukui-search");
|
QDir fifoDir = QDir(QDir::homePath() + "/.config/org.ukui/ukui-search");
|
||||||
if(!fifoDir.exists())
|
if(!fifoDir.exists())
|
||||||
qDebug()<<"create fifo path"<<fifoDir.mkpath(fifoDir.absolutePath());
|
qDebug() << "create fifo path" << fifoDir.mkpath(fifoDir.absolutePath());
|
||||||
|
|
||||||
unlink(UKUI_SEARCH_PIPE_PATH);
|
unlink(UKUI_SEARCH_PIPE_PATH);
|
||||||
int retval = mkfifo(UKUI_SEARCH_PIPE_PATH, 0777);
|
int retval = mkfifo(UKUI_SEARCH_PIPE_PATH, 0777);
|
||||||
if(retval == -1)
|
if(retval == -1) {
|
||||||
{
|
qCritical() << "creat fifo error!!";
|
||||||
qCritical()<<"creat fifo error!!";
|
syslog(LOG_ERR, "creat fifo error!!\n");
|
||||||
syslog(LOG_ERR,"creat fifo error!!\n");
|
|
||||||
assert(false);
|
assert(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug()<<"create fifo success\n";
|
qDebug() << "create fifo success\n";
|
||||||
|
|
||||||
QString indexDataBaseStatus = GlobalSettings::getInstance()->getValue(INDEX_DATABASE_STATE).toString();
|
QString indexDataBaseStatus = GlobalSettings::getInstance()->getValue(INDEX_DATABASE_STATE).toString();
|
||||||
QString contentIndexDataBaseStatus = GlobalSettings::getInstance()->getValue(CONTENT_INDEX_DATABASE_STATE).toString();
|
QString contentIndexDataBaseStatus = GlobalSettings::getInstance()->getValue(CONTENT_INDEX_DATABASE_STATE).toString();
|
||||||
|
@ -80,16 +77,14 @@ void FirstIndex::run(){
|
||||||
qDebug() << "inotifyIndexStatus: " << inotifyIndexStatus;
|
qDebug() << "inotifyIndexStatus: " << inotifyIndexStatus;
|
||||||
|
|
||||||
/* || contentIndexDataBaseStatus == ""*/
|
/* || contentIndexDataBaseStatus == ""*/
|
||||||
if (indexDataBaseStatus == ""){
|
if(indexDataBaseStatus == "") {
|
||||||
this->bool_dataBaseExist = false;
|
this->bool_dataBaseExist = false;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
this->bool_dataBaseExist = true;
|
this->bool_dataBaseExist = true;
|
||||||
}
|
}
|
||||||
if (indexDataBaseStatus != "2" || contentIndexDataBaseStatus != "2" || inotifyIndexStatus != "2"){
|
if(indexDataBaseStatus != "2" || contentIndexDataBaseStatus != "2" || inotifyIndexStatus != "2") {
|
||||||
this->bool_dataBaseStatusOK = false;
|
this->bool_dataBaseStatusOK = false;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
this->bool_dataBaseStatusOK = true;
|
this->bool_dataBaseStatusOK = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +99,7 @@ void FirstIndex::run(){
|
||||||
buffer[0] = 0x1;
|
buffer[0] = 0x1;
|
||||||
buffer[1] = '\0';
|
buffer[1] = '\0';
|
||||||
fifo_fd = open(UKUI_SEARCH_PIPE_PATH, O_RDWR);
|
fifo_fd = open(UKUI_SEARCH_PIPE_PATH, O_RDWR);
|
||||||
if(fifo_fd == -1)
|
if(fifo_fd == -1) {
|
||||||
{
|
|
||||||
perror("open fifo error\n");
|
perror("open fifo error\n");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -119,23 +113,20 @@ void FirstIndex::run(){
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0)
|
if(pid == 0) {
|
||||||
{
|
|
||||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||||
prctl(PR_SET_NAME,"first-index");
|
prctl(PR_SET_NAME, "first-index");
|
||||||
if (this->bool_dataBaseExist){
|
if(this->bool_dataBaseExist) {
|
||||||
if (this->bool_dataBaseStatusOK){
|
if(this->bool_dataBaseStatusOK) {
|
||||||
::_exit(0);
|
::_exit(0);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
//if the parameter is false, index won't be rebuild
|
//if the parameter is false, index won't be rebuild
|
||||||
//if it is true, index will be rebuild
|
//if it is true, index will be rebuild
|
||||||
p_indexGenerator = IndexGenerator::getInstance(true,this);
|
p_indexGenerator = IndexGenerator::getInstance(true, this);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// p_indexGenerator = IndexGenerator::getInstance(false,this);
|
// p_indexGenerator = IndexGenerator::getInstance(false,this);
|
||||||
p_indexGenerator = IndexGenerator::getInstance(true,this);
|
p_indexGenerator = IndexGenerator::getInstance(true, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
QSemaphore sem(5);
|
QSemaphore sem(5);
|
||||||
|
@ -150,16 +141,16 @@ void FirstIndex::run(){
|
||||||
this->setPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
this->setPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
||||||
this->Traverse();
|
this->Traverse();
|
||||||
FileUtils::_max_index_count = this->q_index->length();
|
FileUtils::_max_index_count = this->q_index->length();
|
||||||
qDebug()<<"max_index_count:"<<FileUtils::_max_index_count;
|
qDebug() << "max_index_count:" << FileUtils::_max_index_count;
|
||||||
sem.release(5);
|
sem.release(5);
|
||||||
// });
|
// });
|
||||||
QtConcurrent::run([&](){
|
QtConcurrent::run([&]() {
|
||||||
sem.acquire(2);
|
sem.acquire(2);
|
||||||
mutex2.unlock();
|
mutex2.unlock();
|
||||||
qDebug() << "index start;";
|
qDebug() << "index start;";
|
||||||
QQueue<QVector<QString>>* tmp = new QQueue<QVector<QString>>();
|
QQueue<QVector<QString>>* tmp = new QQueue<QVector<QString>>();
|
||||||
while (!this->q_index->empty()) {
|
while(!this->q_index->empty()) {
|
||||||
for (size_t i = 0; (i < 8192) && (!this->q_index->empty()); ++i){
|
for(size_t i = 0; (i < 8192) && (!this->q_index->empty()); ++i) {
|
||||||
tmp->enqueue(this->q_index->dequeue());
|
tmp->enqueue(this->q_index->dequeue());
|
||||||
}
|
}
|
||||||
this->p_indexGenerator->creatAllIndex(tmp);
|
this->p_indexGenerator->creatAllIndex(tmp);
|
||||||
|
@ -170,14 +161,14 @@ void FirstIndex::run(){
|
||||||
qDebug() << "index end;";
|
qDebug() << "index end;";
|
||||||
sem.release(2);
|
sem.release(2);
|
||||||
});
|
});
|
||||||
QtConcurrent::run([&](){
|
QtConcurrent::run([&]() {
|
||||||
sem.acquire(2);
|
sem.acquire(2);
|
||||||
mutex3.unlock();
|
mutex3.unlock();
|
||||||
QQueue<QString>* tmp = new QQueue<QString>();
|
QQueue<QString>* tmp = new QQueue<QString>();
|
||||||
qDebug()<<"q_content_index:"<<q_content_index->size();
|
qDebug() << "q_content_index:" << q_content_index->size();
|
||||||
while (!this->q_content_index->empty()) {
|
while(!this->q_content_index->empty()) {
|
||||||
// for (size_t i = 0; (i < this->u_send_length) && (!this->q_content_index->empty()); ++i){
|
// for (size_t i = 0; (i < this->u_send_length) && (!this->q_content_index->empty()); ++i){
|
||||||
for (size_t i = 0; (i < 30) && (!this->q_content_index->empty()); ++i){
|
for(size_t i = 0; (i < 30) && (!this->q_content_index->empty()); ++i) {
|
||||||
tmp->enqueue(this->q_content_index->dequeue());
|
tmp->enqueue(this->q_content_index->dequeue());
|
||||||
}
|
}
|
||||||
this->p_indexGenerator->creatAllIndex(tmp);
|
this->p_indexGenerator->creatAllIndex(tmp);
|
||||||
|
@ -195,33 +186,28 @@ void FirstIndex::run(){
|
||||||
mutex2.unlock();
|
mutex2.unlock();
|
||||||
mutex3.unlock();
|
mutex3.unlock();
|
||||||
|
|
||||||
if (this->q_index)
|
if(this->q_index)
|
||||||
delete this->q_index;
|
delete this->q_index;
|
||||||
this->q_index = nullptr;
|
this->q_index = nullptr;
|
||||||
if (this->q_content_index)
|
if(this->q_content_index)
|
||||||
delete this->q_content_index;
|
delete this->q_content_index;
|
||||||
this->q_content_index = nullptr;
|
this->q_content_index = nullptr;
|
||||||
if (p_indexGenerator)
|
if(p_indexGenerator)
|
||||||
delete p_indexGenerator;
|
delete p_indexGenerator;
|
||||||
p_indexGenerator = nullptr;
|
p_indexGenerator = nullptr;
|
||||||
// GlobalSettings::getInstance()->forceSync();
|
// GlobalSettings::getInstance()->forceSync();
|
||||||
::_exit(0);
|
::_exit(0);
|
||||||
}
|
} else if(pid < 0) {
|
||||||
else if(pid < 0)
|
qWarning() << "First Index fork error!!";
|
||||||
{
|
} else {
|
||||||
qWarning()<<"First Index fork error!!";
|
waitpid(pid, NULL, 0);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
waitpid(pid,NULL,0);
|
|
||||||
--FileUtils::_index_status;
|
--FileUtils::_index_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
|
||||||
int retval1 = write(fifo_fd, buffer, strlen(buffer));
|
int retval1 = write(fifo_fd, buffer, strlen(buffer));
|
||||||
if(retval1 == -1)
|
if(retval1 == -1) {
|
||||||
{
|
|
||||||
qWarning("write error\n");
|
qWarning("write error\n");
|
||||||
}
|
}
|
||||||
qDebug("write data ok!\n");
|
qDebug("write data ok!\n");
|
||||||
|
|
|
@ -42,8 +42,7 @@
|
||||||
#include "inotify-index.h"
|
#include "inotify-index.h"
|
||||||
#include "file-utils.h"
|
#include "file-utils.h"
|
||||||
|
|
||||||
class FirstIndex : public QThread, public Traverse_BFS
|
class FirstIndex : public QThread, public Traverse_BFS {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
FirstIndex();
|
FirstIndex();
|
||||||
~FirstIndex();
|
~FirstIndex();
|
||||||
|
|
|
@ -42,36 +42,32 @@ QList<Document> *_doc_list_path;
|
||||||
QMutex _mutex_doc_list_path;
|
QMutex _mutex_doc_list_path;
|
||||||
QList<Document> *_doc_list_content;
|
QList<Document> *_doc_list_content;
|
||||||
QMutex _mutex_doc_list_content;
|
QMutex _mutex_doc_list_content;
|
||||||
IndexGenerator *IndexGenerator::getInstance(bool rebuild, QObject *parent)
|
IndexGenerator *IndexGenerator::getInstance(bool rebuild, QObject *parent) {
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
if (!global_instance) {
|
if(!global_instance) {
|
||||||
qDebug()<<"IndexGenerator=================";
|
qDebug() << "IndexGenerator=================";
|
||||||
global_instance = new IndexGenerator(rebuild,parent);
|
global_instance = new IndexGenerator(rebuild, parent);
|
||||||
}
|
}
|
||||||
qDebug() << "global_instance" << global_instance;
|
qDebug() << "global_instance" << global_instance;
|
||||||
qDebug() << "QThread::currentThreadId()" << QThread::currentThreadId();
|
qDebug() << "QThread::currentThreadId()" << QThread::currentThreadId();
|
||||||
return global_instance;
|
return global_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IndexGenerator::setIndexdataPath()
|
bool IndexGenerator::setIndexdataPath() {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//文件名索引
|
//文件名索引
|
||||||
bool IndexGenerator::creatAllIndex(QQueue<QVector<QString> > *messageList)
|
bool IndexGenerator::creatAllIndex(QQueue<QVector<QString> > *messageList) {
|
||||||
{
|
|
||||||
// FileUtils::_index_status |= 0x1;
|
// FileUtils::_index_status |= 0x1;
|
||||||
// qDebug() << messageList->size();
|
// qDebug() << messageList->size();
|
||||||
HandlePathList(messageList);
|
HandlePathList(messageList);
|
||||||
if (_doc_list_path == NULL){
|
if(_doc_list_path == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qDebug()<<"begin creatAllIndex";
|
qDebug() << "begin creatAllIndex";
|
||||||
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE,"0");
|
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE, "0");
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// m_indexer = new Xapian::TermGenerator();
|
// m_indexer = new Xapian::TermGenerator();
|
||||||
// m_indexer.set_database(*m_database_path);
|
// m_indexer.set_database(*m_database_path);
|
||||||
//可以实现拼写纠正
|
//可以实现拼写纠正
|
||||||
|
@ -80,7 +76,7 @@ bool IndexGenerator::creatAllIndex(QQueue<QVector<QString> > *messageList)
|
||||||
|
|
||||||
// int count =0;
|
// int count =0;
|
||||||
|
|
||||||
for (auto i : *_doc_list_path){
|
for(auto i : *_doc_list_path) {
|
||||||
|
|
||||||
insertIntoDatabase(i);
|
insertIntoDatabase(i);
|
||||||
// if(++count > 8999){
|
// if(++count > 8999){
|
||||||
|
@ -89,17 +85,15 @@ bool IndexGenerator::creatAllIndex(QQueue<QVector<QString> > *messageList)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
m_database_path->commit();
|
m_database_path->commit();
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << "creatAllIndex fail!" << QString::fromStdString(e.get_description());
|
||||||
{
|
|
||||||
qWarning()<<"creatAllIndex fail!"<<QString::fromStdString(e.get_description());
|
|
||||||
//need a record
|
//need a record
|
||||||
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE,"1");
|
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE, "1");
|
||||||
// FileUtils::_index_status &= ~0x1;
|
// FileUtils::_index_status &= ~0x1;
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE,"2");
|
GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE, "2");
|
||||||
qDebug()<<"finish creatAllIndex";
|
qDebug() << "finish creatAllIndex";
|
||||||
// FileUtils::_index_status &= ~0x1;
|
// FileUtils::_index_status &= ~0x1;
|
||||||
_doc_list_path->clear();
|
_doc_list_path->clear();
|
||||||
delete _doc_list_path;
|
delete _doc_list_path;
|
||||||
|
@ -107,41 +101,36 @@ bool IndexGenerator::creatAllIndex(QQueue<QVector<QString> > *messageList)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//文件内容索引
|
//文件内容索引
|
||||||
bool IndexGenerator::creatAllIndex(QQueue<QString> *messageList)
|
bool IndexGenerator::creatAllIndex(QQueue<QString> *messageList) {
|
||||||
{
|
|
||||||
// FileUtils::_index_status |= 0x2;
|
// FileUtils::_index_status |= 0x2;
|
||||||
HandlePathList(messageList);
|
HandlePathList(messageList);
|
||||||
qDebug()<<"begin creatAllIndex for content";
|
qDebug() << "begin creatAllIndex for content";
|
||||||
if (_doc_list_content == NULL){
|
if(_doc_list_content == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int size = _doc_list_content->size();
|
int size = _doc_list_content->size();
|
||||||
qDebug()<<"begin creatAllIndex for content"<<size;
|
qDebug() << "begin creatAllIndex for content" << size;
|
||||||
if(!size == 0)
|
if(!size == 0) {
|
||||||
{
|
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE, "0");
|
||||||
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE,"0");
|
try {
|
||||||
try
|
int count = 0;
|
||||||
{
|
for(auto i : *_doc_list_content) {
|
||||||
int count =0;
|
|
||||||
for (auto i : *_doc_list_content){
|
|
||||||
insertIntoContentDatabase(i);
|
insertIntoContentDatabase(i);
|
||||||
if(++count > 999){
|
if(++count > 999) {
|
||||||
count = 0;
|
count = 0;
|
||||||
m_database_content->commit();
|
m_database_content->commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_database_content->commit();
|
m_database_content->commit();
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << "creat content Index fail!" << QString::fromStdString(e.get_description());
|
||||||
{
|
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE, "1");
|
||||||
qWarning()<<"creat content Index fail!"<<QString::fromStdString(e.get_description());
|
|
||||||
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE,"1");
|
|
||||||
// FileUtils::_index_status &= ~0x2;
|
// FileUtils::_index_status &= ~0x2;
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE,"2");
|
GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE, "2");
|
||||||
// FileUtils::_index_status &= ~0x2;
|
// FileUtils::_index_status &= ~0x2;
|
||||||
qDebug()<<"finish creatAllIndex for content";
|
qDebug() << "finish creatAllIndex for content";
|
||||||
_doc_list_content->clear();
|
_doc_list_content->clear();
|
||||||
delete _doc_list_content;
|
delete _doc_list_content;
|
||||||
_doc_list_content = nullptr;
|
_doc_list_content = nullptr;
|
||||||
|
@ -151,36 +140,28 @@ bool IndexGenerator::creatAllIndex(QQueue<QString> *messageList)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexGenerator::IndexGenerator(bool rebuild, QObject *parent) : QObject(parent)
|
IndexGenerator::IndexGenerator(bool rebuild, QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
QDir database(QString::fromStdString(INDEX_PATH));
|
QDir database(QString::fromStdString(INDEX_PATH));
|
||||||
|
|
||||||
if(database.exists())
|
if(database.exists()) {
|
||||||
{
|
|
||||||
if(rebuild)
|
if(rebuild)
|
||||||
qDebug()<<"remove"<<database.removeRecursively();
|
qDebug() << "remove" << database.removeRecursively();
|
||||||
}
|
} else {
|
||||||
else
|
qDebug() << "create index path" << database.mkpath(QString::fromStdString(INDEX_PATH));
|
||||||
{
|
|
||||||
qDebug()<<"create index path"<<database.mkpath(QString::fromStdString(INDEX_PATH));
|
|
||||||
}
|
}
|
||||||
database.setPath(QString::fromStdString(CONTENT_INDEX_PATH));
|
database.setPath(QString::fromStdString(CONTENT_INDEX_PATH));
|
||||||
if(database.exists())
|
if(database.exists()) {
|
||||||
{
|
|
||||||
if(rebuild)
|
if(rebuild)
|
||||||
qDebug()<<"remove"<<database.removeRecursively();
|
qDebug() << "remove" << database.removeRecursively();
|
||||||
}
|
} else {
|
||||||
else
|
qDebug() << "create content index path" << database.mkpath(QString::fromStdString(CONTENT_INDEX_PATH));
|
||||||
{
|
|
||||||
qDebug()<<"create content index path"<<database.mkpath(QString::fromStdString(CONTENT_INDEX_PATH));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_database_path = new Xapian::WritableDatabase(INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
|
m_database_path = new Xapian::WritableDatabase(INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
|
||||||
m_database_content = new Xapian::WritableDatabase(CONTENT_INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
|
m_database_content = new Xapian::WritableDatabase(CONTENT_INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexGenerator::~IndexGenerator()
|
IndexGenerator::~IndexGenerator() {
|
||||||
{
|
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
qDebug() << "~IndexGenerator";
|
qDebug() << "~IndexGenerator";
|
||||||
if(m_database_path)
|
if(m_database_path)
|
||||||
|
@ -216,8 +197,7 @@ IndexGenerator::~IndexGenerator()
|
||||||
qDebug() << "~IndexGenerator end";
|
qDebug() << "~IndexGenerator end";
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexGenerator::insertIntoDatabase(Document& doc)
|
void IndexGenerator::insertIntoDatabase(Document& doc) {
|
||||||
{
|
|
||||||
// qDebug()<< "--index start--";
|
// qDebug()<< "--index start--";
|
||||||
Xapian::Document document = doc.getXapianDocument();
|
Xapian::Document document = doc.getXapianDocument();
|
||||||
// m_indexer.set_document(document);
|
// m_indexer.set_document(document);
|
||||||
|
@ -229,24 +209,22 @@ void IndexGenerator::insertIntoDatabase(Document& doc)
|
||||||
// qDebug()<<"insert m_database_path:"<<QString::fromStdString(document.get_data());
|
// qDebug()<<"insert m_database_path:"<<QString::fromStdString(document.get_data());
|
||||||
// qDebug()<<"document:"<<QString::fromStdString(document.get_description());
|
// qDebug()<<"document:"<<QString::fromStdString(document.get_description());
|
||||||
|
|
||||||
Xapian::docid innerId= m_database_path->replace_document(doc.getUniqueTerm(),document);
|
Xapian::docid innerId = m_database_path->replace_document(doc.getUniqueTerm(), document);
|
||||||
// qDebug()<<"replace doc docid="<<static_cast<int>(innerId);
|
// qDebug()<<"replace doc docid="<<static_cast<int>(innerId);
|
||||||
// qDebug()<< "--index finish--";
|
// qDebug()<< "--index finish--";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//#define fun(a) a=new ;printf()
|
//#define fun(a) a=new ;printf()
|
||||||
void IndexGenerator::insertIntoContentDatabase(Document& doc)
|
void IndexGenerator::insertIntoContentDatabase(Document& doc) {
|
||||||
{
|
Xapian::docid innerId = m_database_content->replace_document(doc.getUniqueTerm(), doc.getXapianDocument());
|
||||||
Xapian::docid innerId= m_database_content->replace_document(doc.getUniqueTerm(),doc.getXapianDocument());
|
|
||||||
// qDebug()<<"replace doc docid="<<static_cast<int>(innerId);
|
// qDebug()<<"replace doc docid="<<static_cast<int>(innerId);
|
||||||
// qDebug()<< "--index finish--";
|
// qDebug()<< "--index finish--";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexGenerator::HandlePathList(QQueue<QVector<QString>> *messageList)
|
void IndexGenerator::HandlePathList(QQueue<QVector<QString>> *messageList) {
|
||||||
{
|
qDebug() << "Begin HandlePathList!";
|
||||||
qDebug()<<"Begin HandlePathList!";
|
qDebug() << messageList->size();
|
||||||
qDebug()<<messageList->size();
|
|
||||||
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
||||||
// QFuture<Document> future = QtConcurrent::mapped(*messageList,&IndexGenerator::GenerateDocument);
|
// QFuture<Document> future = QtConcurrent::mapped(*messageList,&IndexGenerator::GenerateDocument);
|
||||||
|
|
||||||
|
@ -259,12 +237,11 @@ void IndexGenerator::HandlePathList(QQueue<QVector<QString>> *messageList)
|
||||||
pool.setMaxThreadCount(((QThread::idealThreadCount() - 1) / 2) + 1);
|
pool.setMaxThreadCount(((QThread::idealThreadCount() - 1) / 2) + 1);
|
||||||
pool.setExpiryTimeout(100);
|
pool.setExpiryTimeout(100);
|
||||||
ConstructDocumentForPath *constructer;
|
ConstructDocumentForPath *constructer;
|
||||||
while(!messageList->isEmpty())
|
while(!messageList->isEmpty()) {
|
||||||
{
|
constructer = new ConstructDocumentForPath(messageList->dequeue());
|
||||||
constructer = new ConstructDocumentForPath(messageList->dequeue());
|
pool.start(constructer);
|
||||||
pool.start(constructer);
|
|
||||||
}
|
}
|
||||||
qDebug()<<"pool finish"<<pool.waitForDone(-1);
|
qDebug() << "pool finish" << pool.waitForDone(-1);
|
||||||
// if(constructer)
|
// if(constructer)
|
||||||
// delete constructer;
|
// delete constructer;
|
||||||
// constructer = nullptr;
|
// constructer = nullptr;
|
||||||
|
@ -276,14 +253,13 @@ void IndexGenerator::HandlePathList(QQueue<QVector<QString>> *messageList)
|
||||||
// m_doc_list_path = std::move(future.results());
|
// m_doc_list_path = std::move(future.results());
|
||||||
// qDebug()<<m_doc_list_path.size();
|
// qDebug()<<m_doc_list_path.size();
|
||||||
|
|
||||||
qDebug()<<"Finish HandlePathList!";
|
qDebug() << "Finish HandlePathList!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexGenerator::HandlePathList(QQueue<QString> *messageList)
|
void IndexGenerator::HandlePathList(QQueue<QString> *messageList) {
|
||||||
{
|
qDebug() << "Begin HandlePathList for content index!";
|
||||||
qDebug()<<"Begin HandlePathList for content index!";
|
qDebug() << messageList->size();
|
||||||
qDebug()<<messageList->size();
|
|
||||||
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
||||||
ChineseSegmentation::getInstance();
|
ChineseSegmentation::getInstance();
|
||||||
ConstructDocumentForContent *constructer;
|
ConstructDocumentForContent *constructer;
|
||||||
|
@ -291,12 +267,11 @@ void IndexGenerator::HandlePathList(QQueue<QString> *messageList)
|
||||||
// pool.setMaxThreadCount(((QThread::idealThreadCount() - 1) / 2) + 1);
|
// pool.setMaxThreadCount(((QThread::idealThreadCount() - 1) / 2) + 1);
|
||||||
pool.setMaxThreadCount(1);
|
pool.setMaxThreadCount(1);
|
||||||
pool.setExpiryTimeout(100);
|
pool.setExpiryTimeout(100);
|
||||||
while(!messageList->isEmpty())
|
while(!messageList->isEmpty()) {
|
||||||
{
|
constructer = new ConstructDocumentForContent(messageList->dequeue());
|
||||||
constructer = new ConstructDocumentForContent(messageList->dequeue());
|
pool.start(constructer);
|
||||||
pool.start(constructer);
|
|
||||||
}
|
}
|
||||||
qDebug()<<"pool finish"<<pool.waitForDone(-1);
|
qDebug() << "pool finish" << pool.waitForDone(-1);
|
||||||
// if(constructer)
|
// if(constructer)
|
||||||
// delete constructer;
|
// delete constructer;
|
||||||
// constructer = nullptr;
|
// constructer = nullptr;
|
||||||
|
@ -316,19 +291,18 @@ void IndexGenerator::HandlePathList(QQueue<QString> *messageList)
|
||||||
// m_doc_list_content = std::move(future.results());
|
// m_doc_list_content = std::move(future.results());
|
||||||
// future.cancel();
|
// future.cancel();
|
||||||
|
|
||||||
qDebug()<<"Finish HandlePathList for content index!";
|
qDebug() << "Finish HandlePathList for content index!";
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document IndexGenerator::GenerateDocument(const QVector<QString> &list)
|
Document IndexGenerator::GenerateDocument(const QVector<QString> &list) {
|
||||||
{
|
|
||||||
Document doc;
|
Document doc;
|
||||||
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
// qDebug()<<QString::number(quintptr(QThread::currentThreadId()));
|
||||||
//0-filename 1-filepathname 2-file or dir
|
//0-filename 1-filepathname 2-file or dir
|
||||||
QString index_text = list.at(0);
|
QString index_text = list.at(0);
|
||||||
QString sourcePath = list.at(1);
|
QString sourcePath = list.at(1);
|
||||||
index_text = index_text.replace(""," ");
|
index_text = index_text.replace("", " ");
|
||||||
index_text = index_text.simplified();
|
index_text = index_text.simplified();
|
||||||
|
|
||||||
//不带多音字版
|
//不带多音字版
|
||||||
|
@ -336,16 +310,16 @@ Document IndexGenerator::GenerateDocument(const QVector<QString> &list)
|
||||||
|
|
||||||
//多音字版
|
//多音字版
|
||||||
//现加入首字母
|
//现加入首字母
|
||||||
QStringList pinyin_text_list = FileUtils::findMultiToneWords(QString(list.at(0)).replace(".",""));
|
QStringList pinyin_text_list = FileUtils::findMultiToneWords(QString(list.at(0)).replace(".", ""));
|
||||||
for (QString& i : pinyin_text_list){
|
for(QString& i : pinyin_text_list) {
|
||||||
i.replace("", " ");
|
i.replace("", " ");
|
||||||
i = i.simplified();
|
i = i.simplified();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath));
|
QString uniqueterm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath));
|
||||||
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath.section("/",0,-2,QString::SectionIncludeLeadingSep)));
|
QString upTerm = QString::fromStdString(FileUtils::makeDocUterm(sourcePath.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
|
||||||
// QString uniqueterm1 = QString::fromStdString(QCryptographicHash::hash(sourcePath.toUtf8(),QCryptographicHash::Md5).toStdString());
|
// QString uniqueterm1 = QString::fromStdString(QCryptographicHash::hash(sourcePath.toUtf8(),QCryptographicHash::Md5).toStdString());
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
//QByteArray 和 QString 之间会进行隐式转换,造成字符串被截断等意想不到的后果!!!!!!! zpf
|
//QByteArray 和 QString 之间会进行隐式转换,造成字符串被截断等意想不到的后果!!!!!!! zpf
|
||||||
// if(uniqueterm1!=uniqueterm){
|
// if(uniqueterm1!=uniqueterm){
|
||||||
// qDebug()<<"-----------------------------------------start";
|
// qDebug()<<"-----------------------------------------start";
|
||||||
|
@ -353,7 +327,7 @@ Document IndexGenerator::GenerateDocument(const QVector<QString> &list)
|
||||||
// qDebug()<<uniqueterm;
|
// qDebug()<<uniqueterm;
|
||||||
// qDebug()<<"------------------------------------------finish";
|
// qDebug()<<"------------------------------------------finish";
|
||||||
// }
|
// }
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
doc.setData(sourcePath);
|
doc.setData(sourcePath);
|
||||||
doc.setUniqueTerm(uniqueterm);
|
doc.setUniqueTerm(uniqueterm);
|
||||||
|
@ -367,8 +341,7 @@ Document IndexGenerator::GenerateDocument(const QVector<QString> &list)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document IndexGenerator::GenerateContentDocument(const QString &path)
|
Document IndexGenerator::GenerateContentDocument(const QString &path) {
|
||||||
{
|
|
||||||
// 构造文本索引的document
|
// 构造文本索引的document
|
||||||
QString content;
|
QString content;
|
||||||
QStringList tmp;
|
QStringList tmp;
|
||||||
|
@ -377,7 +350,7 @@ Document IndexGenerator::GenerateContentDocument(const QString &path)
|
||||||
Document doc;
|
Document doc;
|
||||||
QString uniqueterm;
|
QString uniqueterm;
|
||||||
QString upTerm;
|
QString upTerm;
|
||||||
FileReader::getTextContent(path,content);
|
FileReader::getTextContent(path, content);
|
||||||
|
|
||||||
term = ChineseSegmentation::getInstance()->callSegement(content);
|
term = ChineseSegmentation::getInstance()->callSegement(content);
|
||||||
// QStringList term = content.split("");
|
// QStringList term = content.split("");
|
||||||
|
@ -386,9 +359,8 @@ Document IndexGenerator::GenerateContentDocument(const QString &path)
|
||||||
doc.setUniqueTerm(uniqueterm);
|
doc.setUniqueTerm(uniqueterm);
|
||||||
doc.addTerm(upTerm);
|
doc.addTerm(upTerm);
|
||||||
doc.addValue(path);
|
doc.addValue(path);
|
||||||
for(int i = 0;i<term.size();++i)
|
for(int i = 0; i < term.size(); ++i) {
|
||||||
{
|
doc.addPosting(term.at(i).word, term.at(i).offsets, static_cast<int>(term.at(i).weight));
|
||||||
doc.addPosting(term.at(i).word,term.at(i).offsets,static_cast<int>(term.at(i).weight));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,8 +380,7 @@ Document IndexGenerator::GenerateContentDocument(const QString &path)
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IndexGenerator::isIndexdataExist()
|
bool IndexGenerator::isIndexdataExist() {
|
||||||
{
|
|
||||||
|
|
||||||
// Xapian::Database db(m_index_data_path->toStdString());
|
// Xapian::Database db(m_index_data_path->toStdString());
|
||||||
return true;
|
return true;
|
||||||
|
@ -417,12 +388,10 @@ bool IndexGenerator::isIndexdataExist()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList IndexGenerator::IndexSearch(QString indexText)
|
QStringList IndexGenerator::IndexSearch(QString indexText) {
|
||||||
{
|
|
||||||
QStringList searchResult;
|
QStringList searchResult;
|
||||||
try
|
try {
|
||||||
{
|
qDebug() << "--search start--";
|
||||||
qDebug()<<"--search start--";
|
|
||||||
|
|
||||||
Xapian::Database db(INDEX_PATH);
|
Xapian::Database db(INDEX_PATH);
|
||||||
Xapian::Enquire enquire(db);
|
Xapian::Enquire enquire(db);
|
||||||
|
@ -431,33 +400,32 @@ QStringList IndexGenerator::IndexSearch(QString indexText)
|
||||||
qp.set_database(db);
|
qp.set_database(db);
|
||||||
auto userInput = indexText;
|
auto userInput = indexText;
|
||||||
|
|
||||||
std::string queryStr = indexText.replace(""," ").toStdString();
|
std::string queryStr = indexText.replace("", " ").toStdString();
|
||||||
// std::string s =db.get_spelling_suggestion(queryStr,10);
|
// std::string s =db.get_spelling_suggestion(queryStr,10);
|
||||||
// qDebug()<<"spelling_suggestion!"<<QString::fromStdString(s);
|
// qDebug()<<"spelling_suggestion!"<<QString::fromStdString(s);
|
||||||
|
|
||||||
qDebug()<<"queryStr!"<<QString::fromStdString(queryStr);
|
qDebug() << "queryStr!" << QString::fromStdString(queryStr);
|
||||||
//Creat a query
|
//Creat a query
|
||||||
Xapian::Query queryPhrase = qp.parse_query(queryStr,Xapian::QueryParser::FLAG_PHRASE);
|
Xapian::Query queryPhrase = qp.parse_query(queryStr, Xapian::QueryParser::FLAG_PHRASE);
|
||||||
std::vector<Xapian::Query> v;
|
std::vector<Xapian::Query> v;
|
||||||
for(int i=0;i<userInput.size();i++)
|
for(int i = 0; i < userInput.size(); i++) {
|
||||||
{
|
|
||||||
v.push_back(Xapian::Query(QString(userInput.at(i)).toStdString()));
|
v.push_back(Xapian::Query(QString(userInput.at(i)).toStdString()));
|
||||||
qDebug()<<userInput.at(i);
|
qDebug() << userInput.at(i);
|
||||||
qDebug()<<QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
qDebug() << QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
||||||
}
|
}
|
||||||
Xapian::Query queryNear =Xapian::Query(Xapian::Query::OP_NEAR, v.begin(), v.end());
|
Xapian::Query queryNear = Xapian::Query(Xapian::Query::OP_NEAR, v.begin(), v.end());
|
||||||
Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND,queryNear,queryPhrase);
|
Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND, queryNear, queryPhrase);
|
||||||
|
|
||||||
qDebug()<<QString::fromStdString(query.get_description());
|
qDebug() << QString::fromStdString(query.get_description());
|
||||||
enquire.set_query(query);
|
enquire.set_query(query);
|
||||||
|
|
||||||
Xapian::MSet result = enquire.get_mset(0, 9999);
|
Xapian::MSet result = enquire.get_mset(0, 9999);
|
||||||
qDebug()<< "find results count=" <<static_cast<int>(result.get_matches_estimated());
|
qDebug() << "find results count=" << static_cast<int>(result.get_matches_estimated());
|
||||||
|
|
||||||
// QStringList *pathTobeDelete = new QStringList;
|
// QStringList *pathTobeDelete = new QStringList;
|
||||||
|
|
||||||
//get search result
|
//get search result
|
||||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
for(auto it = result.begin(); it != result.end(); ++it) {
|
||||||
Xapian::Document doc = it.get_document();
|
Xapian::Document doc = it.get_document();
|
||||||
std::string data = doc.get_data();
|
std::string data = doc.get_data();
|
||||||
Xapian::weight docScoreWeight = it.get_weight();
|
Xapian::weight docScoreWeight = it.get_weight();
|
||||||
|
@ -465,27 +433,22 @@ QStringList IndexGenerator::IndexSearch(QString indexText)
|
||||||
// QFileInfo *info = new QFileInfo(QString::fromStdString(data));
|
// QFileInfo *info = new QFileInfo(QString::fromStdString(data));
|
||||||
QFileInfo info(QString::fromStdString(data));
|
QFileInfo info(QString::fromStdString(data));
|
||||||
|
|
||||||
if(!info.exists())
|
if(!info.exists()) {
|
||||||
{
|
|
||||||
// pathTobeDelete->append(QString::fromStdString(data));
|
// pathTobeDelete->append(QString::fromStdString(data));
|
||||||
qDebug()<<QString::fromStdString(data)<<"is not exist!!";
|
qDebug() << QString::fromStdString(data) << "is not exist!!";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
searchResult.append(QString::fromStdString(data));
|
searchResult.append(QString::fromStdString(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug()<< "doc="<< QString::fromStdString(data) << ",weight=" <<docScoreWeight << ",percent=" << docScorePercent;
|
qDebug() << "doc=" << QString::fromStdString(data) << ",weight=" << docScoreWeight << ",percent=" << docScorePercent;
|
||||||
}
|
}
|
||||||
// //Delete those path doc which is not already exist.
|
// //Delete those path doc which is not already exist.
|
||||||
// if(!pathTobeDelete->isEmpty())
|
// if(!pathTobeDelete->isEmpty())
|
||||||
// deleteAllIndex(pathTobeDelete);
|
// deleteAllIndex(pathTobeDelete);
|
||||||
|
|
||||||
qDebug()<< "--search finish--";
|
qDebug() << "--search finish--";
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qDebug() << QString::fromStdString(e.get_description());
|
||||||
{
|
|
||||||
qDebug() <<QString::fromStdString(e.get_description());
|
|
||||||
}
|
}
|
||||||
return searchResult;
|
return searchResult;
|
||||||
}
|
}
|
||||||
|
@ -555,32 +518,27 @@ QStringList IndexGenerator::IndexSearch(QString indexText)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
bool IndexGenerator::deleteAllIndex(QStringList *pathlist)
|
bool IndexGenerator::deleteAllIndex(QStringList *pathlist) {
|
||||||
{
|
|
||||||
QStringList *list = pathlist;
|
QStringList *list = pathlist;
|
||||||
if(list->isEmpty())
|
if(list->isEmpty())
|
||||||
return true;
|
return true;
|
||||||
for(int i = 0;i<list->size();i++)
|
for(int i = 0; i < list->size(); i++) {
|
||||||
{
|
|
||||||
QString doc = list->at(i);
|
QString doc = list->at(i);
|
||||||
std::string uniqueterm = FileUtils::makeDocUterm(doc);
|
std::string uniqueterm = FileUtils::makeDocUterm(doc);
|
||||||
try
|
try {
|
||||||
{
|
qDebug() << "--delete start--";
|
||||||
qDebug()<<"--delete start--";
|
|
||||||
m_database_path->delete_document(uniqueterm);
|
m_database_path->delete_document(uniqueterm);
|
||||||
m_database_content->delete_document(uniqueterm);
|
m_database_content->delete_document(uniqueterm);
|
||||||
qDebug()<<"delete path"<<doc;
|
qDebug() << "delete path" << doc;
|
||||||
qDebug()<<"delete md5"<<QString::fromStdString(uniqueterm);
|
qDebug() << "delete md5" << QString::fromStdString(uniqueterm);
|
||||||
m_database_path->commit();
|
m_database_path->commit();
|
||||||
m_database_content->commit();
|
m_database_content->commit();
|
||||||
qDebug()<< "--delete finish--";
|
qDebug() << "--delete finish--";
|
||||||
// qDebug()<<"m_database_path->get_lastdocid()!!!"<<m_database_path->get_lastdocid();
|
// qDebug()<<"m_database_path->get_lastdocid()!!!"<<m_database_path->get_lastdocid();
|
||||||
|
|
||||||
// qDebug()<<"m_database_path->get_doccount()!!!"<<m_database_path->get_doccount();
|
// qDebug()<<"m_database_path->get_doccount()!!!"<<m_database_path->get_doccount();
|
||||||
}
|
} catch(const Xapian::Error &e) {
|
||||||
catch(const Xapian::Error &e)
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
{
|
|
||||||
qWarning()<<QString::fromStdString(e.get_description());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,10 @@ extern QMutex _mutex_doc_list_path;
|
||||||
extern QList<Document> *_doc_list_content;
|
extern QList<Document> *_doc_list_content;
|
||||||
extern QMutex _mutex_doc_list_content;
|
extern QMutex _mutex_doc_list_content;
|
||||||
|
|
||||||
class IndexGenerator : public QObject
|
class IndexGenerator : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static IndexGenerator *getInstance(bool rebuild = false,QObject *parent = nullptr);
|
static IndexGenerator *getInstance(bool rebuild = false, QObject *parent = nullptr);
|
||||||
~IndexGenerator();
|
~IndexGenerator();
|
||||||
bool setIndexdataPath();
|
bool setIndexdataPath();
|
||||||
bool isIndexdataExist();
|
bool isIndexdataExist();
|
||||||
|
@ -58,7 +57,7 @@ public Q_SLOTS:
|
||||||
bool deleteAllIndex(QStringList *pathlist);
|
bool deleteAllIndex(QStringList *pathlist);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit IndexGenerator(bool rebuild = false,QObject *parent = nullptr);
|
explicit IndexGenerator(bool rebuild = false, QObject *parent = nullptr);
|
||||||
static QMutex m_mutex;
|
static QMutex m_mutex;
|
||||||
//For file name index
|
//For file name index
|
||||||
void HandlePathList(QQueue<QVector<QString> > *messageList);
|
void HandlePathList(QQueue<QVector<QString> > *messageList);
|
||||||
|
@ -72,7 +71,7 @@ private:
|
||||||
|
|
||||||
// QList<Document> *m_doc_list_path; //for path index
|
// QList<Document> *m_doc_list_path; //for path index
|
||||||
// QList<Document> *m_doc_list_content; // for text content index
|
// QList<Document> *m_doc_list_content; // for text content index
|
||||||
QMap<QString,QStringList> m_index_map;
|
QMap<QString, QStringList> m_index_map;
|
||||||
QString m_index_data_path;
|
QString m_index_data_path;
|
||||||
Xapian::WritableDatabase* m_database_path;
|
Xapian::WritableDatabase* m_database_path;
|
||||||
Xapian::WritableDatabase* m_database_content;
|
Xapian::WritableDatabase* m_database_content;
|
||||||
|
|
|
@ -46,8 +46,7 @@
|
||||||
CREATE_FILE_NAME_INDEX \
|
CREATE_FILE_NAME_INDEX \
|
||||||
CREATE_FILE_CONTENT_INDEX
|
CREATE_FILE_CONTENT_INDEX
|
||||||
|
|
||||||
InotifyIndex::InotifyIndex(const QString& path) : Traverse_BFS(path)
|
InotifyIndex::InotifyIndex(const QString& path) : Traverse_BFS(path) {
|
||||||
{
|
|
||||||
qDebug() << "setInotifyMaxUserWatches start";
|
qDebug() << "setInotifyMaxUserWatches start";
|
||||||
UkuiSearchQDBus usQDBus;
|
UkuiSearchQDBus usQDBus;
|
||||||
usQDBus.setInotifyMaxUserWatches();
|
usQDBus.setInotifyMaxUserWatches();
|
||||||
|
@ -55,24 +54,23 @@ InotifyIndex::InotifyIndex(const QString& path) : Traverse_BFS(path)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InotifyIndex::~InotifyIndex()
|
InotifyIndex::~InotifyIndex() {
|
||||||
{
|
|
||||||
IndexGenerator::getInstance()->~IndexGenerator();
|
IndexGenerator::getInstance()->~IndexGenerator();
|
||||||
qWarning() << "~InotifyIndex";
|
qWarning() << "~InotifyIndex";
|
||||||
}
|
}
|
||||||
|
|
||||||
void InotifyIndex::firstTraverse(){
|
void InotifyIndex::firstTraverse() {
|
||||||
QQueue<QString> bfs;
|
QQueue<QString> bfs;
|
||||||
bfs.enqueue(this->path);
|
bfs.enqueue(this->path);
|
||||||
QFileInfoList list;
|
QFileInfoList list;
|
||||||
QDir dir;
|
QDir dir;
|
||||||
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||||
dir.setSorting(QDir::DirsFirst);
|
dir.setSorting(QDir::DirsFirst);
|
||||||
while (!bfs.empty()) {
|
while(!bfs.empty()) {
|
||||||
dir.setPath(bfs.dequeue());
|
dir.setPath(bfs.dequeue());
|
||||||
list = dir.entryInfoList();
|
list = dir.entryInfoList();
|
||||||
for (auto i : list){
|
for(auto i : list) {
|
||||||
if (i.isDir() && (!(i.isSymLink()))){
|
if(i.isDir() && (!(i.isSymLink()))) {
|
||||||
this->AddWatch(i.absoluteFilePath());
|
this->AddWatch(i.absoluteFilePath());
|
||||||
bfs.enqueue(i.absoluteFilePath());
|
bfs.enqueue(i.absoluteFilePath());
|
||||||
}
|
}
|
||||||
|
@ -80,24 +78,24 @@ void InotifyIndex::firstTraverse(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InotifyIndex::DoSomething(const QFileInfo& fileInfo){
|
void InotifyIndex::DoSomething(const QFileInfo& fileInfo) {
|
||||||
qDebug() << fileInfo.fileName() << "-------" << fileInfo.absoluteFilePath();
|
qDebug() << fileInfo.fileName() << "-------" << fileInfo.absoluteFilePath();
|
||||||
if(fileInfo.isDir() && (!fileInfo.isSymLink())){
|
if(fileInfo.isDir() && (!fileInfo.isSymLink())) {
|
||||||
this->AddWatch(fileInfo.absoluteFilePath());
|
this->AddWatch(fileInfo.absoluteFilePath());
|
||||||
}
|
}
|
||||||
QQueue<QVector<QString> > tempFile;
|
QQueue<QVector<QString> > tempFile;
|
||||||
tempFile.enqueue(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString((fileInfo.isDir() && (!fileInfo.isSymLink())) ? "1" : "0"));
|
tempFile.enqueue(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString((fileInfo.isDir() && (!fileInfo.isSymLink())) ? "1" : "0"));
|
||||||
IndexGenerator::getInstance()->creatAllIndex(&tempFile);
|
IndexGenerator::getInstance()->creatAllIndex(&tempFile);
|
||||||
if ((fileInfo.fileName().split(".", QString::SkipEmptyParts).length() > 1) && (true == targetFileTypeMap[fileInfo.fileName().split(".").last()])){
|
if((fileInfo.fileName().split(".", QString::SkipEmptyParts).length() > 1) && (true == targetFileTypeMap[fileInfo.fileName().split(".").last()])) {
|
||||||
QQueue<QString> tmp;
|
QQueue<QString> tmp;
|
||||||
tmp.enqueue(fileInfo.absoluteFilePath());
|
tmp.enqueue(fileInfo.absoluteFilePath());
|
||||||
IndexGenerator::getInstance()->creatAllIndex(&tmp);
|
IndexGenerator::getInstance()->creatAllIndex(&tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InotifyIndex::AddWatch(const QString &path){
|
bool InotifyIndex::AddWatch(const QString &path) {
|
||||||
int ret = inotify_add_watch(m_fd, path.toStdString().c_str(), (IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE | IN_MODIFY));
|
int ret = inotify_add_watch(m_fd, path.toStdString().c_str(), (IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE | IN_MODIFY));
|
||||||
if (ret == -1) {
|
if(ret == -1) {
|
||||||
qDebug() << "AddWatch error:" << path;
|
qDebug() << "AddWatch error:" << path;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -108,67 +106,63 @@ bool InotifyIndex::AddWatch(const QString &path){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InotifyIndex::RemoveWatch(const QString &path, bool removeFromDatabase){
|
bool InotifyIndex::RemoveWatch(const QString &path, bool removeFromDatabase) {
|
||||||
int ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
int ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
||||||
if (ret){
|
if(ret) {
|
||||||
qDebug() << "remove path error";
|
qDebug() << "remove path error";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Q_ASSERT(ret == 0);
|
// Q_ASSERT(ret == 0);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
|
|
||||||
if (removeFromDatabase) {
|
if(removeFromDatabase) {
|
||||||
for (QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();) {
|
for(QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();) {
|
||||||
// qDebug() << i.value();
|
// qDebug() << i.value();
|
||||||
if (i.value().length() > path.length()){
|
if(i.value().length() > path.length()) {
|
||||||
// if (i.value().mid(0, path.length()) == path){
|
// if (i.value().mid(0, path.length()) == path){
|
||||||
// if (path.startsWith(i.value())){
|
// if (path.startsWith(i.value())){
|
||||||
if (i.value().startsWith(path)){
|
if(i.value().startsWith(path)) {
|
||||||
qDebug() << "remove path: " << i.value();
|
qDebug() << "remove path: " << i.value();
|
||||||
ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
||||||
if (ret){
|
if(ret) {
|
||||||
qDebug() << "remove path error";
|
qDebug() << "remove path error";
|
||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
// assert(ret == 0);
|
// assert(ret == 0);
|
||||||
/*--------------------------------*/
|
/*--------------------------------*/
|
||||||
//在此调用删除索引
|
//在此调用删除索引
|
||||||
qDebug() << i.value();
|
qDebug() << i.value();
|
||||||
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(i.value()));
|
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(i.value()));
|
||||||
/*--------------------------------*/
|
/*--------------------------------*/
|
||||||
currentPath.erase(i++);
|
currentPath.erase(i++);
|
||||||
// i++;
|
// i++;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();) {
|
for(QMap<int, QString>::Iterator i = currentPath.begin(); i != currentPath.end();) {
|
||||||
// qDebug() << i.value();
|
// qDebug() << i.value();
|
||||||
if (i.value().length() > path.length()){
|
if(i.value().length() > path.length()) {
|
||||||
// if (i.value().mid(0, path.length()) == path){
|
// if (i.value().mid(0, path.length()) == path){
|
||||||
// if (path.startsWith(i.value())){
|
// if (path.startsWith(i.value())){
|
||||||
if (i.value().startsWith(path)){
|
if(i.value().startsWith(path)) {
|
||||||
qDebug() << "remove path: " << i.value();
|
qDebug() << "remove path: " << i.value();
|
||||||
ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
ret = inotify_rm_watch(m_fd, currentPath.key(path));
|
||||||
if (ret){
|
if(ret) {
|
||||||
qDebug() << "remove path error";
|
qDebug() << "remove path error";
|
||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
// assert(ret == 0);
|
// assert(ret == 0);
|
||||||
currentPath.erase(i++);
|
currentPath.erase(i++);
|
||||||
// i++;
|
// i++;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +173,7 @@ bool InotifyIndex::RemoveWatch(const QString &path, bool removeFromDatabase){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InotifyIndex::eventProcess(const char* buf, ssize_t tmp){
|
void InotifyIndex::eventProcess(const char* buf, ssize_t tmp) {
|
||||||
QQueue<QVector<QString>>* indexQueue = new QQueue<QVector<QString>>();
|
QQueue<QVector<QString>>* indexQueue = new QQueue<QVector<QString>>();
|
||||||
QQueue<QString>* contentIndexQueue = new QQueue<QString>();
|
QQueue<QString>* contentIndexQueue = new QQueue<QString>();
|
||||||
|
|
||||||
|
@ -187,27 +181,27 @@ void InotifyIndex::eventProcess(const char* buf, ssize_t tmp){
|
||||||
numRead = tmp;
|
numRead = tmp;
|
||||||
char * p = const_cast<char*>(buf);
|
char * p = const_cast<char*>(buf);
|
||||||
|
|
||||||
for (; p < buf + numRead;) {
|
for(; p < buf + numRead;) {
|
||||||
struct inotify_event * event = reinterpret_cast<inotify_event *>(p);
|
struct inotify_event * event = reinterpret_cast<inotify_event *>(p);
|
||||||
qDebug() << "Read Event event->wd: " << event->wd;
|
qDebug() << "Read Event event->wd: " << event->wd;
|
||||||
qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
|
qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
|
||||||
if(event->name[0] != '.'){
|
if(event->name[0] != '.') {
|
||||||
qDebug() << QString(currentPath[event->wd] + '/' + event->name);
|
qDebug() << QString(currentPath[event->wd] + '/' + event->name);
|
||||||
// switch (event->mask) {
|
// switch (event->mask) {
|
||||||
if (event->mask & IN_CREATE){
|
if(event->mask & IN_CREATE) {
|
||||||
|
|
||||||
//Create top dir first, traverse it last.
|
//Create top dir first, traverse it last.
|
||||||
qDebug() << "IN_CREATE";
|
qDebug() << "IN_CREATE";
|
||||||
CREATE_FILE
|
CREATE_FILE
|
||||||
if (event->mask & IN_ISDIR){
|
if(event->mask & IN_ISDIR) {
|
||||||
TRAVERSE_DIR
|
TRAVERSE_DIR
|
||||||
}
|
}
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((event->mask & IN_DELETE) | (event->mask & IN_MOVED_FROM)){
|
if((event->mask & IN_DELETE) | (event->mask & IN_MOVED_FROM)) {
|
||||||
qDebug() << "IN_DELETE or IN_MOVED_FROM";
|
qDebug() << "IN_DELETE or IN_MOVED_FROM";
|
||||||
if (event->mask & IN_ISDIR){
|
if(event->mask & IN_ISDIR) {
|
||||||
RemoveWatch(currentPath[event->wd] + '/' + event->name);
|
RemoveWatch(currentPath[event->wd] + '/' + event->name);
|
||||||
}
|
}
|
||||||
//delete once more
|
//delete once more
|
||||||
|
@ -215,24 +209,23 @@ void InotifyIndex::eventProcess(const char* buf, ssize_t tmp){
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->mask & IN_MODIFY){
|
if(event->mask & IN_MODIFY) {
|
||||||
qDebug() << "IN_MODIFY";
|
qDebug() << "IN_MODIFY";
|
||||||
if (!(event->mask & IN_ISDIR)){
|
if(!(event->mask & IN_ISDIR)) {
|
||||||
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
||||||
CREATE_FILE
|
CREATE_FILE
|
||||||
}
|
}
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->mask & IN_MOVED_TO){
|
if(event->mask & IN_MOVED_TO) {
|
||||||
qDebug() << "IN_MOVED_TO";
|
qDebug() << "IN_MOVED_TO";
|
||||||
if (event->mask & IN_ISDIR){
|
if(event->mask & IN_ISDIR) {
|
||||||
RemoveWatch(currentPath[event->wd] + '/' + event->name);
|
RemoveWatch(currentPath[event->wd] + '/' + event->name);
|
||||||
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
// IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
||||||
CREATE_FILE
|
CREATE_FILE
|
||||||
TRAVERSE_DIR
|
TRAVERSE_DIR
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
IndexGenerator::getInstance()->deleteAllIndex(new QStringList(currentPath[event->wd] + '/' + event->name));
|
||||||
CREATE_FILE
|
CREATE_FILE
|
||||||
}
|
}
|
||||||
|
@ -249,9 +242,9 @@ next:
|
||||||
contentIndexQueue = nullptr;
|
contentIndexQueue = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InotifyIndex::run(){
|
void InotifyIndex::run() {
|
||||||
m_fd = inotify_init();
|
m_fd = inotify_init();
|
||||||
qDebug() << "m_fd----------->" <<m_fd;
|
qDebug() << "m_fd----------->" << m_fd;
|
||||||
|
|
||||||
this->AddWatch(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
this->AddWatch(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
||||||
this->setPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
this->setPath(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
||||||
|
@ -261,14 +254,12 @@ void InotifyIndex::run(){
|
||||||
char buffer[2];
|
char buffer[2];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
fifo_fd = open(UKUI_SEARCH_PIPE_PATH, O_RDWR);
|
fifo_fd = open(UKUI_SEARCH_PIPE_PATH, O_RDWR);
|
||||||
if(fifo_fd == -1)
|
if(fifo_fd == -1) {
|
||||||
{
|
|
||||||
perror("open fifo error\n");
|
perror("open fifo error\n");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
int retval = read(fifo_fd, buffer, sizeof(buffer));
|
int retval = read(fifo_fd, buffer, sizeof(buffer));
|
||||||
if(retval == -1)
|
if(retval == -1) {
|
||||||
{
|
|
||||||
perror("read error\n");
|
perror("read error\n");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -276,7 +267,7 @@ void InotifyIndex::run(){
|
||||||
|
|
||||||
printf("read data ok\n");
|
printf("read data ok\n");
|
||||||
close(fifo_fd);
|
close(fifo_fd);
|
||||||
if (buffer[0] & 0x1){
|
if(buffer[0] & 0x1) {
|
||||||
printf("data confirmed\n");
|
printf("data confirmed\n");
|
||||||
}
|
}
|
||||||
unlink(UKUI_SEARCH_PIPE_PATH);
|
unlink(UKUI_SEARCH_PIPE_PATH);
|
||||||
|
@ -285,12 +276,12 @@ void InotifyIndex::run(){
|
||||||
|
|
||||||
ssize_t numRead;
|
ssize_t numRead;
|
||||||
|
|
||||||
while (FileUtils::SearchMethod::INDEXSEARCH == FileUtils::searchMethod) {
|
while(FileUtils::SearchMethod::INDEXSEARCH == FileUtils::searchMethod) {
|
||||||
// for (;;) { /* Read events forever */
|
// for (;;) { /* Read events forever */
|
||||||
memset(buf, 0x00, BUF_LEN);
|
memset(buf, 0x00, BUF_LEN);
|
||||||
numRead = read(m_fd, buf, BUF_LEN);
|
numRead = read(m_fd, buf, BUF_LEN);
|
||||||
|
|
||||||
if (numRead == -1){
|
if(numRead == -1) {
|
||||||
printf("\033[1;31;40mread event error\033[0m\n");
|
printf("\033[1;31;40mread event error\033[0m\n");
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "1");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "1");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -300,16 +291,16 @@ void InotifyIndex::run(){
|
||||||
|
|
||||||
char * tmp = const_cast<char*>(buf);
|
char * tmp = const_cast<char*>(buf);
|
||||||
|
|
||||||
for (; tmp < buf + numRead;) {
|
for(; tmp < buf + numRead;) {
|
||||||
struct inotify_event * event = reinterpret_cast<inotify_event *>(tmp);
|
struct inotify_event * event = reinterpret_cast<inotify_event *>(tmp);
|
||||||
// qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
|
// qDebug() << "Read Event: " << currentPath[event->wd] << QString(event->name) << event->cookie << event->wd << event->mask;
|
||||||
if(event->name[0] != '.'){
|
if(event->name[0] != '.') {
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "0");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "0");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp += sizeof(struct inotify_event) + event->len;
|
tmp += sizeof(struct inotify_event) + event->len;
|
||||||
}
|
}
|
||||||
if (tmp >= buf + numRead) {
|
if(tmp >= buf + numRead) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,14 +308,13 @@ void InotifyIndex::run(){
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0)
|
if(pid == 0) {
|
||||||
{
|
|
||||||
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
prctl(PR_SET_PDEATHSIG, SIGTERM);
|
||||||
prctl(PR_SET_NAME,"inotify-index");
|
prctl(PR_SET_NAME, "inotify-index");
|
||||||
if (numRead == 0) {
|
if(numRead == 0) {
|
||||||
qDebug() << "read() from inotify fd returned 0!";
|
qDebug() << "read() from inotify fd returned 0!";
|
||||||
}
|
}
|
||||||
if (numRead == -1) {
|
if(numRead == -1) {
|
||||||
qDebug() << "read";
|
qDebug() << "read";
|
||||||
}
|
}
|
||||||
eventProcess(buf, numRead);
|
eventProcess(buf, numRead);
|
||||||
|
@ -336,29 +326,27 @@ void InotifyIndex::run(){
|
||||||
|
|
||||||
read_timeout->tv_sec = 40;
|
read_timeout->tv_sec = 40;
|
||||||
read_timeout->tv_usec = 0;
|
read_timeout->tv_usec = 0;
|
||||||
for(;;)
|
for(;;) {
|
||||||
{
|
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_SET(m_fd, &read_fds);
|
FD_SET(m_fd, &read_fds);
|
||||||
qDebug() << read_timeout->tv_sec;
|
qDebug() << read_timeout->tv_sec;
|
||||||
rc = select(m_fd + 1, &read_fds, NULL, NULL, read_timeout);
|
rc = select(m_fd + 1, &read_fds, NULL, NULL, read_timeout);
|
||||||
if ( rc < 0 ) {
|
if(rc < 0) {
|
||||||
// error
|
// error
|
||||||
qWarning() << "select result < 0, error!";
|
qWarning() << "select result < 0, error!";
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "1");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "1");
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
} else if(rc == 0) {
|
||||||
else if ( rc == 0 ) {
|
|
||||||
qDebug() << "select timeout!";
|
qDebug() << "select timeout!";
|
||||||
::free(read_timeout);
|
::free(read_timeout);
|
||||||
IndexGenerator::getInstance()->~IndexGenerator();
|
IndexGenerator::getInstance()->~IndexGenerator();
|
||||||
// GlobalSettings::getInstance()->forceSync();
|
// GlobalSettings::getInstance()->forceSync();
|
||||||
::_exit(0);
|
::_exit(0);
|
||||||
}else{
|
} else {
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "0");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "0");
|
||||||
memset(buf, 0x00, BUF_LEN);
|
memset(buf, 0x00, BUF_LEN);
|
||||||
numRead = read(m_fd, buf, BUF_LEN);
|
numRead = read(m_fd, buf, BUF_LEN);
|
||||||
if (numRead == -1){
|
if(numRead == -1) {
|
||||||
printf("\033[1;31;40mread event error\033[0m\n");
|
printf("\033[1;31;40mread event error\033[0m\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -368,18 +356,16 @@ void InotifyIndex::run(){
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if(pid > 0) {
|
||||||
else if (pid > 0){
|
|
||||||
memset(buf, 0x00, BUF_LEN);
|
memset(buf, 0x00, BUF_LEN);
|
||||||
waitpid(pid, NULL, 0);
|
waitpid(pid, NULL, 0);
|
||||||
--FileUtils::_index_status;
|
--FileUtils::_index_status;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FileUtils::SearchMethod::DIRECTSEARCH == FileUtils::searchMethod) {
|
if(FileUtils::SearchMethod::DIRECTSEARCH == FileUtils::searchMethod) {
|
||||||
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "3");
|
GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "3");
|
||||||
RemoveWatch(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), false);
|
RemoveWatch(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,11 @@
|
||||||
#define BUF_LEN 1024000
|
#define BUF_LEN 1024000
|
||||||
class InotifyIndex;
|
class InotifyIndex;
|
||||||
static InotifyIndex* global_instance_of_index = nullptr;
|
static InotifyIndex* global_instance_of_index = nullptr;
|
||||||
class InotifyIndex : public QThread, public Traverse_BFS
|
class InotifyIndex : public QThread, public Traverse_BFS {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static InotifyIndex* getInstance(const QString& path){
|
static InotifyIndex* getInstance(const QString& path) {
|
||||||
if (!global_instance_of_index) {
|
if(!global_instance_of_index) {
|
||||||
global_instance_of_index = new InotifyIndex(path);
|
global_instance_of_index = new InotifyIndex(path);
|
||||||
}
|
}
|
||||||
return global_instance_of_index;
|
return global_instance_of_index;
|
||||||
|
|
|
@ -25,18 +25,15 @@ size_t SearchManager::uniqueSymbol3 = 0;
|
||||||
QMutex SearchManager::m_mutex1;
|
QMutex SearchManager::m_mutex1;
|
||||||
QMutex SearchManager::m_mutex2;
|
QMutex SearchManager::m_mutex2;
|
||||||
QMutex SearchManager::m_mutex3;
|
QMutex SearchManager::m_mutex3;
|
||||||
SearchManager::SearchManager(QObject *parent) : QObject(parent)
|
SearchManager::SearchManager(QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
m_pool.setMaxThreadCount(2);
|
m_pool.setMaxThreadCount(2);
|
||||||
m_pool.setExpiryTimeout(1000);
|
m_pool.setExpiryTimeout(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchManager::~SearchManager()
|
SearchManager::~SearchManager() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SearchManager::getCurrentIndexCount()
|
int SearchManager::getCurrentIndexCount() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
Xapian::Database db(INDEX_PATH);
|
Xapian::Database db(INDEX_PATH);
|
||||||
return db.get_doccount();
|
return db.get_doccount();
|
||||||
|
@ -46,9 +43,8 @@ int SearchManager::getCurrentIndexCount()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchManager::onKeywordSearch(QString keyword,QQueue<QString> *searchResultFile,QQueue<QString> *searchResultDir,
|
void SearchManager::onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir,
|
||||||
QQueue<QPair<QString,QStringList>> *searchResultContent)
|
QQueue<QPair<QString, QStringList>> *searchResultContent) {
|
||||||
{
|
|
||||||
m_mutex1.lock();
|
m_mutex1.lock();
|
||||||
++uniqueSymbol1;
|
++uniqueSymbol1;
|
||||||
m_mutex1.unlock();
|
m_mutex1.unlock();
|
||||||
|
@ -59,21 +55,21 @@ void SearchManager::onKeywordSearch(QString keyword,QQueue<QString> *searchResul
|
||||||
++uniqueSymbol3;
|
++uniqueSymbol3;
|
||||||
m_mutex3.unlock();
|
m_mutex3.unlock();
|
||||||
|
|
||||||
if (FileUtils::SearchMethod::DIRECTSEARCH == FileUtils::searchMethod) {
|
if(FileUtils::SearchMethod::DIRECTSEARCH == FileUtils::searchMethod) {
|
||||||
DirectSearch *directSearch;
|
DirectSearch *directSearch;
|
||||||
directSearch = new DirectSearch(keyword, searchResultFile, searchResultDir, uniqueSymbol1);
|
directSearch = new DirectSearch(keyword, searchResultFile, searchResultDir, uniqueSymbol1);
|
||||||
m_pool.start(directSearch);
|
m_pool.start(directSearch);
|
||||||
} else if (FileUtils::SearchMethod::INDEXSEARCH == FileUtils::searchMethod) {
|
} else if(FileUtils::SearchMethod::INDEXSEARCH == FileUtils::searchMethod) {
|
||||||
FileSearch *filesearch;
|
FileSearch *filesearch;
|
||||||
filesearch = new FileSearch(searchResultFile,uniqueSymbol1,keyword,"0",1,0,5);
|
filesearch = new FileSearch(searchResultFile, uniqueSymbol1, keyword, "0", 1, 0, 5);
|
||||||
m_pool.start(filesearch);
|
m_pool.start(filesearch);
|
||||||
|
|
||||||
FileSearch *dirsearch;
|
FileSearch *dirsearch;
|
||||||
dirsearch = new FileSearch(searchResultDir,uniqueSymbol2,keyword,"1",1,0,5);
|
dirsearch = new FileSearch(searchResultDir, uniqueSymbol2, keyword, "1", 1, 0, 5);
|
||||||
m_pool.start(dirsearch);
|
m_pool.start(dirsearch);
|
||||||
|
|
||||||
FileContentSearch *contentSearch;
|
FileContentSearch *contentSearch;
|
||||||
contentSearch = new FileContentSearch(searchResultContent,uniqueSymbol3,keyword,0,5);
|
contentSearch = new FileContentSearch(searchResultContent, uniqueSymbol3, keyword, 0, 5);
|
||||||
m_pool.start(contentSearch);
|
m_pool.start(contentSearch);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Unknown search method! FileUtils::searchMethod: " << static_cast<int>(FileUtils::searchMethod);
|
qWarning() << "Unknown search method! FileUtils::searchMethod: " << static_cast<int>(FileUtils::searchMethod);
|
||||||
|
@ -81,11 +77,9 @@ void SearchManager::onKeywordSearch(QString keyword,QQueue<QString> *searchResul
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SearchManager::isBlocked(QString &path)
|
bool SearchManager::isBlocked(QString &path) {
|
||||||
{
|
|
||||||
QStringList blockList = GlobalSettings::getInstance()->getBlockDirs();
|
QStringList blockList = GlobalSettings::getInstance()->getBlockDirs();
|
||||||
for(QString i : blockList)
|
for(QString i : blockList) {
|
||||||
{
|
|
||||||
if(path.startsWith(i.prepend("/")))
|
if(path.startsWith(i.prepend("/")))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -93,8 +87,7 @@ bool SearchManager::isBlocked(QString &path)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSearch::FileSearch(QQueue<QString> *searchResult,size_t uniqueSymbol, QString keyword, QString value, unsigned slot, int begin, int num)
|
FileSearch::FileSearch(QQueue<QString> *searchResult, size_t uniqueSymbol, QString keyword, QString value, unsigned slot, int begin, int num) {
|
||||||
{
|
|
||||||
this->setAutoDelete(true);
|
this->setAutoDelete(true);
|
||||||
m_search_result = searchResult;
|
m_search_result = searchResult;
|
||||||
m_uniqueSymbol = uniqueSymbol;
|
m_uniqueSymbol = uniqueSymbol;
|
||||||
|
@ -105,21 +98,19 @@ FileSearch::FileSearch(QQueue<QString> *searchResult,size_t uniqueSymbol, QStrin
|
||||||
m_num = num;
|
m_num = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSearch::~FileSearch()
|
FileSearch::~FileSearch() {
|
||||||
{
|
|
||||||
m_search_result = nullptr;
|
m_search_result = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSearch::run()
|
void FileSearch::run() {
|
||||||
{
|
if(!m_search_result->isEmpty()) {
|
||||||
if (!m_search_result->isEmpty()){
|
|
||||||
m_search_result->clear();
|
m_search_result->clear();
|
||||||
}
|
}
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
while (total < 100) {
|
while(total < 100) {
|
||||||
resultCount = keywordSearchfile();
|
resultCount = keywordSearchfile();
|
||||||
if (resultCount == 0 || resultCount == -1)
|
if(resultCount == 0 || resultCount == -1)
|
||||||
break;
|
break;
|
||||||
total += resultCount;
|
total += resultCount;
|
||||||
m_begin += m_num;
|
m_begin += m_num;
|
||||||
|
@ -127,8 +118,7 @@ void FileSearch::run()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearch::keywordSearchfile()
|
int FileSearch::keywordSearchfile() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
qDebug() << "--keywordSearchfile start--";
|
qDebug() << "--keywordSearchfile start--";
|
||||||
Xapian::Database db(INDEX_PATH);
|
Xapian::Database db(INDEX_PATH);
|
||||||
|
@ -136,49 +126,47 @@ int FileSearch::keywordSearchfile()
|
||||||
Xapian::Enquire enquire(db);
|
Xapian::Enquire enquire(db);
|
||||||
|
|
||||||
Xapian::Query queryFile;
|
Xapian::Query queryFile;
|
||||||
if (!m_value.isEmpty()) {
|
if(!m_value.isEmpty()) {
|
||||||
std::string slotValue = m_value.toStdString();
|
std::string slotValue = m_value.toStdString();
|
||||||
Xapian::Query queryValue = Xapian::Query(Xapian::Query::OP_VALUE_RANGE,m_slot,slotValue,slotValue);
|
Xapian::Query queryValue = Xapian::Query(Xapian::Query::OP_VALUE_RANGE, m_slot, slotValue, slotValue);
|
||||||
queryFile = Xapian::Query(Xapian::Query::OP_AND,query,queryValue);
|
queryFile = Xapian::Query(Xapian::Query::OP_AND, query, queryValue);
|
||||||
} else {
|
} else {
|
||||||
queryFile = query;
|
queryFile = query;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "keywordSearchfile:"<<QString::fromStdString(queryFile.get_description());
|
qDebug() << "keywordSearchfile:" << QString::fromStdString(queryFile.get_description());
|
||||||
|
|
||||||
enquire.set_query(queryFile);
|
enquire.set_query(queryFile);
|
||||||
Xapian::MSet result = enquire.get_mset(m_begin, m_num);
|
Xapian::MSet result = enquire.get_mset(m_begin, m_num);
|
||||||
int resultCount = result.size();
|
int resultCount = result.size();
|
||||||
qDebug() << "keywordSearchfile results count=" <<resultCount;
|
qDebug() << "keywordSearchfile results count=" << resultCount;
|
||||||
if (resultCount == 0)
|
if(resultCount == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (getResult(result) == -1)
|
if(getResult(result) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
qDebug() << "--keywordSearchfile finish--";
|
qDebug() << "--keywordSearchfile finish--";
|
||||||
return resultCount;
|
return resultCount;
|
||||||
} catch (const Xapian::Error &e) {
|
} catch(const Xapian::Error &e) {
|
||||||
qWarning() <<QString::fromStdString(e.get_description());
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
qDebug() << "--keywordSearchfile finish--";
|
qDebug() << "--keywordSearchfile finish--";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Xapian::Query FileSearch::creatQueryForFileSearch(Xapian::Database &db)
|
Xapian::Query FileSearch::creatQueryForFileSearch(Xapian::Database &db) {
|
||||||
{
|
|
||||||
auto userInput = m_keyword.toLower();
|
auto userInput = m_keyword.toLower();
|
||||||
std::vector<Xapian::Query> v;
|
std::vector<Xapian::Query> v;
|
||||||
for (int i=0;i<userInput.size();i++) {
|
for(int i = 0; i < userInput.size(); i++) {
|
||||||
v.push_back(Xapian::Query(QUrl::toPercentEncoding(userInput.at(i)).toStdString()));
|
v.push_back(Xapian::Query(QUrl::toPercentEncoding(userInput.at(i)).toStdString()));
|
||||||
// qDebug()<<QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
// qDebug()<<QString::fromStdString(Xapian::Query(QString(userInput.at(i)).toStdString()).get_description());
|
||||||
}
|
}
|
||||||
Xapian::Query queryPhrase =Xapian::Query(Xapian::Query::OP_PHRASE, v.begin(), v.end());
|
Xapian::Query queryPhrase = Xapian::Query(Xapian::Query::OP_PHRASE, v.begin(), v.end());
|
||||||
return queryPhrase;
|
return queryPhrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSearch::getResult(Xapian::MSet &result)
|
int FileSearch::getResult(Xapian::MSet &result) {
|
||||||
{
|
for(auto it = result.begin(); it != result.end(); ++it) {
|
||||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
|
||||||
Xapian::Document doc = it.get_document();
|
Xapian::Document doc = it.get_document();
|
||||||
std::string data = doc.get_data();
|
std::string data = doc.get_data();
|
||||||
Xapian::weight docScoreWeight = it.get_weight();
|
Xapian::weight docScoreWeight = it.get_weight();
|
||||||
|
@ -186,20 +174,20 @@ int FileSearch::getResult(Xapian::MSet &result)
|
||||||
QString path = QString::fromStdString(data);
|
QString path = QString::fromStdString(data);
|
||||||
std::string().swap(data);
|
std::string().swap(data);
|
||||||
|
|
||||||
if (SearchManager::isBlocked(path)) {
|
if(SearchManager::isBlocked(path)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo info(path);
|
QFileInfo info(path);
|
||||||
|
|
||||||
if (!info.exists()) {
|
if(!info.exists()) {
|
||||||
// pathTobeDelete->append(QString::fromStdString(data));
|
// pathTobeDelete->append(QString::fromStdString(data));
|
||||||
qDebug()<<path<<"is not exist!!";
|
qDebug() << path << "is not exist!!";
|
||||||
} else {
|
} else {
|
||||||
switch (m_value.toInt()) {
|
switch(m_value.toInt()) {
|
||||||
case 1:
|
case 1:
|
||||||
SearchManager::m_mutex1.lock();
|
SearchManager::m_mutex1.lock();
|
||||||
if (m_uniqueSymbol == SearchManager::uniqueSymbol2) {
|
if(m_uniqueSymbol == SearchManager::uniqueSymbol2) {
|
||||||
m_search_result->enqueue(path);
|
m_search_result->enqueue(path);
|
||||||
SearchManager::m_mutex1.unlock();
|
SearchManager::m_mutex1.unlock();
|
||||||
} else {
|
} else {
|
||||||
|
@ -230,8 +218,7 @@ int FileSearch::getResult(Xapian::MSet &result)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileContentSearch::FileContentSearch(QQueue<QPair<QString,QStringList>> *searchResult, size_t uniqueSymbol, QString keyword, int begin, int num)
|
FileContentSearch::FileContentSearch(QQueue<QPair<QString, QStringList>> *searchResult, size_t uniqueSymbol, QString keyword, int begin, int num) {
|
||||||
{
|
|
||||||
this->setAutoDelete(true);
|
this->setAutoDelete(true);
|
||||||
m_search_result = searchResult;
|
m_search_result = searchResult;
|
||||||
m_uniqueSymbol = uniqueSymbol;
|
m_uniqueSymbol = uniqueSymbol;
|
||||||
|
@ -240,22 +227,20 @@ FileContentSearch::FileContentSearch(QQueue<QPair<QString,QStringList>> *searchR
|
||||||
m_num = num;
|
m_num = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileContentSearch::~FileContentSearch()
|
FileContentSearch::~FileContentSearch() {
|
||||||
{
|
|
||||||
m_search_result = nullptr;
|
m_search_result = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileContentSearch::run()
|
void FileContentSearch::run() {
|
||||||
{
|
if(!m_search_result->isEmpty()) {
|
||||||
if (!m_search_result->isEmpty()) {
|
|
||||||
m_search_result->clear();
|
m_search_result->clear();
|
||||||
}
|
}
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
||||||
while (total<50) {
|
while(total < 50) {
|
||||||
resultCount = keywordSearchContent();
|
resultCount = keywordSearchContent();
|
||||||
if (resultCount == 0 || resultCount == -1) {
|
if(resultCount == 0 || resultCount == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
total += resultCount;
|
total += resultCount;
|
||||||
|
@ -264,34 +249,33 @@ void FileContentSearch::run()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileContentSearch::keywordSearchContent()
|
int FileContentSearch::keywordSearchContent() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
qDebug()<<"--keywordSearchContent search start--";
|
qDebug() << "--keywordSearchContent search start--";
|
||||||
|
|
||||||
Xapian::Database db(CONTENT_INDEX_PATH);
|
Xapian::Database db(CONTENT_INDEX_PATH);
|
||||||
Xapian::Enquire enquire(db);
|
Xapian::Enquire enquire(db);
|
||||||
Xapian::QueryParser qp;
|
Xapian::QueryParser qp;
|
||||||
qp.set_default_op(Xapian::Query::OP_AND);
|
qp.set_default_op(Xapian::Query::OP_AND);
|
||||||
qp.set_database(db);
|
qp.set_database(db);
|
||||||
/*
|
/*
|
||||||
::friso::ResultMap ret;
|
::friso::ResultMap ret;
|
||||||
::friso::FrisoSegmentation::getInstance()->callSegement(ret, keyword.toLocal8Bit().data());
|
::friso::FrisoSegmentation::getInstance()->callSegement(ret, keyword.toLocal8Bit().data());
|
||||||
for (::friso::ResultMap::iterator it_map = ret.begin(); it_map != ret.end(); ++it_map){
|
for (::friso::ResultMap::iterator it_map = ret.begin(); it_map != ret.end(); ++it_map){
|
||||||
target_str += it_map->first;
|
target_str += it_map->first;
|
||||||
target_str += " ";
|
target_str += " ";
|
||||||
it_map->second.first.clear();
|
it_map->second.first.clear();
|
||||||
::std::vector<size_t>().swap(it_map->second.first);
|
::std::vector<size_t>().swap(it_map->second.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.clear();
|
ret.clear();
|
||||||
ret.erase(ret.begin(), ret.end());
|
ret.erase(ret.begin(), ret.end());
|
||||||
::friso::ResultMap().swap(ret);
|
::friso::ResultMap().swap(ret);
|
||||||
*/
|
*/
|
||||||
QVector<SKeyWord> sKeyWord = ChineseSegmentation::getInstance()->callSegement(m_keyword);
|
QVector<SKeyWord> sKeyWord = ChineseSegmentation::getInstance()->callSegement(m_keyword);
|
||||||
//Creat a query
|
//Creat a query
|
||||||
std::string words;
|
std::string words;
|
||||||
for (int i=0; i<sKeyWord.size(); i++) {
|
for(int i = 0; i < sKeyWord.size(); i++) {
|
||||||
words.append(sKeyWord.at(i).word).append(" ");
|
words.append(sKeyWord.at(i).word).append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,16 +308,16 @@ int FileContentSearch::keywordSearchContent()
|
||||||
|
|
||||||
Xapian::MSet result = enquire.get_mset(m_begin, m_num);
|
Xapian::MSet result = enquire.get_mset(m_begin, m_num);
|
||||||
int resultCount = result.size();
|
int resultCount = result.size();
|
||||||
if (result.size() == 0) {
|
if(result.size() == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
qDebug() << "keywordSearchContent results count=" << resultCount;
|
qDebug() << "keywordSearchContent results count=" << resultCount;
|
||||||
|
|
||||||
if (getResult(result,words) == -1){
|
if(getResult(result, words) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug()<< "--keywordSearchContent search finish--";
|
qDebug() << "--keywordSearchContent search finish--";
|
||||||
return resultCount;
|
return resultCount;
|
||||||
} catch(const Xapian::Error &e) {
|
} catch(const Xapian::Error &e) {
|
||||||
qWarning() << QString::fromStdString(e.get_description());
|
qWarning() << QString::fromStdString(e.get_description());
|
||||||
|
@ -342,22 +326,21 @@ int FileContentSearch::keywordSearchContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord)
|
int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord) {
|
||||||
{
|
for(auto it = result.begin(); it != result.end(); ++it) {
|
||||||
for (auto it = result.begin(); it != result.end(); ++it) {
|
|
||||||
Xapian::Document doc = it.get_document();
|
Xapian::Document doc = it.get_document();
|
||||||
std::string data = doc.get_data();
|
std::string data = doc.get_data();
|
||||||
double docScoreWeight = it.get_weight();
|
double docScoreWeight = it.get_weight();
|
||||||
Xapian::percent docScorePercent = it.get_percent();
|
Xapian::percent docScorePercent = it.get_percent();
|
||||||
QString path = QString::fromStdString(doc.get_value(1));
|
QString path = QString::fromStdString(doc.get_value(1));
|
||||||
|
|
||||||
if (SearchManager::isBlocked(path)){
|
if(SearchManager::isBlocked(path)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo info(path);
|
QFileInfo info(path);
|
||||||
|
|
||||||
if (!info.exists()) {
|
if(!info.exists()) {
|
||||||
// pathTobeDelete->append(QString::fromStdString(data));
|
// pathTobeDelete->append(QString::fromStdString(data));
|
||||||
qDebug() << path << "is not exist!!";
|
qDebug() << path << "is not exist!!";
|
||||||
continue;
|
continue;
|
||||||
|
@ -367,15 +350,15 @@ int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord)
|
||||||
// snippets.append(QString::fromStdString( result.snippet(doc.get_data(),400)));
|
// snippets.append(QString::fromStdString( result.snippet(doc.get_data(),400)));
|
||||||
// qWarning()<<QString::fromStdString(s);
|
// qWarning()<<QString::fromStdString(s);
|
||||||
auto term = doc.termlist_begin();
|
auto term = doc.termlist_begin();
|
||||||
std::string wordTobeFound = QString::fromStdString(keyWord).section(" ",0,0).toStdString();
|
std::string wordTobeFound = QString::fromStdString(keyWord).section(" ", 0, 0).toStdString();
|
||||||
int size = wordTobeFound.length();
|
int size = wordTobeFound.length();
|
||||||
term.skip_to(wordTobeFound);
|
term.skip_to(wordTobeFound);
|
||||||
int count =0;
|
int count = 0;
|
||||||
for (auto pos = term.positionlist_begin();pos != term.positionlist_end()&&count < 6;++pos) {
|
for(auto pos = term.positionlist_begin(); pos != term.positionlist_end() && count < 6; ++pos) {
|
||||||
std::string s = data.substr((*pos < 60)? 0: (*pos - 60) , size + 120);
|
std::string s = data.substr((*pos < 60) ? 0 : (*pos - 60), size + 120);
|
||||||
QString snippet = QString::fromStdString(s);
|
QString snippet = QString::fromStdString(s);
|
||||||
if (snippet.size() > 6 + QString::fromStdString(keyWord).size()){
|
if(snippet.size() > 6 + QString::fromStdString(keyWord).size()) {
|
||||||
snippet.replace(0,3,"...").replace(snippet.size()-3,3,"...");
|
snippet.replace(0, 3, "...").replace(snippet.size() - 3, 3, "...");
|
||||||
} else {
|
} else {
|
||||||
snippet.append("...").prepend("...");
|
snippet.append("...").prepend("...");
|
||||||
}
|
}
|
||||||
|
@ -402,8 +385,8 @@ int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
SearchManager::m_mutex3.lock();
|
SearchManager::m_mutex3.lock();
|
||||||
if (m_uniqueSymbol == SearchManager::uniqueSymbol3) {
|
if(m_uniqueSymbol == SearchManager::uniqueSymbol3) {
|
||||||
m_search_result->enqueue(qMakePair(path,snippets));
|
m_search_result->enqueue(qMakePair(path, snippets));
|
||||||
SearchManager::m_mutex3.unlock();
|
SearchManager::m_mutex3.unlock();
|
||||||
snippets.clear();
|
snippets.clear();
|
||||||
QStringList().swap(snippets);
|
QStringList().swap(snippets);
|
||||||
|
@ -419,8 +402,7 @@ int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectSearch::DirectSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, size_t uniqueSymbol)
|
DirectSearch::DirectSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, size_t uniqueSymbol) {
|
||||||
{
|
|
||||||
this->setAutoDelete(true);
|
this->setAutoDelete(true);
|
||||||
m_keyword = keyword;
|
m_keyword = keyword;
|
||||||
m_searchResultFile = searchResultFile;
|
m_searchResultFile = searchResultFile;
|
||||||
|
@ -428,8 +410,7 @@ DirectSearch::DirectSearch(QString keyword, QQueue<QString> *searchResultFile, Q
|
||||||
m_uniqueSymbol = uniqueSymbol;
|
m_uniqueSymbol = uniqueSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectSearch::run()
|
void DirectSearch::run() {
|
||||||
{
|
|
||||||
QQueue<QString> bfs;
|
QQueue<QString> bfs;
|
||||||
bfs.enqueue(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
bfs.enqueue(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
|
||||||
QFileInfoList list;
|
QFileInfoList list;
|
||||||
|
@ -437,25 +418,25 @@ void DirectSearch::run()
|
||||||
// QDir::Hidden
|
// QDir::Hidden
|
||||||
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||||
dir.setSorting(QDir::DirsFirst);
|
dir.setSorting(QDir::DirsFirst);
|
||||||
while (!bfs.empty()) {
|
while(!bfs.empty()) {
|
||||||
dir.setPath(bfs.dequeue());
|
dir.setPath(bfs.dequeue());
|
||||||
list = dir.entryInfoList();
|
list = dir.entryInfoList();
|
||||||
for (auto i : list) {
|
for(auto i : list) {
|
||||||
if (i.isDir() && (!(i.isSymLink()))) {
|
if(i.isDir() && (!(i.isSymLink()))) {
|
||||||
bfs.enqueue(i.absoluteFilePath());
|
bfs.enqueue(i.absoluteFilePath());
|
||||||
}
|
}
|
||||||
if (i.fileName().contains(m_keyword, Qt::CaseInsensitive)) {
|
if(i.fileName().contains(m_keyword, Qt::CaseInsensitive)) {
|
||||||
SearchManager::m_mutex1.lock();
|
SearchManager::m_mutex1.lock();
|
||||||
// qWarning() << i.fileName() << m_keyword;
|
// qWarning() << i.fileName() << m_keyword;
|
||||||
if (m_uniqueSymbol == SearchManager::uniqueSymbol1) {
|
if(m_uniqueSymbol == SearchManager::uniqueSymbol1) {
|
||||||
// TODO
|
// TODO
|
||||||
if (i.isDir() && m_searchResultDir->length() < 51) {
|
if(i.isDir() && m_searchResultDir->length() < 51) {
|
||||||
m_searchResultDir->enqueue(i.absoluteFilePath());
|
m_searchResultDir->enqueue(i.absoluteFilePath());
|
||||||
} else if (m_searchResultFile->length() < 51) {
|
} else if(m_searchResultFile->length() < 51) {
|
||||||
m_searchResultFile->enqueue(i.absoluteFilePath());
|
m_searchResultFile->enqueue(i.absoluteFilePath());
|
||||||
}
|
}
|
||||||
SearchManager::m_mutex1.unlock();
|
SearchManager::m_mutex1.unlock();
|
||||||
if (m_searchResultDir->length() > 49 && m_searchResultFile->length() > 49) {
|
if(m_searchResultDir->length() > 49 && m_searchResultFile->length() > 49) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -46,8 +46,7 @@
|
||||||
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
|
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
|
||||||
|
|
||||||
|
|
||||||
class SearchManager : public QObject
|
class SearchManager : public QObject {
|
||||||
{
|
|
||||||
friend class FileSearch;
|
friend class FileSearch;
|
||||||
friend class FileContentSearch;
|
friend class FileContentSearch;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -65,12 +64,12 @@ public:
|
||||||
static QMutex m_mutex3;
|
static QMutex m_mutex3;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onKeywordSearch(QString keyword,QQueue<QString> *searchResultFile,QQueue<QString> *searchResultDir,QQueue<QPair<QString,QStringList>> *searchResultContent);
|
void onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, QQueue<QPair<QString, QStringList>> *searchResultContent);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void resultFile(QQueue<QString> *);
|
void resultFile(QQueue<QString> *);
|
||||||
void resultDir(QQueue<QString> *);
|
void resultDir(QQueue<QString> *);
|
||||||
void resultContent(QQueue<QPair<QString,QStringList>> *);
|
void resultContent(QQueue<QPair<QString, QStringList>> *);
|
||||||
private:
|
private:
|
||||||
// int keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value,unsigned slot = 1,int begin = 0, int num = 20);
|
// int keywordSearchfile(size_t uniqueSymbol, QString keyword, QString value,unsigned slot = 1,int begin = 0, int num = 20);
|
||||||
// int keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
// int keywordSearchContent(size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
||||||
|
@ -96,10 +95,9 @@ private:
|
||||||
QThreadPool m_pool;
|
QThreadPool m_pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileSearch : public QRunnable
|
class FileSearch : public QRunnable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit FileSearch(QQueue<QString> *searchResult,size_t uniqueSymbol, QString keyword, QString value,unsigned slot = 1,int begin = 0, int num = 20);
|
explicit FileSearch(QQueue<QString> *searchResult, size_t uniqueSymbol, QString keyword, QString value, unsigned slot = 1, int begin = 0, int num = 20);
|
||||||
~FileSearch();
|
~FileSearch();
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
|
@ -117,26 +115,24 @@ private:
|
||||||
int m_num = 20;
|
int m_num = 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileContentSearch : public QRunnable
|
class FileContentSearch : public QRunnable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit FileContentSearch(QQueue<QPair<QString,QStringList>> *searchResult,size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
explicit FileContentSearch(QQueue<QPair<QString, QStringList>> *searchResult, size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
|
||||||
~FileContentSearch();
|
~FileContentSearch();
|
||||||
protected:
|
protected:
|
||||||
void run();
|
void run();
|
||||||
private:
|
private:
|
||||||
int keywordSearchContent();
|
int keywordSearchContent();
|
||||||
int getResult(Xapian::MSet &result,std::string &keyWord);
|
int getResult(Xapian::MSet &result, std::string &keyWord);
|
||||||
|
|
||||||
QQueue<QPair<QString,QStringList>> *m_search_result = nullptr;
|
QQueue<QPair<QString, QStringList>> *m_search_result = nullptr;
|
||||||
size_t m_uniqueSymbol;
|
size_t m_uniqueSymbol;
|
||||||
QString m_keyword;
|
QString m_keyword;
|
||||||
int m_begin = 0;
|
int m_begin = 0;
|
||||||
int m_num = 20;
|
int m_num = 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirectSearch : public QRunnable
|
class DirectSearch : public QRunnable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit DirectSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, size_t uniqueSymbol);
|
explicit DirectSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, size_t uniqueSymbol);
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
#include "searchmethodmanager.h"
|
#include "searchmethodmanager.h"
|
||||||
|
|
||||||
void SearchMethodManager::searchMethod(FileUtils::SearchMethod sm)
|
void SearchMethodManager::searchMethod(FileUtils::SearchMethod sm) {
|
||||||
{
|
|
||||||
qWarning() << "searchMethod start: " << static_cast<int>(sm);
|
qWarning() << "searchMethod start: " << static_cast<int>(sm);
|
||||||
if (FileUtils::SearchMethod::INDEXSEARCH == sm || FileUtils::SearchMethod::DIRECTSEARCH == sm) {
|
if(FileUtils::SearchMethod::INDEXSEARCH == sm || FileUtils::SearchMethod::DIRECTSEARCH == sm) {
|
||||||
FileUtils::searchMethod = sm;
|
FileUtils::searchMethod = sm;
|
||||||
} else {
|
} else {
|
||||||
printf("enum class error!!!\n");
|
printf("enum class error!!!\n");
|
||||||
qWarning("enum class error!!!\n");
|
qWarning("enum class error!!!\n");
|
||||||
}
|
}
|
||||||
if (FileUtils::SearchMethod::INDEXSEARCH == sm && 0 == FileUtils::_index_status) {
|
if(FileUtils::SearchMethod::INDEXSEARCH == sm && 0 == FileUtils::_index_status) {
|
||||||
qWarning() << "start first index";
|
qWarning() << "start first index";
|
||||||
// m_fi = FirstIndex("/home/zhangzihao/Desktop");
|
// m_fi = FirstIndex("/home/zhangzihao/Desktop");
|
||||||
m_fi.start();
|
m_fi.start();
|
||||||
|
@ -17,10 +16,10 @@ void SearchMethodManager::searchMethod(FileUtils::SearchMethod sm)
|
||||||
// InotifyIndex ii("/home");
|
// InotifyIndex ii("/home");
|
||||||
// ii.start();
|
// ii.start();
|
||||||
this->m_ii = InotifyIndex::getInstance("/home");
|
this->m_ii = InotifyIndex::getInstance("/home");
|
||||||
if (!this->m_ii->isRunning()) {
|
if(!this->m_ii->isRunning()) {
|
||||||
this->m_ii->start();
|
this->m_ii->start();
|
||||||
}
|
}
|
||||||
qDebug()<<"Search method has been set to INDEXSEARCH";
|
qDebug() << "Search method has been set to INDEXSEARCH";
|
||||||
}
|
}
|
||||||
qWarning() << "searchMethod end: " << static_cast<int>(FileUtils::searchMethod);
|
qWarning() << "searchMethod end: " << static_cast<int>(FileUtils::searchMethod);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
#include "first-index.h"
|
#include "first-index.h"
|
||||||
#include "inotify-index.h"
|
#include "inotify-index.h"
|
||||||
|
|
||||||
class SearchMethodManager
|
class SearchMethodManager {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SearchMethodManager() = default;
|
SearchMethodManager() = default;
|
||||||
void searchMethod(FileUtils::SearchMethod sm);
|
void searchMethod(FileUtils::SearchMethod sm);
|
||||||
|
|
|
@ -19,13 +19,12 @@
|
||||||
*/
|
*/
|
||||||
#include "traverse_bfs.h"
|
#include "traverse_bfs.h"
|
||||||
|
|
||||||
Traverse_BFS::Traverse_BFS(const QString& path)
|
Traverse_BFS::Traverse_BFS(const QString& path) {
|
||||||
{
|
|
||||||
Q_ASSERT('/' == path.at(0));
|
Q_ASSERT('/' == path.at(0));
|
||||||
this->path = path;
|
this->path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Traverse_BFS::Traverse(){
|
void Traverse_BFS::Traverse() {
|
||||||
QQueue<QString> bfs;
|
QQueue<QString> bfs;
|
||||||
bfs.enqueue(this->path);
|
bfs.enqueue(this->path);
|
||||||
QFileInfoList list;
|
QFileInfoList list;
|
||||||
|
@ -33,11 +32,11 @@ void Traverse_BFS::Traverse(){
|
||||||
// QDir::Hidden
|
// QDir::Hidden
|
||||||
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||||
dir.setSorting(QDir::DirsFirst);
|
dir.setSorting(QDir::DirsFirst);
|
||||||
while (!bfs.empty()) {
|
while(!bfs.empty()) {
|
||||||
dir.setPath(bfs.dequeue());
|
dir.setPath(bfs.dequeue());
|
||||||
list = dir.entryInfoList();
|
list = dir.entryInfoList();
|
||||||
for (auto i : list){
|
for(auto i : list) {
|
||||||
if (i.isDir() && (!(i.isSymLink()))){
|
if(i.isDir() && (!(i.isSymLink()))) {
|
||||||
bfs.enqueue(i.absoluteFilePath());
|
bfs.enqueue(i.absoluteFilePath());
|
||||||
}
|
}
|
||||||
DoSomething(i);
|
DoSomething(i);
|
||||||
|
@ -45,6 +44,6 @@ void Traverse_BFS::Traverse(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Traverse_BFS::setPath(const QString& path){
|
void Traverse_BFS::setPath(const QString& path) {
|
||||||
this->path = path;
|
this->path = path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
class Traverse_BFS
|
class Traverse_BFS {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Traverse_BFS() = default;
|
Traverse_BFS() = default;
|
||||||
void Traverse();
|
void Traverse();
|
||||||
|
|
|
@ -20,25 +20,23 @@
|
||||||
#include "ukui-search-qdbus.h"
|
#include "ukui-search-qdbus.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
UkuiSearchQDBus::UkuiSearchQDBus()
|
UkuiSearchQDBus::UkuiSearchQDBus() {
|
||||||
{
|
|
||||||
this->tmpSystemQDBusInterface = new QDBusInterface("com.ukui.search.qt.systemdbus",
|
this->tmpSystemQDBusInterface = new QDBusInterface("com.ukui.search.qt.systemdbus",
|
||||||
"/",
|
"/",
|
||||||
"com.ukui.search.interface",
|
"com.ukui.search.interface",
|
||||||
QDBusConnection::systemBus());
|
QDBusConnection::systemBus());
|
||||||
if (!tmpSystemQDBusInterface->isValid()){
|
if(!tmpSystemQDBusInterface->isValid()) {
|
||||||
qCritical() << "Create Client Interface Failed When execute chage: " << QDBusConnection::systemBus().lastError();
|
qCritical() << "Create Client Interface Failed When execute chage: " << QDBusConnection::systemBus().lastError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UkuiSearchQDBus::~UkuiSearchQDBus(){
|
UkuiSearchQDBus::~UkuiSearchQDBus() {
|
||||||
delete this->tmpSystemQDBusInterface;
|
delete this->tmpSystemQDBusInterface;
|
||||||
this->tmpSystemQDBusInterface = nullptr;
|
this->tmpSystemQDBusInterface = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//一键三连
|
//一键三连
|
||||||
void UkuiSearchQDBus::setInotifyMaxUserWatches()
|
void UkuiSearchQDBus::setInotifyMaxUserWatches() {
|
||||||
{
|
|
||||||
// /proc/sys/fs/inotify/max_user_watches
|
// /proc/sys/fs/inotify/max_user_watches
|
||||||
this->tmpSystemQDBusInterface->call("setInotifyMaxUserWatchesStep1");
|
this->tmpSystemQDBusInterface->call("setInotifyMaxUserWatchesStep1");
|
||||||
// sysctl
|
// sysctl
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
|
|
||||||
#include <QDBusInterface>
|
#include <QDBusInterface>
|
||||||
|
|
||||||
class UkuiSearchQDBus
|
class UkuiSearchQDBus {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
UkuiSearchQDBus();
|
UkuiSearchQDBus();
|
||||||
~UkuiSearchQDBus();
|
~UkuiSearchQDBus();
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
#include "index/inotify-index.h"
|
#include "index/inotify-index.h"
|
||||||
#include "index/search-manager.h"
|
#include "index/search-manager.h"
|
||||||
|
|
||||||
class LIBSEARCH_EXPORT GlobalSearch
|
class LIBSEARCH_EXPORT GlobalSearch {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static QStringList fileSearch(QString keyword, int begin = 0, int num = -1);
|
static QStringList fileSearch(QString keyword, int begin = 0, int num = -1);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,22 +7,19 @@
|
||||||
#define UCHAR unsigned char
|
#define UCHAR unsigned char
|
||||||
#define USHORT unsigned short
|
#define USHORT unsigned short
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
Word = 0,
|
||||||
Word = 0,
|
Excel,
|
||||||
Excel,
|
Ppt
|
||||||
Ppt
|
} TYPE;
|
||||||
}TYPE;
|
|
||||||
|
|
||||||
/* Property Set Storage */
|
/* Property Set Storage */
|
||||||
typedef struct pps_tag
|
typedef struct pps_tag {
|
||||||
{
|
|
||||||
ULONG ulSB;
|
ULONG ulSB;
|
||||||
ULONG ulSize;
|
ULONG ulSize;
|
||||||
} ppsTag;
|
} ppsTag;
|
||||||
|
|
||||||
typedef struct pps_info_tag
|
typedef struct pps_info_tag {
|
||||||
{
|
|
||||||
ppsTag tWordDocument; /* Text stream */
|
ppsTag tWordDocument; /* Text stream */
|
||||||
ppsTag tWorkBook;
|
ppsTag tWorkBook;
|
||||||
ppsTag tPPTDocument;
|
ppsTag tPPTDocument;
|
||||||
|
@ -37,8 +34,7 @@ typedef struct pps_info_tag
|
||||||
} ppsInfoType;
|
} ppsInfoType;
|
||||||
|
|
||||||
/* Private type for Property Set Storage entries */
|
/* Private type for Property Set Storage entries */
|
||||||
typedef struct pps_entry_tag
|
typedef struct pps_entry_tag {
|
||||||
{
|
|
||||||
ULONG ulNext;
|
ULONG ulNext;
|
||||||
ULONG ulPrevious;
|
ULONG ulPrevious;
|
||||||
ULONG ulDir;
|
ULONG ulDir;
|
||||||
|
@ -50,10 +46,8 @@ typedef struct pps_entry_tag
|
||||||
} ppsEntryType;
|
} ppsEntryType;
|
||||||
|
|
||||||
/* Excel Record Struct*/
|
/* Excel Record Struct*/
|
||||||
typedef struct excelRecord
|
typedef struct excelRecord {
|
||||||
{
|
excelRecord() {
|
||||||
excelRecord()
|
|
||||||
{
|
|
||||||
usLen = 0;
|
usLen = 0;
|
||||||
usRichLen = 0;
|
usRichLen = 0;
|
||||||
ulWLen = 0;
|
ulWLen = 0;
|
||||||
|
@ -65,52 +59,49 @@ typedef struct excelRecord
|
||||||
bool bUni;
|
bool bUni;
|
||||||
} excelRecord;
|
} excelRecord;
|
||||||
|
|
||||||
typedef struct readDataParam
|
typedef struct readDataParam {
|
||||||
{
|
readDataParam() {
|
||||||
readDataParam()
|
ulStBlk = 0;
|
||||||
{
|
pFile = NULL;
|
||||||
ulStBlk = 0;
|
ulBBd = NULL;
|
||||||
pFile = NULL;
|
tBBdLen = 0;
|
||||||
ulBBd = NULL;
|
usBlkSize = 0;
|
||||||
tBBdLen = 0;
|
}
|
||||||
usBlkSize = 0;
|
ulong ulStBlk;
|
||||||
}
|
FILE *pFile;
|
||||||
ulong ulStBlk;
|
ulong *ulBBd;
|
||||||
FILE *pFile;
|
size_t tBBdLen;
|
||||||
ulong *ulBBd;
|
ushort usBlkSize;
|
||||||
size_t tBBdLen;
|
} rdPara;
|
||||||
ushort usBlkSize;
|
|
||||||
}rdPara;
|
|
||||||
|
|
||||||
class KBinaryParser :public QObject
|
class KBinaryParser : public QObject {
|
||||||
{
|
Q_OBJECT
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
KBinaryParser(QObject *parent=0);
|
KBinaryParser(QObject *parent = 0);
|
||||||
~KBinaryParser();
|
~KBinaryParser();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool RunParser(QString strFile,QString &content);
|
bool RunParser(QString strFile, QString &content);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool bGetPPS(FILE *pFile,
|
bool bGetPPS(FILE *pFile,
|
||||||
const ULONG *aulRootList, size_t tRootListLen, ppsInfoType *pPPS);
|
const ULONG *aulRootList, size_t tRootListLen, ppsInfoType *pPPS);
|
||||||
|
|
||||||
int readData(rdPara &readParam, uchar *aucBuffer, ulong ulOffset, size_t tToRead);
|
int readData(rdPara &readParam, uchar *aucBuffer, ulong ulOffset, size_t tToRead);
|
||||||
|
|
||||||
int InitDocOle(FILE *pFile,long lFilesize,QString &content);
|
int InitDocOle(FILE *pFile, long lFilesize, QString &content);
|
||||||
bool read8DocText(FILE *pFile, const ppsInfoType *pPPS,
|
bool read8DocText(FILE *pFile, const ppsInfoType *pPPS,
|
||||||
const ULONG *aulBBD, size_t tBBDLen,
|
const ULONG *aulBBD, size_t tBBDLen,
|
||||||
const ULONG *aulSBD, size_t tSBDLen,
|
const ULONG *aulSBD, size_t tSBDLen,
|
||||||
const UCHAR *aucHeader,QString &content);
|
const UCHAR *aucHeader, QString &content);
|
||||||
|
|
||||||
int readSSTRecord(readDataParam &rdParam, ppsInfoType, ulong &ulOff, ushort usPartLen,QString &content);
|
int readSSTRecord(readDataParam &rdParam, ppsInfoType, ulong &ulOff, ushort usPartLen, QString &content);
|
||||||
int read8BiffRecord(uchar uFlag, ulong ulOff, ulong &ulNext, readDataParam &rdParam, excelRecord &eR);
|
int read8BiffRecord(uchar uFlag, ulong ulOff, ulong &ulNext, readDataParam &rdParam, excelRecord &eR);
|
||||||
|
|
||||||
ULONG readPPtRecord(FILE* pFile, ppsInfoType* PPS_info, ULONG* aulBBD,
|
ULONG readPPtRecord(FILE* pFile, ppsInfoType* PPS_info, ULONG* aulBBD,
|
||||||
size_t tBBDLen, ULONG ulPos,QString &content);
|
size_t tBBDLen, ULONG ulPos, QString &content);
|
||||||
|
|
||||||
QString m_strFileName;
|
QString m_strFileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SEARCHHELPER_H
|
#endif // SEARCHHELPER_H
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
*/
|
*/
|
||||||
#include "setting-match.h"
|
#include "setting-match.h"
|
||||||
#include "file-utils.h"
|
#include "file-utils.h"
|
||||||
SettingsMatch::SettingsMatch(QObject *parent) : QObject(parent)
|
SettingsMatch::SettingsMatch(QObject *parent) : QObject(parent) {
|
||||||
{
|
|
||||||
xmlElement();
|
xmlElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +30,9 @@ SettingsMatch::SettingsMatch(QObject *parent) : QObject(parent)
|
||||||
* 获取的字符串
|
* 获取的字符串
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QStringList SettingsMatch::startMatchApp(const QString &source){
|
QStringList SettingsMatch::startMatchApp(const QString &source) {
|
||||||
m_sourceText=source;
|
m_sourceText = source;
|
||||||
QStringList settingList=matching();
|
QStringList settingList = matching();
|
||||||
return settingList;
|
return settingList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,42 +40,42 @@ QStringList SettingsMatch::startMatchApp(const QString &source){
|
||||||
* @brief SettingsMatch::xmlElement
|
* @brief SettingsMatch::xmlElement
|
||||||
* 将xml文件内容读到内存
|
* 将xml文件内容读到内存
|
||||||
*/
|
*/
|
||||||
void SettingsMatch::xmlElement(){
|
void SettingsMatch::xmlElement() {
|
||||||
QString ChineseIndex;
|
QString ChineseIndex;
|
||||||
QString EnglishIndex;
|
QString EnglishIndex;
|
||||||
QFile file(QString::fromLocal8Bit("/usr/share/ukui-control-center/shell/res/search.xml"));
|
QFile file(QString::fromLocal8Bit("/usr/share/ukui-control-center/shell/res/search.xml"));
|
||||||
if (!file.open(QIODevice::ReadOnly)){
|
if(!file.open(QIODevice::ReadOnly)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
doc.setContent(&file);
|
doc.setContent(&file);
|
||||||
QDomElement root=doc.documentElement();
|
QDomElement root = doc.documentElement();
|
||||||
QDomNode node = root.previousSibling();
|
QDomNode node = root.previousSibling();
|
||||||
node=root.firstChild();
|
node = root.firstChild();
|
||||||
|
|
||||||
while(!node.isNull()){
|
while(!node.isNull()) {
|
||||||
QDomElement element=node.toElement();
|
QDomElement element = node.toElement();
|
||||||
QString key=element.attribute("name");;
|
QString key = element.attribute("name");;
|
||||||
m_chine_searchResult=m_chine_searchList.value(key);
|
m_chine_searchResult = m_chine_searchList.value(key);
|
||||||
m_English_searchResult=m_English_searchList.value(key);
|
m_English_searchResult = m_English_searchList.value(key);
|
||||||
QDomNodeList list=element.childNodes();
|
QDomNodeList list = element.childNodes();
|
||||||
for(int i=0;i<list.count();++i){
|
for(int i = 0; i < list.count(); ++i) {
|
||||||
QDomNode n=list.at(i);
|
QDomNode n = list.at(i);
|
||||||
if(n.nodeName()==QString::fromLocal8Bit("ChinesePlugin")){
|
if(n.nodeName() == QString::fromLocal8Bit("ChinesePlugin")) {
|
||||||
ChineseIndex=n.toElement().text();
|
ChineseIndex = n.toElement().text();
|
||||||
}
|
}
|
||||||
if(n.nodeName()==QString::fromLocal8Bit("ChineseFunc")){
|
if(n.nodeName() == QString::fromLocal8Bit("ChineseFunc")) {
|
||||||
ChineseIndex+=QString::fromLocal8Bit("/")+n.toElement().text();
|
ChineseIndex += QString::fromLocal8Bit("/") + n.toElement().text();
|
||||||
m_chine_searchResult.append(ChineseIndex);
|
m_chine_searchResult.append(ChineseIndex);
|
||||||
}
|
}
|
||||||
if(n.nodeName()==QString::fromLocal8Bit("EnglishFunc")){
|
if(n.nodeName() == QString::fromLocal8Bit("EnglishFunc")) {
|
||||||
EnglishIndex=QString::fromLocal8Bit("/")+n.toElement().text();
|
EnglishIndex = QString::fromLocal8Bit("/") + n.toElement().text();
|
||||||
m_English_searchResult.append(EnglishIndex);
|
m_English_searchResult.append(EnglishIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_chine_searchList.insert(key,m_chine_searchResult);
|
m_chine_searchList.insert(key, m_chine_searchResult);
|
||||||
m_English_searchList.insert(key,m_English_searchResult);
|
m_English_searchList.insert(key, m_English_searchResult);
|
||||||
node=node.nextSibling();
|
node = node.nextSibling();
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
@ -86,42 +85,40 @@ void SettingsMatch::xmlElement(){
|
||||||
* 进行关键字匹配
|
* 进行关键字匹配
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QStringList SettingsMatch::matching(){
|
QStringList SettingsMatch::matching() {
|
||||||
QStringList returnresult;
|
QStringList returnresult;
|
||||||
QStringList regmatch;
|
QStringList regmatch;
|
||||||
QString key;
|
QString key;
|
||||||
QStringList pinyinlist;
|
QStringList pinyinlist;
|
||||||
QMap<QString, QStringList>::const_iterator i;
|
QMap<QString, QStringList>::const_iterator i;
|
||||||
QLocale ql;
|
QLocale ql;
|
||||||
if(ql.language()==QLocale::Chinese){
|
if(ql.language() == QLocale::Chinese) {
|
||||||
for(i=m_chine_searchList.constBegin();i!=m_chine_searchList.constEnd();++i){
|
for(i = m_chine_searchList.constBegin(); i != m_chine_searchList.constEnd(); ++i) {
|
||||||
regmatch=*i;
|
regmatch = *i;
|
||||||
key=i.key();
|
key = i.key();
|
||||||
for(int t=0; t<regmatch.size();t++)
|
for(int t = 0; t < regmatch.size(); t++) {
|
||||||
{
|
if(m_sourceText == "/")
|
||||||
if(m_sourceText=="/")
|
|
||||||
continue;
|
continue;
|
||||||
QString str =regmatch.at(t);
|
QString str = regmatch.at(t);
|
||||||
pinyinlist=FileUtils::findMultiToneWords(str);
|
pinyinlist = FileUtils::findMultiToneWords(str);
|
||||||
if(str.contains(m_sourceText))
|
if(str.contains(m_sourceText)) {
|
||||||
{
|
str = key + "/" + str;
|
||||||
str=key+"/"+str;
|
|
||||||
returnresult.append(str);//中文名
|
returnresult.append(str);//中文名
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(int i = 0;i<pinyinlist.size()/2;i++){
|
for(int i = 0; i < pinyinlist.size() / 2; i++) {
|
||||||
str =regmatch.at(t);
|
str = regmatch.at(t);
|
||||||
QString shouzimu=pinyinlist.at(2*i+1); // 中文转首字母
|
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
|
||||||
if(shouzimu.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(shouzimu.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
str=key+"/"+str;
|
str = key + "/" + str;
|
||||||
returnresult.append(str);
|
returnresult.append(str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(m_sourceText.size()<2)
|
if(m_sourceText.size() < 2)
|
||||||
break;
|
break;
|
||||||
QString pinyin=pinyinlist.at(2*i);// 中文转拼音
|
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
|
||||||
if(pinyin.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(pinyin.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
str=key+"/"+str;
|
str = key + "/" + str;
|
||||||
returnresult.append(str);
|
returnresult.append(str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -130,17 +127,16 @@ QStringList SettingsMatch::matching(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ql.language()==QLocale::English){
|
if(ql.language() == QLocale::English) {
|
||||||
for(i=m_English_searchList.constBegin();i!=m_English_searchList.constEnd();++i){
|
for(i = m_English_searchList.constBegin(); i != m_English_searchList.constEnd(); ++i) {
|
||||||
regmatch=*i;
|
regmatch = *i;
|
||||||
key=i.key();
|
key = i.key();
|
||||||
for(int t=0; t<regmatch.size();t++)
|
for(int t = 0; t < regmatch.size(); t++) {
|
||||||
{
|
if(m_sourceText == "/")
|
||||||
if(m_sourceText=="/")
|
|
||||||
continue;
|
continue;
|
||||||
QString str =regmatch.at(t);
|
QString str = regmatch.at(t);
|
||||||
if(str.contains(m_sourceText,Qt::CaseInsensitive)){
|
if(str.contains(m_sourceText, Qt::CaseInsensitive)) {
|
||||||
str=key+"/"+str;
|
str = key + "/" + str;
|
||||||
returnresult.append(str);
|
returnresult.append(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
class SettingsMatch : public QObject
|
class SettingsMatch : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SettingsMatch(QObject *parent = nullptr);
|
explicit SettingsMatch(QObject *parent = nullptr);
|
||||||
|
@ -42,8 +41,8 @@ private:
|
||||||
QStringList matching();
|
QStringList matching();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString,QStringList> m_chine_searchList;
|
QMap<QString, QStringList> m_chine_searchList;
|
||||||
QMap<QString,QStringList> m_English_searchList;
|
QMap<QString, QStringList> m_English_searchList;
|
||||||
QStringList m_chine_searchResult;
|
QStringList m_chine_searchResult;
|
||||||
QStringList m_English_searchResult;
|
QStringList m_English_searchResult;
|
||||||
QString m_sourceText;
|
QString m_sourceText;
|
||||||
|
|
|
@ -24,26 +24,24 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include "config-file.h"
|
#include "config-file.h"
|
||||||
|
|
||||||
ContentWidget::ContentWidget(QWidget * parent):QStackedWidget(parent)
|
ContentWidget::ContentWidget(QWidget * parent): QStackedWidget(parent) {
|
||||||
{
|
|
||||||
initUI();
|
initUI();
|
||||||
initListView();
|
initListView();
|
||||||
//快速入口应用列表
|
//快速入口应用列表
|
||||||
// m_quicklyOpenList<<"/usr/share/applications/peony.desktop"<<"/usr/share/applications/ukui-control-center.desktop"<<"/usr/share/applications/ksc-defender.desktop";
|
// m_quicklyOpenList<<"/usr/share/applications/peony.desktop"<<"/usr/share/applications/ukui-control-center.desktop"<<"/usr/share/applications/ksc-defender.desktop";
|
||||||
m_quicklyOpenList << "/usr/share/applications/ksc-defender.desktop"
|
m_quicklyOpenList << "/usr/share/applications/ksc-defender.desktop"
|
||||||
<< "/usr/share/applications/ukui-notebook.desktop"
|
<< "/usr/share/applications/ukui-notebook.desktop"
|
||||||
<< "/usr/share/applications/eom.desktop"
|
<< "/usr/share/applications/eom.desktop"
|
||||||
<< "/usr/share/applications/pluma.desktop"
|
<< "/usr/share/applications/pluma.desktop"
|
||||||
<< "/usr/share/applications/claws-mail.desktop" ;
|
<< "/usr/share/applications/claws-mail.desktop" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentWidget::~ContentWidget()
|
ContentWidget::~ContentWidget() {
|
||||||
{
|
if(m_homePage) {
|
||||||
if (m_homePage) {
|
|
||||||
delete m_homePage;
|
delete m_homePage;
|
||||||
m_homePage = nullptr;
|
m_homePage = nullptr;
|
||||||
}
|
}
|
||||||
if (m_resultPage) {
|
if(m_resultPage) {
|
||||||
delete m_resultPage;
|
delete m_resultPage;
|
||||||
m_resultPage = nullptr;
|
m_resultPage = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +54,7 @@ void ContentWidget::initUI() {
|
||||||
m_homePage = new QWidget(this);
|
m_homePage = new QWidget(this);
|
||||||
m_homePageLyt = new QVBoxLayout(m_homePage);
|
m_homePageLyt = new QVBoxLayout(m_homePage);
|
||||||
m_homePageLyt->setSpacing(0);
|
m_homePageLyt->setSpacing(0);
|
||||||
m_homePageLyt->setContentsMargins(0,0,0,0);
|
m_homePageLyt->setContentsMargins(0, 0, 0, 0);
|
||||||
m_homePage->setLayout(m_homePageLyt);
|
m_homePage->setLayout(m_homePageLyt);
|
||||||
|
|
||||||
m_resultPage = new QWidget(this);
|
m_resultPage = new QWidget(this);
|
||||||
|
@ -103,8 +101,7 @@ void ContentWidget::initUI() {
|
||||||
/**
|
/**
|
||||||
* @brief ContentWidget::initListView 初始化所有搜索结果列表
|
* @brief ContentWidget::initListView 初始化所有搜索结果列表
|
||||||
*/
|
*/
|
||||||
void ContentWidget::initListView()
|
void ContentWidget::initListView() {
|
||||||
{
|
|
||||||
m_fileListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Files);
|
m_fileListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Files);
|
||||||
m_dirListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Dirs);
|
m_dirListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Dirs);
|
||||||
m_contentListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Contents);
|
m_contentListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Contents);
|
||||||
|
@ -232,8 +229,7 @@ void ContentWidget::initListView()
|
||||||
/**
|
/**
|
||||||
* @brief ContentWidget::hideListView 隐藏所有列表
|
* @brief ContentWidget::hideListView 隐藏所有列表
|
||||||
*/
|
*/
|
||||||
void ContentWidget::hideListView()
|
void ContentWidget::hideListView() {
|
||||||
{
|
|
||||||
m_bestTitleLabel->hide();
|
m_bestTitleLabel->hide();
|
||||||
m_bestListView->hide();
|
m_bestListView->hide();
|
||||||
m_appTitleLabel->hide();
|
m_appTitleLabel->hide();
|
||||||
|
@ -262,16 +258,16 @@ void ContentWidget::hideListView()
|
||||||
void ContentWidget::setupConnect(SearchListView * listview) {
|
void ContentWidget::setupConnect(SearchListView * listview) {
|
||||||
connect(this, &ContentWidget::currentItemChanged, listview, [ = ]() {
|
connect(this, &ContentWidget::currentItemChanged, listview, [ = ]() {
|
||||||
|
|
||||||
if (! listview->is_current_list) {
|
if(! listview->is_current_list) {
|
||||||
listview->blockSignals(true);
|
listview->blockSignals(true);
|
||||||
listview->clearSelection();
|
listview->clearSelection();
|
||||||
listview->blockSignals(false);
|
listview->blockSignals(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
connect(listview,&SearchListView::currentSelectPos,[=](QPoint pos){
|
connect(listview, &SearchListView::currentSelectPos, [ = ](QPoint pos) {
|
||||||
m_resultListArea->ensureVisible(pos.x(),pos.y());
|
m_resultListArea->ensureVisible(pos.x(), pos.y());
|
||||||
});
|
});
|
||||||
connect(listview,&SearchListView::mousePressed,this,&ContentWidget::mousePressed);
|
connect(listview, &SearchListView::mousePressed, this, &ContentWidget::mousePressed);
|
||||||
connect(listview, &SearchListView::currentRowChanged, this, &ContentWidget::onListViewRowChanged);
|
connect(listview, &SearchListView::currentRowChanged, this, &ContentWidget::onListViewRowChanged);
|
||||||
connect(listview, &SearchListView::onRowDoubleClicked, this, &ContentWidget::onListViewRowDoubleClicked);
|
connect(listview, &SearchListView::onRowDoubleClicked, this, &ContentWidget::onListViewRowDoubleClicked);
|
||||||
}
|
}
|
||||||
|
@ -279,57 +275,55 @@ void ContentWidget::setupConnect(SearchListView * listview) {
|
||||||
/**
|
/**
|
||||||
* @brief ContentWidget::resetHeight 重新计算列表高度
|
* @brief ContentWidget::resetHeight 重新计算列表高度
|
||||||
*/
|
*/
|
||||||
void ContentWidget::resetListHeight()
|
void ContentWidget::resetListHeight() {
|
||||||
{
|
|
||||||
int height = 0;
|
int height = 0;
|
||||||
if (! m_bestListView->isHidden) {
|
if(! m_bestListView->isHidden) {
|
||||||
height += m_bestTitleLabel->height();
|
height += m_bestTitleLabel->height();
|
||||||
height += m_bestListView->height();
|
height += m_bestListView->height();
|
||||||
}
|
}
|
||||||
if (! m_appListView->isHidden) {
|
if(! m_appListView->isHidden) {
|
||||||
height += m_appTitleLabel->height();
|
height += m_appTitleLabel->height();
|
||||||
height += m_appListView->height();
|
height += m_appListView->height();
|
||||||
if (m_appShowMoreLabel->isVisible()) {
|
if(m_appShowMoreLabel->isVisible()) {
|
||||||
height += m_appShowMoreLabel->height();
|
height += m_appShowMoreLabel->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_settingListView->isHidden) {
|
if(! m_settingListView->isHidden) {
|
||||||
height += m_settingTitleLabel->height();
|
height += m_settingTitleLabel->height();
|
||||||
height += m_settingListView->height();
|
height += m_settingListView->height();
|
||||||
if (m_settingShowMoreLabel->isVisible()) {
|
if(m_settingShowMoreLabel->isVisible()) {
|
||||||
height += m_settingShowMoreLabel->height();
|
height += m_settingShowMoreLabel->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_fileListView->isHidden) {
|
if(! m_fileListView->isHidden) {
|
||||||
height += m_fileTitleLabel->height();
|
height += m_fileTitleLabel->height();
|
||||||
height += m_fileListView->height();
|
height += m_fileListView->height();
|
||||||
if (m_fileShowMoreLabel->isVisible()) {
|
if(m_fileShowMoreLabel->isVisible()) {
|
||||||
height += m_fileShowMoreLabel->height();
|
height += m_fileShowMoreLabel->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_dirListView->isHidden) {
|
if(! m_dirListView->isHidden) {
|
||||||
height += m_dirTitleLabel->height();
|
height += m_dirTitleLabel->height();
|
||||||
height += m_dirListView->height();
|
height += m_dirListView->height();
|
||||||
if (m_dirShowMoreLabel->isVisible()) {
|
if(m_dirShowMoreLabel->isVisible()) {
|
||||||
height += m_dirShowMoreLabel->height();
|
height += m_dirShowMoreLabel->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_contentListView->isHidden) {
|
if(! m_contentListView->isHidden) {
|
||||||
height += m_contentTitleLabel->height();
|
height += m_contentTitleLabel->height();
|
||||||
height += m_contentListView->height();
|
height += m_contentListView->height();
|
||||||
if (m_contentShowMoreLabel->isVisible()) {
|
if(m_contentShowMoreLabel->isVisible()) {
|
||||||
height += m_contentShowMoreLabel->height();
|
height += m_contentShowMoreLabel->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! m_webListView->isHidden) {
|
if(! m_webListView->isHidden) {
|
||||||
height += m_webTitleLabel->height();
|
height += m_webTitleLabel->height();
|
||||||
height += m_webListView->height();
|
height += m_webListView->height();
|
||||||
}
|
}
|
||||||
m_resultList->setFixedHeight(height);
|
m_resultList->setFixedHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWidget::appendBestItem(const int &type, const QString &path)
|
void ContentWidget::appendBestItem(const int &type, const QString &path) {
|
||||||
{
|
|
||||||
m_bestList.append(QPair<int, QString>(type, path));
|
m_bestList.append(QPair<int, QString>(type, path));
|
||||||
m_bestListView->appendBestItem(QPair<int, QString>(type, path));
|
m_bestListView->appendBestItem(QPair<int, QString>(type, path));
|
||||||
appendSearchItem(SearchItem::SearchType::Best, path);
|
appendSearchItem(SearchItem::SearchType::Best, path);
|
||||||
|
@ -351,27 +345,27 @@ void ContentWidget::initHomePage() {
|
||||||
lists.append(recentlyList);
|
lists.append(recentlyList);
|
||||||
lists.append(commonlyList);
|
lists.append(commonlyList);
|
||||||
|
|
||||||
for (int i = 0; i < lists.count(); i++) {
|
for(int i = 0; i < lists.count(); i++) {
|
||||||
if (lists.at(i).isEmpty())
|
if(lists.at(i).isEmpty())
|
||||||
continue;
|
continue;
|
||||||
QWidget * listWidget = new QWidget(m_homePage);
|
QWidget * listWidget = new QWidget(m_homePage);
|
||||||
QVBoxLayout * itemWidgetLyt = new QVBoxLayout(listWidget);
|
QVBoxLayout * itemWidgetLyt = new QVBoxLayout(listWidget);
|
||||||
QLabel * titleLabel = new QLabel(listWidget);
|
QLabel * titleLabel = new QLabel(listWidget);
|
||||||
QWidget * itemWidget = new QWidget(listWidget);
|
QWidget * itemWidget = new QWidget(listWidget);
|
||||||
if (i == 1) {
|
if(i == 1) {
|
||||||
if (lists.at(i).length() <= 2) itemWidget->setFixedHeight(48);
|
if(lists.at(i).length() <= 2) itemWidget->setFixedHeight(48);
|
||||||
else itemWidget->setFixedHeight(104);
|
else itemWidget->setFixedHeight(104);
|
||||||
titleLabel->setText(tr("Recently Opened"));
|
titleLabel->setText(tr("Recently Opened"));
|
||||||
QGridLayout * layout = new QGridLayout(itemWidget);
|
QGridLayout * layout = new QGridLayout(itemWidget);
|
||||||
layout->setSpacing(8);
|
layout->setSpacing(8);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
itemWidget->setLayout(layout);
|
itemWidget->setLayout(layout);
|
||||||
for (int j = 0; j < lists.at(i).count(); j++) {
|
for(int j = 0; j < lists.at(i).count(); j++) {
|
||||||
HomePageItem * item = new HomePageItem(itemWidget, i, lists.at(i).at(j));
|
HomePageItem * item = new HomePageItem(itemWidget, i, lists.at(i).at(j));
|
||||||
item->setFixedSize(300, 48);
|
item->setFixedSize(300, 48);
|
||||||
layout->addWidget(item, j / 2, j % 2);
|
layout->addWidget(item, j / 2, j % 2);
|
||||||
}
|
}
|
||||||
if (lists.at(i).length() == 1) {
|
if(lists.at(i).length() == 1) {
|
||||||
QWidget * emptyItem = new QWidget(itemWidget);
|
QWidget * emptyItem = new QWidget(itemWidget);
|
||||||
emptyItem->setFixedSize(300, 48); //占位用widget,只有一项时在右方补全
|
emptyItem->setFixedSize(300, 48); //占位用widget,只有一项时在右方补全
|
||||||
layout->addWidget(emptyItem, 1, 2);
|
layout->addWidget(emptyItem, 1, 2);
|
||||||
|
@ -383,8 +377,8 @@ void ContentWidget::initHomePage() {
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
itemWidget->setLayout(layout);
|
itemWidget->setLayout(layout);
|
||||||
int shownItem = lists.at(i).length();
|
int shownItem = lists.at(i).length();
|
||||||
Q_FOREACH(QString path, lists.at(i)){
|
Q_FOREACH(QString path, lists.at(i)) {
|
||||||
if (i == 0 && QString::compare(FileUtils::getAppName(path),"Unknown App") == 0) {
|
if(i == 0 && QString::compare(FileUtils::getAppName(path), "Unknown App") == 0) {
|
||||||
shownItem --;
|
shownItem --;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -392,12 +386,12 @@ void ContentWidget::initHomePage() {
|
||||||
item->setFixedSize(116, 116);
|
item->setFixedSize(116, 116);
|
||||||
layout->addWidget(item);
|
layout->addWidget(item);
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 5 - shownItem; j++) {
|
for(int j = 0; j < 5 - shownItem; j++) {
|
||||||
QWidget * emptyItem = new QWidget(itemWidget);
|
QWidget * emptyItem = new QWidget(itemWidget);
|
||||||
emptyItem->setFixedSize(116, 116); //占位用widget,少于5项会补全后方占位
|
emptyItem->setFixedSize(116, 116); //占位用widget,少于5项会补全后方占位
|
||||||
layout->addWidget(emptyItem);
|
layout->addWidget(emptyItem);
|
||||||
}
|
}
|
||||||
if (i == 0 && shownItem) titleLabel->setText(tr("Open Quickly"));
|
if(i == 0 && shownItem) titleLabel->setText(tr("Open Quickly"));
|
||||||
else titleLabel->setText(tr("Commonly Used"));
|
else titleLabel->setText(tr("Commonly Used"));
|
||||||
}
|
}
|
||||||
itemWidgetLyt->setSpacing(6);
|
itemWidgetLyt->setSpacing(6);
|
||||||
|
@ -428,51 +422,50 @@ int ContentWidget::currentPage() {
|
||||||
/**
|
/**
|
||||||
* @brief ContentWidget::resetSearchList 在构建新的搜索结果列表前,先重置所有控件
|
* @brief ContentWidget::resetSearchList 在构建新的搜索结果列表前,先重置所有控件
|
||||||
*/
|
*/
|
||||||
void ContentWidget::resetSearchList()
|
void ContentWidget::resetSearchList() {
|
||||||
{
|
|
||||||
// this->hideListView();
|
// this->hideListView();
|
||||||
if (m_fileListView) {
|
if(m_fileListView) {
|
||||||
m_fileListView->hide();
|
m_fileListView->hide();
|
||||||
m_fileTitleLabel->hide();
|
m_fileTitleLabel->hide();
|
||||||
m_fileShowMoreLabel->hide();
|
m_fileShowMoreLabel->hide();
|
||||||
m_fileListView->isHidden = true;
|
m_fileListView->isHidden = true;
|
||||||
m_fileListView->clear();
|
m_fileListView->clear();
|
||||||
}
|
}
|
||||||
if (m_dirListView) {
|
if(m_dirListView) {
|
||||||
m_dirListView->hide();
|
m_dirListView->hide();
|
||||||
m_dirTitleLabel->hide();
|
m_dirTitleLabel->hide();
|
||||||
m_dirShowMoreLabel->hide();
|
m_dirShowMoreLabel->hide();
|
||||||
m_dirListView->isHidden = true;
|
m_dirListView->isHidden = true;
|
||||||
m_dirListView->clear();
|
m_dirListView->clear();
|
||||||
}
|
}
|
||||||
if (m_contentListView) {
|
if(m_contentListView) {
|
||||||
m_contentListView->hide();
|
m_contentListView->hide();
|
||||||
m_contentTitleLabel->hide();
|
m_contentTitleLabel->hide();
|
||||||
m_contentShowMoreLabel->hide();
|
m_contentShowMoreLabel->hide();
|
||||||
m_contentListView->isHidden = true;
|
m_contentListView->isHidden = true;
|
||||||
m_contentListView->clear();
|
m_contentListView->clear();
|
||||||
}
|
}
|
||||||
if (m_appListView) {
|
if(m_appListView) {
|
||||||
m_appListView->hide();
|
m_appListView->hide();
|
||||||
m_appTitleLabel->hide();
|
m_appTitleLabel->hide();
|
||||||
m_appShowMoreLabel->hide();
|
m_appShowMoreLabel->hide();
|
||||||
m_appListView->isHidden = true;
|
m_appListView->isHidden = true;
|
||||||
m_appListView->clear();
|
m_appListView->clear();
|
||||||
}
|
}
|
||||||
if (m_settingListView) {
|
if(m_settingListView) {
|
||||||
m_settingListView->hide();
|
m_settingListView->hide();
|
||||||
m_settingTitleLabel->hide();
|
m_settingTitleLabel->hide();
|
||||||
m_settingShowMoreLabel->hide();
|
m_settingShowMoreLabel->hide();
|
||||||
m_settingListView->isHidden = true;
|
m_settingListView->isHidden = true;
|
||||||
m_settingListView->clear();
|
m_settingListView->clear();
|
||||||
}
|
}
|
||||||
if (m_bestListView) {
|
if(m_bestListView) {
|
||||||
m_bestListView->hide();
|
m_bestListView->hide();
|
||||||
m_bestTitleLabel->hide();
|
m_bestTitleLabel->hide();
|
||||||
m_bestListView->isHidden = true;
|
m_bestListView->isHidden = true;
|
||||||
m_bestListView->clear();
|
m_bestListView->clear();
|
||||||
}
|
}
|
||||||
if (m_webListView) {
|
if(m_webListView) {
|
||||||
m_webListView->clear();
|
m_webListView->clear();
|
||||||
m_webListView->appendItem(m_keyword);
|
m_webListView->appendItem(m_keyword);
|
||||||
m_webTitleLabel->show();
|
m_webTitleLabel->show();
|
||||||
|
@ -492,21 +485,21 @@ void ContentWidget::resetSearchList()
|
||||||
m_contentShowMoreLabel->resetLabel();
|
m_contentShowMoreLabel->resetLabel();
|
||||||
|
|
||||||
m_bestList.clear();
|
m_bestList.clear();
|
||||||
if (! m_appList.isEmpty())
|
if(! m_appList.isEmpty())
|
||||||
m_appList.clear();
|
m_appList.clear();
|
||||||
if (! m_settingList.isEmpty())
|
if(! m_settingList.isEmpty())
|
||||||
m_settingList.clear();
|
m_settingList.clear();
|
||||||
if (! m_dirList.isEmpty())
|
if(! m_dirList.isEmpty())
|
||||||
m_dirList.clear();
|
m_dirList.clear();
|
||||||
if (! m_fileList.isEmpty())
|
if(! m_fileList.isEmpty())
|
||||||
m_fileList.clear();
|
m_fileList.clear();
|
||||||
if (! m_contentList.isEmpty())
|
if(! m_contentList.isEmpty())
|
||||||
m_contentList.clear();
|
m_contentList.clear();
|
||||||
if (! m_appPathList.isEmpty())
|
if(! m_appPathList.isEmpty())
|
||||||
m_appPathList.clear();
|
m_appPathList.clear();
|
||||||
if (! m_appIconList.isEmpty())
|
if(! m_appIconList.isEmpty())
|
||||||
m_appIconList.clear();
|
m_appIconList.clear();
|
||||||
if (!m_appDescList.isEmpty())
|
if(!m_appDescList.isEmpty())
|
||||||
m_appDescList.clear();
|
m_appDescList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,17 +507,16 @@ void ContentWidget::resetSearchList()
|
||||||
* @brief ContentWidget::setSettingList 插入设置项搜索结果列表
|
* @brief ContentWidget::setSettingList 插入设置项搜索结果列表
|
||||||
* @param settingList
|
* @param settingList
|
||||||
*/
|
*/
|
||||||
void ContentWidget::setSettingList(const QStringList & settingList)
|
void ContentWidget::setSettingList(const QStringList & settingList) {
|
||||||
{
|
if(settingList.isEmpty())
|
||||||
if (settingList.isEmpty())
|
|
||||||
return;
|
return;
|
||||||
m_settingList = settingList;
|
m_settingList = settingList;
|
||||||
qDebug()<<"Append a best item into list: "<<settingList.at(0);
|
qDebug() << "Append a best item into list: " << settingList.at(0);
|
||||||
this->appendBestItem(SearchItem::SearchType::Settings, settingList.at(0));
|
this->appendBestItem(SearchItem::SearchType::Settings, settingList.at(0));
|
||||||
m_settingListView->show();
|
m_settingListView->show();
|
||||||
m_settingTitleLabel->show();
|
m_settingTitleLabel->show();
|
||||||
m_settingListView->isHidden = false;
|
m_settingListView->isHidden = false;
|
||||||
if (m_settingList.length() <= 5) {
|
if(m_settingList.length() <= 5) {
|
||||||
m_settingListView->setList(m_settingList);
|
m_settingListView->setList(m_settingList);
|
||||||
} else {
|
} else {
|
||||||
m_settingShowMoreLabel->show();
|
m_settingShowMoreLabel->show();
|
||||||
|
@ -538,16 +530,16 @@ void ContentWidget::setSettingList(const QStringList & settingList)
|
||||||
* @param appList QVector<namelist,pathlist,iconlist>
|
* @param appList QVector<namelist,pathlist,iconlist>
|
||||||
*/
|
*/
|
||||||
void ContentWidget::setAppList(const QVector<QStringList>& appList) {
|
void ContentWidget::setAppList(const QVector<QStringList>& appList) {
|
||||||
if (appList.at(0).isEmpty())
|
if(appList.at(0).isEmpty())
|
||||||
return;
|
return;
|
||||||
m_appList = appList.at(0);
|
m_appList = appList.at(0);
|
||||||
m_appPathList = appList.at(1);
|
m_appPathList = appList.at(1);
|
||||||
m_appIconList = appList.at(2);
|
m_appIconList = appList.at(2);
|
||||||
m_appDescList = appList.at(3);
|
m_appDescList = appList.at(3);
|
||||||
m_appListView->setAppList(m_appPathList, m_appIconList);
|
m_appListView->setAppList(m_appPathList, m_appIconList);
|
||||||
qDebug()<<"Append a best item into list: "<<appList.at(0).at(0);
|
qDebug() << "Append a best item into list: " << appList.at(0).at(0);
|
||||||
SearchItemModel * model = qobject_cast<SearchItemModel *>(m_bestListView->model());
|
SearchItemModel * model = qobject_cast<SearchItemModel *>(m_bestListView->model());
|
||||||
if (appList.at(1).at(0).isEmpty() || appList.at(1).at(0) == "") {
|
if(appList.at(1).at(0).isEmpty() || appList.at(1).at(0) == "") {
|
||||||
model->setBestAppIcon(appList.at(2).at(0), false);
|
model->setBestAppIcon(appList.at(2).at(0), false);
|
||||||
} else {
|
} else {
|
||||||
model->setBestAppIcon(appList.at(2).at(0), true);
|
model->setBestAppIcon(appList.at(2).at(0), true);
|
||||||
|
@ -556,7 +548,7 @@ void ContentWidget::setAppList(const QVector<QStringList>& appList) {
|
||||||
m_appListView->show();
|
m_appListView->show();
|
||||||
m_appTitleLabel->show();
|
m_appTitleLabel->show();
|
||||||
m_appListView->isHidden = false;
|
m_appListView->isHidden = false;
|
||||||
if (m_appList.length() <= 5) {
|
if(m_appList.length() <= 5) {
|
||||||
m_appListView->setList(m_appList);
|
m_appListView->setList(m_appList);
|
||||||
} else {
|
} else {
|
||||||
m_appShowMoreLabel->show();
|
m_appShowMoreLabel->show();
|
||||||
|
@ -572,86 +564,86 @@ void ContentWidget::setAppList(const QVector<QStringList>& appList) {
|
||||||
* @param contents 文件内容
|
* @param contents 文件内容
|
||||||
*/
|
*/
|
||||||
void ContentWidget::appendSearchItem(const int& type, const QString& path, QStringList contents) {
|
void ContentWidget::appendSearchItem(const int& type, const QString& path, QStringList contents) {
|
||||||
switch (type) {
|
switch(type) {
|
||||||
case SearchItem::SearchType::Best: {
|
case SearchItem::SearchType::Best: {
|
||||||
if (m_bestListView->isHidden) {
|
if(m_bestListView->isHidden) {
|
||||||
m_bestListView->show();
|
m_bestListView->show();
|
||||||
m_bestTitleLabel->show();
|
m_bestTitleLabel->show();
|
||||||
m_bestListView->isHidden = false;
|
m_bestListView->isHidden = false;
|
||||||
}
|
|
||||||
m_bestListView->appendItem(path);
|
|
||||||
if (m_detailView->isEmpty()) {
|
|
||||||
m_bestListView->setCurrentIndex(m_bestListView->model()->index(0, 0, QModelIndex()));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case SearchItem::SearchType::Files: {
|
m_bestListView->appendItem(path);
|
||||||
if (m_fileListView->isHidden) {
|
if(m_detailView->isEmpty()) {
|
||||||
m_fileListView->show();
|
m_bestListView->setCurrentIndex(m_bestListView->model()->index(0, 0, QModelIndex()));
|
||||||
m_fileTitleLabel->show();
|
|
||||||
m_fileListView->isHidden = false;
|
|
||||||
this->appendBestItem(SearchItem::SearchType::Files, path);
|
|
||||||
}
|
|
||||||
if (m_fileListView->getLength() < 5) { //当已搜索结果列表少于5项,直接将搜索结果添加到列表中
|
|
||||||
m_fileListView->appendItem(path);
|
|
||||||
} else if (m_fileListView->getLength() == 5) { //当已搜索结果等于5项,新增的被折叠,显示“展开”按钮
|
|
||||||
m_fileShowMoreLabel->show();
|
|
||||||
} else { //当搜索列表显示的大于5项,说明列表被展开,可以继续把新增项添加到列表中
|
|
||||||
m_fileListView->appendItem(path);
|
|
||||||
}
|
|
||||||
m_fileList.append(path);
|
|
||||||
break;;
|
|
||||||
}
|
}
|
||||||
case SearchItem::SearchType::Dirs: {
|
break;
|
||||||
if (m_dirListView->isHidden) {
|
}
|
||||||
m_dirListView->show();
|
case SearchItem::SearchType::Files: {
|
||||||
m_dirTitleLabel->show();
|
if(m_fileListView->isHidden) {
|
||||||
m_dirListView->isHidden = false;
|
m_fileListView->show();
|
||||||
this->appendBestItem(SearchItem::SearchType::Dirs, path);
|
m_fileTitleLabel->show();
|
||||||
}
|
m_fileListView->isHidden = false;
|
||||||
if (m_dirListView->getLength() < 5) {
|
this->appendBestItem(SearchItem::SearchType::Files, path);
|
||||||
m_dirListView->appendItem(path);
|
|
||||||
} else if (m_dirListView->getLength() == 5) {
|
|
||||||
m_dirShowMoreLabel->show();
|
|
||||||
} else {
|
|
||||||
m_dirListView->appendItem(path);
|
|
||||||
}
|
|
||||||
m_dirList.append(path);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case SearchItem::SearchType::Contents: {
|
if(m_fileListView->getLength() < 5) { //当已搜索结果列表少于5项,直接将搜索结果添加到列表中
|
||||||
if (m_contentListView->isHidden) {
|
m_fileListView->appendItem(path);
|
||||||
m_contentListView->show();
|
} else if(m_fileListView->getLength() == 5) { //当已搜索结果等于5项,新增的被折叠,显示“展开”按钮
|
||||||
m_contentTitleLabel->show();
|
m_fileShowMoreLabel->show();
|
||||||
m_contentListView->isHidden = false;
|
} else { //当搜索列表显示的大于5项,说明列表被展开,可以继续把新增项添加到列表中
|
||||||
for (int i = 0; i < contents.length(); i ++) {
|
m_fileListView->appendItem(path);
|
||||||
m_bestContent.append(contents.at(i));
|
}
|
||||||
if (i != contents.length() - 1) {
|
m_fileList.append(path);
|
||||||
m_bestContent.append("\n");
|
break;;
|
||||||
}
|
}
|
||||||
}
|
case SearchItem::SearchType::Dirs: {
|
||||||
this->appendBestItem(SearchItem::SearchType::Contents, path);
|
if(m_dirListView->isHidden) {
|
||||||
}
|
m_dirListView->show();
|
||||||
if (m_contentListView->getLength() < 5) {
|
m_dirTitleLabel->show();
|
||||||
m_contentListView->appendItem(path);
|
m_dirListView->isHidden = false;
|
||||||
} else if (m_contentListView->getLength() == 5) {
|
this->appendBestItem(SearchItem::SearchType::Dirs, path);
|
||||||
m_contentShowMoreLabel->show();
|
}
|
||||||
} else {
|
if(m_dirListView->getLength() < 5) {
|
||||||
m_contentListView->appendItem(path);
|
m_dirListView->appendItem(path);
|
||||||
}
|
} else if(m_dirListView->getLength() == 5) {
|
||||||
m_contentList.append(path);
|
m_dirShowMoreLabel->show();
|
||||||
QString temp;
|
} else {
|
||||||
for (int i = 0; i < contents.length(); i ++) {
|
m_dirListView->appendItem(path);
|
||||||
temp.append(contents.at(i));
|
}
|
||||||
if (i != contents.length() - 1) {
|
m_dirList.append(path);
|
||||||
temp.append("\n");
|
break;
|
||||||
|
}
|
||||||
|
case SearchItem::SearchType::Contents: {
|
||||||
|
if(m_contentListView->isHidden) {
|
||||||
|
m_contentListView->show();
|
||||||
|
m_contentTitleLabel->show();
|
||||||
|
m_contentListView->isHidden = false;
|
||||||
|
for(int i = 0; i < contents.length(); i ++) {
|
||||||
|
m_bestContent.append(contents.at(i));
|
||||||
|
if(i != contents.length() - 1) {
|
||||||
|
m_bestContent.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_contentDetailList.append(temp);
|
this->appendBestItem(SearchItem::SearchType::Contents, path);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
if(m_contentListView->getLength() < 5) {
|
||||||
break;
|
m_contentListView->appendItem(path);
|
||||||
|
} else if(m_contentListView->getLength() == 5) {
|
||||||
|
m_contentShowMoreLabel->show();
|
||||||
|
} else {
|
||||||
|
m_contentListView->appendItem(path);
|
||||||
|
}
|
||||||
|
m_contentList.append(path);
|
||||||
|
QString temp;
|
||||||
|
for(int i = 0; i < contents.length(); i ++) {
|
||||||
|
temp.append(contents.at(i));
|
||||||
|
if(i != contents.length() - 1) {
|
||||||
|
temp.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_contentDetailList.append(temp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
this->resetListHeight();
|
this->resetListHeight();
|
||||||
return;
|
return;
|
||||||
|
@ -663,23 +655,23 @@ void ContentWidget::appendSearchItem(const int& type, const QString& path, QStri
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QString ContentWidget::getTitleName(const int& type) {
|
QString ContentWidget::getTitleName(const int& type) {
|
||||||
switch (type) {
|
switch(type) {
|
||||||
case SearchItem::SearchType::Apps :
|
case SearchItem::SearchType::Apps :
|
||||||
return tr("Apps");
|
return tr("Apps");
|
||||||
case SearchItem::SearchType::Settings :
|
case SearchItem::SearchType::Settings :
|
||||||
return tr("Settings");
|
return tr("Settings");
|
||||||
case SearchItem::SearchType::Files :
|
case SearchItem::SearchType::Files :
|
||||||
return tr("Files");
|
return tr("Files");
|
||||||
case SearchItem::SearchType::Dirs :
|
case SearchItem::SearchType::Dirs :
|
||||||
return tr("Dirs");
|
return tr("Dirs");
|
||||||
case SearchItem::SearchType::Contents :
|
case SearchItem::SearchType::Contents :
|
||||||
return tr("File Contents");
|
return tr("File Contents");
|
||||||
case SearchItem::SearchType::Best :
|
case SearchItem::SearchType::Best :
|
||||||
return tr("Best Matches");
|
return tr("Best Matches");
|
||||||
case SearchItem::SearchType::Web :
|
case SearchItem::SearchType::Web :
|
||||||
return tr("Web Pages");
|
return tr("Web Pages");
|
||||||
default :
|
default :
|
||||||
return tr("Unknown");
|
return tr("Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,11 +680,10 @@ QString ContentWidget::getTitleName(const int& type) {
|
||||||
* @param layout 需要清空的布局
|
* @param layout 需要清空的布局
|
||||||
*/
|
*/
|
||||||
void ContentWidget::clearLayout(QLayout * layout) {
|
void ContentWidget::clearLayout(QLayout * layout) {
|
||||||
if (! layout) return;
|
if(! layout) return;
|
||||||
QLayoutItem * child;
|
QLayoutItem * child;
|
||||||
while ((child = layout->takeAt(0)) != 0) {
|
while((child = layout->takeAt(0)) != 0) {
|
||||||
if(child->widget())
|
if(child->widget()) {
|
||||||
{
|
|
||||||
child->widget()->setParent(NULL); //防止删除后窗口看上去没有消失
|
child->widget()->setParent(NULL); //防止删除后窗口看上去没有消失
|
||||||
}
|
}
|
||||||
delete child;
|
delete child;
|
||||||
|
@ -705,12 +696,11 @@ void ContentWidget::clearLayout(QLayout * layout) {
|
||||||
* @param type
|
* @param type
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
void ContentWidget::onListViewRowChanged(SearchListView * listview, const int &type, const QString &path)
|
void ContentWidget::onListViewRowChanged(SearchListView * listview, const int &type, const QString &path) {
|
||||||
{
|
|
||||||
if(type == SearchItem::SearchType::Contents && !m_contentDetailList.isEmpty()) {
|
if(type == SearchItem::SearchType::Contents && !m_contentDetailList.isEmpty()) {
|
||||||
m_detailView->isContent = true;
|
m_detailView->isContent = true;
|
||||||
m_detailView->setContent(m_contentDetailList.at(listview->currentIndex().row()), m_keyword);
|
m_detailView->setContent(m_contentDetailList.at(listview->currentIndex().row()), m_keyword);
|
||||||
} else if (type == SearchItem::SearchType::Best && !m_bestContent.isEmpty() && listview->currentIndex().row() == listview->getLength() - 1) {
|
} else if(type == SearchItem::SearchType::Best && !m_bestContent.isEmpty() && listview->currentIndex().row() == listview->getLength() - 1) {
|
||||||
m_detailView->setContent(m_bestContent, m_keyword);
|
m_detailView->setContent(m_bestContent, m_keyword);
|
||||||
m_detailView->isContent = true;
|
m_detailView->isContent = true;
|
||||||
m_detailView->setupWidget(SearchItem::SearchType::Contents, path);
|
m_detailView->setupWidget(SearchItem::SearchType::Contents, path);
|
||||||
|
@ -721,14 +711,14 @@ void ContentWidget::onListViewRowChanged(SearchListView * listview, const int &t
|
||||||
} else {
|
} else {
|
||||||
m_detailView->isContent = false;
|
m_detailView->isContent = false;
|
||||||
}
|
}
|
||||||
if (type == SearchItem::SearchType::Web) {
|
if(type == SearchItem::SearchType::Web) {
|
||||||
m_detailView->setWebWidget(this->m_keyword);
|
m_detailView->setWebWidget(this->m_keyword);
|
||||||
} else if (type == SearchItem::SearchType::Apps) {
|
} else if(type == SearchItem::SearchType::Apps) {
|
||||||
int index = listview->currentIndex().row();
|
int index = listview->currentIndex().row();
|
||||||
m_detailView->setAppWidget(m_appList.at(index), m_appPathList.at(index), m_appIconList.at(index), m_appDescList.at(index));
|
m_detailView->setAppWidget(m_appList.at(index), m_appPathList.at(index), m_appIconList.at(index), m_appDescList.at(index));
|
||||||
} else if (type == SearchItem::SearchType::Best) {
|
} else if(type == SearchItem::SearchType::Best) {
|
||||||
if (m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
if(m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
||||||
m_detailView->setAppWidget(m_appList.at(0), m_appPathList.at(0), m_appIconList.at(0), m_appDescList.at(0));
|
m_detailView->setAppWidget(m_appList.at(0), m_appPathList.at(0), m_appIconList.at(0), m_appDescList.at(0));
|
||||||
} else {
|
} else {
|
||||||
m_detailView->setupWidget(m_bestList.at(listview->currentIndex().row()).first, m_bestList.at(listview->currentIndex().row()).second);
|
m_detailView->setupWidget(m_bestList.at(listview->currentIndex().row()).first, m_bestList.at(listview->currentIndex().row()).second);
|
||||||
}
|
}
|
||||||
|
@ -745,20 +735,19 @@ void ContentWidget::onListViewRowChanged(SearchListView * listview, const int &t
|
||||||
* @param type
|
* @param type
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
void ContentWidget::onListViewRowDoubleClicked(SearchListView * listview, const int &type, const QString &path)
|
void ContentWidget::onListViewRowDoubleClicked(SearchListView * listview, const int &type, const QString &path) {
|
||||||
{
|
qDebug() << "A row has been double clicked.Type = " << type << "; Name = " << path;
|
||||||
qDebug()<<"A row has been double clicked.Type = "<<type<<"; Name = "<<path;
|
if(type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first != SearchItem::SearchType::Apps) {
|
||||||
if (type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first != SearchItem::SearchType::Apps) {
|
|
||||||
m_detailView->doubleClickAction(m_bestList.at(listview->currentIndex().row()).first, path);
|
m_detailView->doubleClickAction(m_bestList.at(listview->currentIndex().row()).first, path);
|
||||||
} else if (type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
} else if(type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
||||||
if (m_appPathList.at(0) == "" || m_appPathList.at(0).isEmpty()){
|
if(m_appPathList.at(0) == "" || m_appPathList.at(0).isEmpty()) {
|
||||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(0));
|
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(0));
|
||||||
} else {
|
} else {
|
||||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(0));
|
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(0));
|
||||||
}
|
}
|
||||||
} else if (type == SearchItem::SearchType::Apps) {
|
} else if(type == SearchItem::SearchType::Apps) {
|
||||||
int index = listview->currentIndex().row();
|
int index = listview->currentIndex().row();
|
||||||
if (m_appPathList.at(index) == "" || m_appPathList.at(index).isEmpty()){
|
if(m_appPathList.at(index) == "" || m_appPathList.at(index).isEmpty()) {
|
||||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(index));
|
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(index));
|
||||||
} else {
|
} else {
|
||||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(index));
|
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(index));
|
||||||
|
@ -782,8 +771,7 @@ void ContentWidget::setContentList(const QStringList& list) {
|
||||||
* @brief ContentWidget::setKeyword 设置关键字
|
* @brief ContentWidget::setKeyword 设置关键字
|
||||||
* @param keyword
|
* @param keyword
|
||||||
*/
|
*/
|
||||||
void ContentWidget::setKeyword(QString keyword)
|
void ContentWidget::setKeyword(QString keyword) {
|
||||||
{
|
|
||||||
m_keyword = keyword;
|
m_keyword = keyword;
|
||||||
m_fileListView->setKeyword(keyword);
|
m_fileListView->setKeyword(keyword);
|
||||||
m_dirListView->setKeyword(keyword);
|
m_dirListView->setKeyword(keyword);
|
||||||
|
@ -798,15 +786,13 @@ void ContentWidget::setKeyword(QString keyword)
|
||||||
* @brief ContentWidget::setQuicklyOpenList 设置快速打开列表
|
* @brief ContentWidget::setQuicklyOpenList 设置快速打开列表
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
void ContentWidget::setQuicklyOpenList(const QStringList & list)
|
void ContentWidget::setQuicklyOpenList(const QStringList & list) {
|
||||||
{
|
|
||||||
m_quicklyOpenList = list;
|
m_quicklyOpenList = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ContentWidget::closeWebView 在主界面失焦消失的时候调用,(若webview未关闭)关闭网页搜索界面
|
* @brief ContentWidget::closeWebView 在主界面失焦消失的时候调用,(若webview未关闭)关闭网页搜索界面
|
||||||
*/
|
*/
|
||||||
void ContentWidget::closeWebView()
|
void ContentWidget::closeWebView() {
|
||||||
{
|
|
||||||
m_detailView->closeWebWidget();
|
m_detailView->closeWebWidget();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
#include "show-more-label.h"
|
#include "show-more-label.h"
|
||||||
#include "title-label.h"
|
#include "title-label.h"
|
||||||
|
|
||||||
class ContentWidget : public QStackedWidget
|
class ContentWidget : public QStackedWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ContentWidget(QWidget *);
|
ContentWidget(QWidget *);
|
||||||
|
|
|
@ -19,18 +19,18 @@
|
||||||
*/
|
*/
|
||||||
#include "config-file.h"
|
#include "config-file.h"
|
||||||
|
|
||||||
bool ConfigFile::writeCommonly(QString message){
|
bool ConfigFile::writeCommonly(QString message) {
|
||||||
QSettings *m_qSettings=new QSettings(HOMEPAGE_SETTINGS,QSettings::IniFormat);
|
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||||
QStringList messagelist=message.split("/");
|
QStringList messagelist = message.split("/");
|
||||||
QString appname=messagelist.last();
|
QString appname = messagelist.last();
|
||||||
if(!appname.contains("desktop"))
|
if(!appname.contains("desktop"))
|
||||||
return false;
|
return false;
|
||||||
m_qSettings->beginGroup("Commonly");
|
m_qSettings->beginGroup("Commonly");
|
||||||
QStringList quickly=m_qSettings->allKeys();
|
QStringList quickly = m_qSettings->allKeys();
|
||||||
if(quickly.contains(message.mid(1, message.length()-1))){
|
if(quickly.contains(message.mid(1, message.length() - 1))) {
|
||||||
m_qSettings->setValue(message,m_qSettings->value(message).toInt()+1);
|
m_qSettings->setValue(message, m_qSettings->value(message).toInt() + 1);
|
||||||
}else{
|
} else {
|
||||||
m_qSettings->setValue(message,1);
|
m_qSettings->setValue(message, 1);
|
||||||
}
|
}
|
||||||
m_qSettings->endGroup();
|
m_qSettings->endGroup();
|
||||||
if(m_qSettings)
|
if(m_qSettings)
|
||||||
|
@ -38,26 +38,26 @@ bool ConfigFile::writeCommonly(QString message){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ConfigFile::readCommonly(){
|
QStringList ConfigFile::readCommonly() {
|
||||||
QSettings *m_qSettings=new QSettings(HOMEPAGE_SETTINGS,QSettings::IniFormat);
|
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||||
QStringList returnlist;
|
QStringList returnlist;
|
||||||
QMap<QString,int> quicklycount;
|
QMap<QString, int> quicklycount;
|
||||||
m_qSettings->beginGroup("Commonly");
|
m_qSettings->beginGroup("Commonly");
|
||||||
QStringList Commonly=m_qSettings->allKeys();
|
QStringList Commonly = m_qSettings->allKeys();
|
||||||
for(int i=0;i<Commonly.size();i++){
|
for(int i = 0; i < Commonly.size(); i++) {
|
||||||
quicklycount.insert(Commonly.at(i),m_qSettings->value(Commonly.at(i)).toInt());
|
quicklycount.insert(Commonly.at(i), m_qSettings->value(Commonly.at(i)).toInt());
|
||||||
}
|
}
|
||||||
m_qSettings->endGroup();
|
m_qSettings->endGroup();
|
||||||
QMap<QString, int>::iterator iter =quicklycount.begin();
|
QMap<QString, int>::iterator iter = quicklycount.begin();
|
||||||
QVector<QPair<QString, int>> vec;
|
QVector<QPair<QString, int>> vec;
|
||||||
while(iter !=quicklycount.end()) {
|
while(iter != quicklycount.end()) {
|
||||||
vec.push_back(qMakePair(iter.key(), iter.value()));
|
vec.push_back(qMakePair(iter.key(), iter.value()));
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
qSort(vec.begin(), vec.end(), [](const QPair<QString, int> &l, const QPair<QString, int> &r) {
|
qSort(vec.begin(), vec.end(), [](const QPair<QString, int> &l, const QPair<QString, int> &r) {
|
||||||
return (l.second > r.second);
|
return (l.second > r.second);
|
||||||
});
|
});
|
||||||
for(int j=0;j<vec.size();j++){
|
for(int j = 0; j < vec.size(); j++) {
|
||||||
returnlist.append("/" + vec.at(j).first);
|
returnlist.append("/" + vec.at(j).first);
|
||||||
}
|
}
|
||||||
if(m_qSettings)
|
if(m_qSettings)
|
||||||
|
@ -65,22 +65,22 @@ QStringList ConfigFile::readCommonly(){
|
||||||
return returnlist.mid(0, 5);
|
return returnlist.mid(0, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigFile::writeRecently(QString message){
|
bool ConfigFile::writeRecently(QString message) {
|
||||||
QSettings *m_qSettings=new QSettings(HOMEPAGE_SETTINGS,QSettings::IniFormat);
|
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||||
|
|
||||||
m_qSettings->beginGroup("Recently");
|
m_qSettings->beginGroup("Recently");
|
||||||
QStringList recently=m_qSettings->value("Recently").toStringList();
|
QStringList recently = m_qSettings->value("Recently").toStringList();
|
||||||
m_qSettings->endGroup();
|
m_qSettings->endGroup();
|
||||||
if(recently.contains(message)){
|
if(recently.contains(message)) {
|
||||||
recently.removeOne(message);
|
recently.removeOne(message);
|
||||||
}
|
}
|
||||||
recently.insert(0,message);
|
recently.insert(0, message);
|
||||||
|
|
||||||
m_qSettings->beginGroup("Recently");
|
m_qSettings->beginGroup("Recently");
|
||||||
if (m_qSettings->value("Recently").toStringList().length() >= 20) {
|
if(m_qSettings->value("Recently").toStringList().length() >= 20) {
|
||||||
m_qSettings->setValue("Recently",QStringList(recently.mid(0, 20)));
|
m_qSettings->setValue("Recently", QStringList(recently.mid(0, 20)));
|
||||||
} else {
|
} else {
|
||||||
m_qSettings->setValue("Recently",recently);
|
m_qSettings->setValue("Recently", recently);
|
||||||
}
|
}
|
||||||
m_qSettings->endGroup();
|
m_qSettings->endGroup();
|
||||||
if(m_qSettings)
|
if(m_qSettings)
|
||||||
|
@ -88,34 +88,34 @@ bool ConfigFile::writeRecently(QString message){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ConfigFile::readRecently(){
|
QStringList ConfigFile::readRecently() {
|
||||||
QSettings *m_qSettings=new QSettings(HOMEPAGE_SETTINGS,QSettings::IniFormat);
|
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||||
|
|
||||||
m_qSettings->beginGroup("Recently");
|
m_qSettings->beginGroup("Recently");
|
||||||
QStringList recently=m_qSettings->value("Recently").toStringList();
|
QStringList recently = m_qSettings->value("Recently").toStringList();
|
||||||
m_qSettings->endGroup();
|
m_qSettings->endGroup();
|
||||||
if(m_qSettings)
|
if(m_qSettings)
|
||||||
delete m_qSettings;
|
delete m_qSettings;
|
||||||
return recently.mid(0, 4);
|
return recently.mid(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigFile::writeConfig(QString message){
|
bool ConfigFile::writeConfig(QString message) {
|
||||||
bool isWriteCommonlyDone = writeCommonly(message);
|
bool isWriteCommonlyDone = writeCommonly(message);
|
||||||
bool isWriteRecentlyDone = writeRecently(message);
|
bool isWriteRecentlyDone = writeRecently(message);
|
||||||
return (isWriteCommonlyDone || isWriteRecentlyDone);
|
return (isWriteCommonlyDone || isWriteRecentlyDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString,QStringList> ConfigFile::readConfig(){
|
QMap<QString, QStringList> ConfigFile::readConfig() {
|
||||||
QMap<QString,QStringList> returnresult;
|
QMap<QString, QStringList> returnresult;
|
||||||
returnresult.insert("Commonly",readCommonly());
|
returnresult.insert("Commonly", readCommonly());
|
||||||
returnresult.insert("Recently",readRecently());
|
returnresult.insert("Recently", readRecently());
|
||||||
return returnresult;
|
return returnresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigFile::receiveMessage(QString message){
|
void ConfigFile::receiveMessage(QString message) {
|
||||||
QFile file(HOMEPAGE_SETTINGS);
|
QFile file(HOMEPAGE_SETTINGS);
|
||||||
if(!file.exists()){
|
if(!file.exists()) {
|
||||||
file.open( QIODevice::ReadWrite | QIODevice::Text );
|
file.open(QIODevice::ReadWrite | QIODevice::Text);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
readConfig();//页面调用
|
readConfig();//页面调用
|
||||||
|
|
|
@ -26,18 +26,17 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#define HOMEPAGE_SETTINGS QDir::homePath()+"/.config/org.ukui/ukui-search/ukui-search-homepage.conf"
|
#define HOMEPAGE_SETTINGS QDir::homePath()+"/.config/org.ukui/ukui-search/ukui-search-homepage.conf"
|
||||||
class ConfigFile : public QObject
|
class ConfigFile : public QObject {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static bool writeConfig(QString message);
|
static bool writeConfig(QString message);
|
||||||
static QMap<QString,QStringList> readConfig();
|
static QMap<QString, QStringList> readConfig();
|
||||||
static void receiveMessage(QString message);
|
static void receiveMessage(QString message);
|
||||||
private:
|
private:
|
||||||
static bool writeCommonly(QString message);
|
static bool writeCommonly(QString message);
|
||||||
static QStringList readCommonly();
|
static QStringList readCommonly();
|
||||||
static bool writeRecently(QString message);
|
static bool writeRecently(QString message);
|
||||||
static QStringList readRecently();
|
static QStringList readRecently();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,12 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
|
||||||
FolderListItem::FolderListItem(QWidget *parent, const QString &path) : QWidget(parent)
|
FolderListItem::FolderListItem(QWidget *parent, const QString &path) : QWidget(parent) {
|
||||||
{
|
|
||||||
m_path = path;
|
m_path = path;
|
||||||
initUi();
|
initUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
FolderListItem::~FolderListItem()
|
FolderListItem::~FolderListItem() {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +37,7 @@ FolderListItem::~FolderListItem()
|
||||||
void FolderListItem::initUi() {
|
void FolderListItem::initUi() {
|
||||||
m_layout = new QVBoxLayout(this);
|
m_layout = new QVBoxLayout(this);
|
||||||
m_layout->setSpacing(0);
|
m_layout->setSpacing(0);
|
||||||
m_layout->setContentsMargins(0,0,0,0);
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
m_widget = new QWidget(this);
|
m_widget = new QWidget(this);
|
||||||
m_widget->setObjectName("mWidget");
|
m_widget->setObjectName("mWidget");
|
||||||
this->setFixedHeight(32);
|
this->setFixedHeight(32);
|
||||||
|
@ -77,7 +75,7 @@ QString FolderListItem::getPath() {
|
||||||
* @brief FolderListItem::enterEvent 鼠标移入事件
|
* @brief FolderListItem::enterEvent 鼠标移入事件
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
void FolderListItem::enterEvent(QEvent *event){
|
void FolderListItem::enterEvent(QEvent *event) {
|
||||||
m_delLabel->show();
|
m_delLabel->show();
|
||||||
m_widget->setStyleSheet("QWidget#mWidget{background: rgba(0,0,0,0.1);}");
|
m_widget->setStyleSheet("QWidget#mWidget{background: rgba(0,0,0,0.1);}");
|
||||||
QWidget::enterEvent(event);
|
QWidget::enterEvent(event);
|
||||||
|
@ -87,7 +85,7 @@ void FolderListItem::enterEvent(QEvent *event){
|
||||||
* @brief FolderListItem::leaveEvent 鼠标移出事件
|
* @brief FolderListItem::leaveEvent 鼠标移出事件
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
void FolderListItem::leaveEvent(QEvent *event){
|
void FolderListItem::leaveEvent(QEvent *event) {
|
||||||
m_delLabel->hide();
|
m_delLabel->hide();
|
||||||
m_widget->setStyleSheet("QWidget#mWidget{background: transparent;}");
|
m_widget->setStyleSheet("QWidget#mWidget{background: transparent;}");
|
||||||
QWidget::leaveEvent(event);
|
QWidget::leaveEvent(event);
|
||||||
|
@ -100,9 +98,9 @@ void FolderListItem::leaveEvent(QEvent *event){
|
||||||
* @param event
|
* @param event
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool FolderListItem::eventFilter(QObject *watched, QEvent *event){
|
bool FolderListItem::eventFilter(QObject *watched, QEvent *event) {
|
||||||
if (watched == m_delLabel) {
|
if(watched == m_delLabel) {
|
||||||
if (event->type() == QEvent::MouseButtonPress) {
|
if(event->type() == QEvent::MouseButtonPress) {
|
||||||
// qDebug()<<"pressed!";
|
// qDebug()<<"pressed!";
|
||||||
Q_EMIT this->onDelBtnClicked(m_path);
|
Q_EMIT this->onDelBtnClicked(m_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,7 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
class FolderListItem : public QWidget
|
class FolderListItem : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FolderListItem(QWidget *parent = nullptr, const QString &path = 0);
|
explicit FolderListItem(QWidget *parent = nullptr, const QString &path = 0);
|
||||||
|
|
|
@ -27,8 +27,7 @@
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include "global-settings.h"
|
#include "global-settings.h"
|
||||||
|
|
||||||
HighlightItemDelegate::HighlightItemDelegate(QObject *parent) : QStyledItemDelegate (parent)
|
HighlightItemDelegate::HighlightItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,22 +36,21 @@ HighlightItemDelegate::HighlightItemDelegate(QObject *parent) : QStyledItemDeleg
|
||||||
* \param option
|
* \param option
|
||||||
* \param index
|
* \param index
|
||||||
*/
|
*/
|
||||||
void HighlightItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
|
void HighlightItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||||
{
|
|
||||||
QStyleOptionViewItemV4 optionV4 = option;
|
QStyleOptionViewItemV4 optionV4 = option;
|
||||||
initStyleOption(&optionV4, index);
|
initStyleOption(&optionV4, index);
|
||||||
|
|
||||||
QStyle *style = optionV4.widget? optionV4.widget->style() : QApplication::style();
|
QStyle *style = optionV4.widget ? optionV4.widget->style() : QApplication::style();
|
||||||
|
|
||||||
optionV4.text = QString();
|
optionV4.text = QString();
|
||||||
style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); //绘制非文本区域内容
|
style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); //绘制非文本区域内容
|
||||||
if (index.model()->data(index,Qt::DisplayRole).toString().isEmpty()) return;
|
if(index.model()->data(index, Qt::DisplayRole).toString().isEmpty()) return;
|
||||||
|
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
doc.setHtml(getHtmlText(painter, option, index)); //提取富文本
|
doc.setHtml(getHtmlText(painter, option, index)); //提取富文本
|
||||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||||
|
|
||||||
if (optionV4.state & QStyle::State_Selected)
|
if(optionV4.state & QStyle::State_Selected)
|
||||||
ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));
|
ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));
|
||||||
|
|
||||||
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
|
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
|
||||||
|
@ -80,32 +78,31 @@ void HighlightItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem
|
||||||
* @param index
|
* @param index
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QString HighlightItemDelegate::getHtmlText(QPainter *painter, const QStyleOptionViewItem &itemOption, const QModelIndex &index) const
|
QString HighlightItemDelegate::getHtmlText(QPainter *painter, const QStyleOptionViewItem &itemOption, const QModelIndex &index) const {
|
||||||
{
|
|
||||||
int indexFindLeft = 0;
|
int indexFindLeft = 0;
|
||||||
QString indexString = index.model()->data(index,Qt::DisplayRole).toString();
|
QString indexString = index.model()->data(index, Qt::DisplayRole).toString();
|
||||||
QFont ft(painter->font().family(), GlobalSettings::getInstance()->getValue(FONT_SIZE_KEY).toInt());
|
QFont ft(painter->font().family(), GlobalSettings::getInstance()->getValue(FONT_SIZE_KEY).toInt());
|
||||||
QFontMetrics fm(ft);
|
QFontMetrics fm(ft);
|
||||||
QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() + 10); //当字体超过Item的长度时显示为省略号
|
QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() + 10); //当字体超过Item的长度时显示为省略号
|
||||||
// QFontMetrics m_QFontMetrics = painter->fontMetrics();
|
// QFontMetrics m_QFontMetrics = painter->fontMetrics();
|
||||||
// QString indexColString = m_QFontMetrics.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() + 10); //当字体超过Item的长度时显示为省略号
|
// QString indexColString = m_QFontMetrics.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() + 10); //当字体超过Item的长度时显示为省略号
|
||||||
QString htmlString;
|
QString htmlString;
|
||||||
if ((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) {
|
if((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) {
|
||||||
indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置
|
indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置
|
||||||
// paintKeywordHighlight(painter, itemOption, indexColString, indexFindLeft, m_regFindKeyWords.length());
|
// paintKeywordHighlight(painter, itemOption, indexColString, indexFindLeft, m_regFindKeyWords.length());
|
||||||
htmlString = escapeHtml(indexColString.left(indexFindLeft)) + "<b>" + escapeHtml(indexColString.mid(indexFindLeft, m_regFindKeyWords.length())) + "</b>" + escapeHtml(indexColString.right(indexColString.length() - indexFindLeft - m_regFindKeyWords.length()));
|
htmlString = escapeHtml(indexColString.left(indexFindLeft)) + "<b>" + escapeHtml(indexColString.mid(indexFindLeft, m_regFindKeyWords.length())) + "</b>" + escapeHtml(indexColString.right(indexColString.length() - indexFindLeft - m_regFindKeyWords.length()));
|
||||||
} else {
|
} else {
|
||||||
bool boldOpenned = false;
|
bool boldOpenned = false;
|
||||||
for (int i = 0; i < indexColString.length(); i++) {
|
for(int i = 0; i < indexColString.length(); i++) {
|
||||||
if ((m_regFindKeyWords.toUpper()).contains(QString(indexColString.at(i)).toUpper())) {
|
if((m_regFindKeyWords.toUpper()).contains(QString(indexColString.at(i)).toUpper())) {
|
||||||
// paintKeywordHighlight(painter, itemOption, indexColString, i, 1);
|
// paintKeywordHighlight(painter, itemOption, indexColString, i, 1);
|
||||||
if (! boldOpenned) {
|
if(! boldOpenned) {
|
||||||
boldOpenned = true;
|
boldOpenned = true;
|
||||||
htmlString.append(QString("<b>"));
|
htmlString.append(QString("<b>"));
|
||||||
}
|
}
|
||||||
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
||||||
} else {
|
} else {
|
||||||
if (boldOpenned) {
|
if(boldOpenned) {
|
||||||
boldOpenned = false;
|
boldOpenned = false;
|
||||||
htmlString.append(QString("</b>"));
|
htmlString.append(QString("</b>"));
|
||||||
}
|
}
|
||||||
|
@ -123,8 +120,7 @@ QString HighlightItemDelegate::getHtmlText(QPainter *painter, const QStyleOption
|
||||||
* @param str
|
* @param str
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QString HighlightItemDelegate::escapeHtml(const QString & str) const
|
QString HighlightItemDelegate::escapeHtml(const QString & str) const {
|
||||||
{
|
|
||||||
QString temp = str;
|
QString temp = str;
|
||||||
temp.replace("<", "<");
|
temp.replace("<", "<");
|
||||||
temp.replace(">", ">");
|
temp.replace(">", ">");
|
||||||
|
@ -139,8 +135,7 @@ QString HighlightItemDelegate::escapeHtml(const QString & str) const
|
||||||
* @param indexFindLeft 关键字位置
|
* @param indexFindLeft 关键字位置
|
||||||
* @param keywordLength 关键字长度
|
* @param keywordLength 关键字长度
|
||||||
*/
|
*/
|
||||||
void HighlightItemDelegate::paintKeywordHighlight(QPainter *painter, const QStyleOptionViewItem &itemOption, const QString &indexColString, const int &indexFindLeft, const int &keywordLength) const
|
void HighlightItemDelegate::paintKeywordHighlight(QPainter *painter, const QStyleOptionViewItem &itemOption, const QString &indexColString, const int &indexFindLeft, const int &keywordLength) const {
|
||||||
{
|
|
||||||
QPen pen(Qt::black);
|
QPen pen(Qt::black);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
QFont font = QApplication::font(itemOption.widget);
|
QFont font = QApplication::font(itemOption.widget);
|
||||||
|
@ -157,15 +152,14 @@ void HighlightItemDelegate::paintKeywordHighlight(QPainter *painter, const QStyl
|
||||||
QStyle * m_QStyle = m_QWidget ? m_QWidget->style() : QApplication::style(); //得到当前的style
|
QStyle * m_QStyle = m_QWidget ? m_QWidget->style() : QApplication::style(); //得到当前的style
|
||||||
QRect m_QRect = itemOption.rect;//得到Item的自己的Rect
|
QRect m_QRect = itemOption.rect;//得到Item的自己的Rect
|
||||||
QPalette::ColorRole textDisplayRole = QPalette::NoRole; //设置text的role
|
QPalette::ColorRole textDisplayRole = QPalette::NoRole; //设置text的role
|
||||||
if (itemOption.state & QStyle::State_Selected)
|
if(itemOption.state & QStyle::State_Selected) {
|
||||||
{
|
|
||||||
textDisplayRole = QPalette::HighlightedText; //当选中字体的时候字体显示高亮
|
textDisplayRole = QPalette::HighlightedText; //当选中字体的时候字体显示高亮
|
||||||
} else {
|
} else {
|
||||||
textDisplayRole = QPalette::Text;
|
textDisplayRole = QPalette::Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findKeyWordWidth = m_leftFontMetrics.width(m_regFindKeyWords); //得到查找字体的像素宽度
|
int findKeyWordWidth = m_leftFontMetrics.width(m_regFindKeyWords); //得到查找字体的像素宽度
|
||||||
int preFindKeyWordWidth = m_leftFontMetrics.width(indexColString.mid(0,indexFindLeft)); //得到查找字体前面的字体的像素宽度
|
int preFindKeyWordWidth = m_leftFontMetrics.width(indexColString.mid(0, indexFindLeft)); //得到查找字体前面的字体的像素宽度
|
||||||
|
|
||||||
m_QRect = m_QRect.adjusted(preFindKeyWordWidth + 3, 0, findKeyWordWidth, 0);
|
m_QRect = m_QRect.adjusted(preFindKeyWordWidth + 3, 0, findKeyWordWidth, 0);
|
||||||
//高亮字段
|
//高亮字段
|
||||||
|
@ -177,8 +171,7 @@ void HighlightItemDelegate::paintKeywordHighlight(QPainter *painter, const QStyl
|
||||||
* \brief treewidget_styledItemDelegate::search_keyword 赋值关键字
|
* \brief treewidget_styledItemDelegate::search_keyword 赋值关键字
|
||||||
* \param regFindKeyWords
|
* \param regFindKeyWords
|
||||||
*/
|
*/
|
||||||
void HighlightItemDelegate::setSearchKeyword(const QString ®FindKeyWords)
|
void HighlightItemDelegate::setSearchKeyword(const QString ®FindKeyWords) {
|
||||||
{
|
|
||||||
m_regFindKeyWords.clear();
|
m_regFindKeyWords.clear();
|
||||||
m_regFindKeyWords = regFindKeyWords;
|
m_regFindKeyWords = regFindKeyWords;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,15 +23,14 @@
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
class HighlightItemDelegate : public QStyledItemDelegate
|
class HighlightItemDelegate : public QStyledItemDelegate {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit HighlightItemDelegate(QObject *parent = nullptr);
|
explicit HighlightItemDelegate(QObject *parent = nullptr);
|
||||||
void setSearchKeyword(const QString &);
|
void setSearchKeyword(const QString &);
|
||||||
private:
|
private:
|
||||||
QString m_regFindKeyWords = 0;
|
QString m_regFindKeyWords = 0;
|
||||||
void paint(QPainter *,const QStyleOptionViewItem &, const QModelIndex &) const override;
|
void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||||
QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
|
QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||||
QString escapeHtml(const QString&) const;
|
QString escapeHtml(const QString&) const;
|
||||||
void paintKeywordHighlight(QPainter *, const QStyleOptionViewItem &, const QString &, const int &, const int &) const;
|
void paintKeywordHighlight(QPainter *, const QStyleOptionViewItem &, const QString &, const int &, const int &) const;
|
||||||
|
|
|
@ -28,14 +28,13 @@
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
HomePageItem::HomePageItem(QWidget *parent, const int& type, const QString& path) : QWidget(parent)
|
HomePageItem::HomePageItem(QWidget *parent, const int& type, const QString& path) : QWidget(parent) {
|
||||||
{
|
|
||||||
setupUi(type, path);
|
setupUi(type, path);
|
||||||
m_transparency = 0.06;
|
m_transparency = 0.06;
|
||||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||||
if (m_namelabel) {
|
if(m_namelabel) {
|
||||||
QString name = this->toolTip();
|
QString name = this->toolTip();
|
||||||
if (m_type == ItemType::Recent) {
|
if(m_type == ItemType::Recent) {
|
||||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 250));
|
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 250));
|
||||||
} else {
|
} else {
|
||||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
||||||
|
@ -44,8 +43,7 @@ HomePageItem::HomePageItem(QWidget *parent, const int& type, const QString& path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
HomePageItem::~HomePageItem()
|
HomePageItem::~HomePageItem() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,42 +60,42 @@ void HomePageItem::setupUi(const int& type, const QString& path) {
|
||||||
m_widget->installEventFilter(this);
|
m_widget->installEventFilter(this);
|
||||||
m_iconlabel = new QLabel(m_widget);
|
m_iconlabel = new QLabel(m_widget);
|
||||||
m_namelabel = new QLabel(m_widget);
|
m_namelabel = new QLabel(m_widget);
|
||||||
if (type == ItemType::Recent) {
|
if(type == ItemType::Recent) {
|
||||||
m_widget->setFixedSize(300, 48);
|
m_widget->setFixedSize(300, 48);
|
||||||
QIcon icon;
|
QIcon icon;
|
||||||
switch (SearchListView::getResType(path)) { //可能出现文件应用等,需要根据路径判断类型
|
switch(SearchListView::getResType(path)) { //可能出现文件应用等,需要根据路径判断类型
|
||||||
case SearchListView::ResType::App : {
|
case SearchListView::ResType::App : {
|
||||||
icon = FileUtils::getAppIcon(path);
|
icon = FileUtils::getAppIcon(path);
|
||||||
m_namelabel->setText(FileUtils::getAppName(path));
|
m_namelabel->setText(FileUtils::getAppName(path));
|
||||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||||
QString name = FileUtils::getAppName(path);
|
QString name = FileUtils::getAppName(path);
|
||||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||||
this->setToolTip(name);
|
this->setToolTip(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SearchListView::ResType::Best :
|
case SearchListView::ResType::Best :
|
||||||
case SearchListView::ResType::Content:
|
case SearchListView::ResType::Content:
|
||||||
case SearchListView::ResType::Dir :
|
case SearchListView::ResType::Dir :
|
||||||
case SearchListView::ResType::File : {
|
case SearchListView::ResType::File : {
|
||||||
icon = FileUtils::getFileIcon(QString("file://%1").arg(path));
|
icon = FileUtils::getFileIcon(QString("file://%1").arg(path));
|
||||||
// m_namelabel->setText(FileUtils::getFileName(path));
|
// m_namelabel->setText(FileUtils::getFileName(path));
|
||||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||||
QString name = FileUtils::getFileName(path);
|
QString name = FileUtils::getFileName(path);
|
||||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||||
this->setToolTip(name);
|
this->setToolTip(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SearchListView::ResType::Setting : {
|
case SearchListView::ResType::Setting : {
|
||||||
icon = FileUtils::getSettingIcon(path, true);
|
icon = FileUtils::getSettingIcon(path, true);
|
||||||
// m_namelabel->setText(FileUtils::getSettingName(path));
|
// m_namelabel->setText(FileUtils::getSettingName(path));
|
||||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||||
QString name = FileUtils::getSettingName(path);
|
QString name = FileUtils::getSettingName(path);
|
||||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||||
this->setToolTip(name);
|
this->setToolTip(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(24, 24))));
|
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(24, 24))));
|
||||||
m_hlayout = new QHBoxLayout(m_widget);
|
m_hlayout = new QHBoxLayout(m_widget);
|
||||||
|
@ -107,12 +105,12 @@ void HomePageItem::setupUi(const int& type, const QString& path) {
|
||||||
m_hlayout->addWidget(m_namelabel);
|
m_hlayout->addWidget(m_namelabel);
|
||||||
m_hlayout->addStretch();
|
m_hlayout->addStretch();
|
||||||
return;
|
return;
|
||||||
} else if (type == ItemType::Quick) {
|
} else if(type == ItemType::Quick) {
|
||||||
QIcon icon = FileUtils::getAppIcon(path);
|
QIcon icon = FileUtils::getAppIcon(path);
|
||||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
||||||
QString name = FileUtils::getAppName(path);
|
QString name = FileUtils::getAppName(path);
|
||||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
||||||
this->setToolTip(name);
|
this->setToolTip(name);
|
||||||
} else {
|
} else {
|
||||||
QIcon icon = FileUtils::getAppIcon(path);
|
QIcon icon = FileUtils::getAppIcon(path);
|
||||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
||||||
|
@ -124,56 +122,55 @@ void HomePageItem::setupUi(const int& type, const QString& path) {
|
||||||
}
|
}
|
||||||
m_widget->setFixedSize(116, 116);
|
m_widget->setFixedSize(116, 116);
|
||||||
m_vlayout = new QVBoxLayout(m_widget);
|
m_vlayout = new QVBoxLayout(m_widget);
|
||||||
m_vlayout->setContentsMargins(0,16,0,12);
|
m_vlayout->setContentsMargins(0, 16, 0, 12);
|
||||||
m_iconlabel->setAlignment(Qt::AlignCenter);
|
m_iconlabel->setAlignment(Qt::AlignCenter);
|
||||||
m_namelabel->setAlignment(Qt::AlignCenter);
|
m_namelabel->setAlignment(Qt::AlignCenter);
|
||||||
m_vlayout->addWidget(m_iconlabel);
|
m_vlayout->addWidget(m_iconlabel);
|
||||||
m_vlayout->addWidget(m_namelabel);
|
m_vlayout->addWidget(m_namelabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HomePageItem::onItemClicked()
|
void HomePageItem::onItemClicked() {
|
||||||
{
|
switch(SearchListView::getResType(m_path)) {
|
||||||
switch (SearchListView::getResType(m_path)) {
|
case SearchListView::ResType::App: {
|
||||||
case SearchListView::ResType::App: {
|
GDesktopAppInfo * desktopAppInfo = g_desktop_app_info_new_from_filename(m_path.toLocal8Bit().data());
|
||||||
GDesktopAppInfo * desktopAppInfo = g_desktop_app_info_new_from_filename(m_path.toLocal8Bit().data());
|
g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr);
|
||||||
g_app_info_launch(G_APP_INFO(desktopAppInfo),nullptr, nullptr, nullptr);
|
g_object_unref(desktopAppInfo);
|
||||||
g_object_unref(desktopAppInfo);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case SearchListView::ResType::Best:
|
||||||
case SearchListView::ResType::Best:
|
case SearchListView::ResType::Content:
|
||||||
case SearchListView::ResType::Content:
|
case SearchListView::ResType::Dir:
|
||||||
case SearchListView::ResType::Dir:
|
case SearchListView::ResType::File: {
|
||||||
case SearchListView::ResType::File: {
|
QDesktopServices::openUrl(QUrl::fromLocalFile(m_path));
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(m_path));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case SearchListView::ResType::Setting: {
|
||||||
case SearchListView::ResType::Setting: {
|
//打开控制面板对应页面
|
||||||
//打开控制面板对应页面
|
QProcess process;
|
||||||
QProcess process;
|
process.startDetached(QString("ukui-control-center --%1").arg(m_path.left(m_path.indexOf("/")).toLower()));
|
||||||
process.startDetached(QString("ukui-control-center --%1").arg(m_path.left(m_path.indexOf("/")).toLower()));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HomePageItem::eventFilter(QObject *watched, QEvent *event){
|
bool HomePageItem::eventFilter(QObject *watched, QEvent *event) {
|
||||||
if (watched == m_widget){
|
if(watched == m_widget) {
|
||||||
if (event->type() == QEvent::MouseButtonPress) {
|
if(event->type() == QEvent::MouseButtonPress) {
|
||||||
m_transparency = 0.06;
|
m_transparency = 0.06;
|
||||||
this->update();
|
this->update();
|
||||||
return true;
|
return true;
|
||||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||||
this->onItemClicked();
|
this->onItemClicked();
|
||||||
m_transparency = 0.06;
|
m_transparency = 0.06;
|
||||||
this->update();
|
this->update();
|
||||||
return true;
|
return true;
|
||||||
} else if (event->type() == QEvent::Enter) {
|
} else if(event->type() == QEvent::Enter) {
|
||||||
m_transparency = 0.15;
|
m_transparency = 0.15;
|
||||||
this->update();
|
this->update();
|
||||||
return true;
|
return true;
|
||||||
} else if (event->type() == QEvent::Leave) {
|
} else if(event->type() == QEvent::Leave) {
|
||||||
m_transparency = 0.06;
|
m_transparency = 0.06;
|
||||||
this->update();
|
this->update();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
#include "file-utils.h"
|
#include "file-utils.h"
|
||||||
#include "search-list-view.h"
|
#include "search-list-view.h"
|
||||||
|
|
||||||
class HomePageItem : public QWidget
|
class HomePageItem : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit HomePageItem(QWidget *, const int&, const QString&);
|
explicit HomePageItem(QWidget *, const int&, const QString&);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue