Format code style.

This commit is contained in:
zhangzihao 2021-04-26 15:06:47 +08:00
parent a70be3f810
commit 422c73fd1e
141 changed files with 11473 additions and 12282 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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_;
}; };
} }

View File

@ -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_;
}; };
} }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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*/

View File

@ -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

View File

@ -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;
//} //}

View File

@ -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, * 65304,
* 65305, * 65305,
*/ */
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

View File

@ -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 );
//} //}

View File

@ -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;
} }

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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 );
} }

View File

@ -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';

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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]);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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/");
} }
} }
}); });

View File

@ -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:

View File

@ -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();

View File

@ -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:

View File

@ -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()));
} }
} }

View File

@ -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);

View File

@ -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);
} }

View File

@ -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));
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);
}; };

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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");

View File

@ -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();

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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;

View File

@ -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 {

View File

@ -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:

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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();

View File

@ -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

View File

@ -22,8 +22,7 @@
#include <QDBusInterface> #include <QDBusInterface>
class UkuiSearchQDBus class UkuiSearchQDBus {
{
public: public:
UkuiSearchQDBus(); UkuiSearchQDBus();
~UkuiSearchQDBus(); ~UkuiSearchQDBus();

View File

@ -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

View File

@ -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

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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();
} }

View File

@ -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 *);

View File

@ -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();//页面调用

View File

@ -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();
}; };

View File

@ -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);
} }

View File

@ -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);

View File

@ -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("<", "&lt;"); temp.replace("<", "&lt;");
temp.replace(">", "&gt;"); temp.replace(">", "&gt;");
@ -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 &regFindKeyWords) void HighlightItemDelegate::setSearchKeyword(const QString &regFindKeyWords) {
{
m_regFindKeyWords.clear(); m_regFindKeyWords.clear();
m_regFindKeyWords = regFindKeyWords; m_regFindKeyWords = regFindKeyWords;
} }

View File

@ -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;

View File

@ -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;

View File

@ -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