mirror of
https://github.com/yanyiwu/cppjieba.git
synced 2025-07-18 00:00:12 +08:00
add submodule limonp
This commit is contained in:
parent
194c144d8b
commit
01aba1d85d
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "deps/limonp"]
|
||||
path = deps/limonp
|
||||
url = https://github.com/yanyiwu/limonp.git
|
1
deps/limonp
vendored
Submodule
1
deps/limonp
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8cabf54faa56c7b3ea25c62f625a9a64e2dcf501
|
70
deps/limonp/ArgvContext.hpp
vendored
70
deps/limonp/ArgvContext.hpp
vendored
@ -1,70 +0,0 @@
|
||||
/************************************
|
||||
* file enc : ascii
|
||||
* author : wuyanyi09@gmail.com
|
||||
************************************/
|
||||
|
||||
#ifndef LIMONP_ARGV_FUNCTS_H
|
||||
#define LIMONP_ARGV_FUNCTS_H
|
||||
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include "StringUtil.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ArgvContext {
|
||||
public :
|
||||
ArgvContext(int argc, const char* const * argv) {
|
||||
for(int i = 0; i < argc; i++) {
|
||||
if(StartsWith(argv[i], "-")) {
|
||||
if(i + 1 < argc && !StartsWith(argv[i + 1], "-")) {
|
||||
mpss_[argv[i]] = argv[i+1];
|
||||
i++;
|
||||
} else {
|
||||
sset_.insert(argv[i]);
|
||||
}
|
||||
} else {
|
||||
args_.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
~ArgvContext() {
|
||||
}
|
||||
|
||||
friend ostream& operator << (ostream& os, const ArgvContext& args);
|
||||
string operator [](size_t i) const {
|
||||
if(i < args_.size()) {
|
||||
return args_[i];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
string operator [](const string& key) const {
|
||||
map<string, string>::const_iterator it = mpss_.find(key);
|
||||
if(it != mpss_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool HasKey(const string& key) const {
|
||||
if(mpss_.find(key) != mpss_.end() || sset_.find(key) != sset_.end()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
vector<string> args_;
|
||||
map<string, string> mpss_;
|
||||
set<string> sset_;
|
||||
}; // class ArgvContext
|
||||
|
||||
inline ostream& operator << (ostream& os, const ArgvContext& args) {
|
||||
return os<<args.args_<<args.mpss_<<args.sset_;
|
||||
}
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif
|
49
deps/limonp/BlockingQueue.hpp
vendored
49
deps/limonp/BlockingQueue.hpp
vendored
@ -1,49 +0,0 @@
|
||||
#ifndef LIMONP_BLOCKINGQUEUE_HPP
|
||||
#define LIMONP_BLOCKINGQUEUE_HPP
|
||||
|
||||
#include <queue>
|
||||
#include "Condition.hpp"
|
||||
|
||||
namespace limonp {
|
||||
template<class T>
|
||||
class BlockingQueue: NonCopyable {
|
||||
public:
|
||||
BlockingQueue()
|
||||
: 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 {
|
||||
MutexLockGuard lock(mutex_);
|
||||
return queue_.size();
|
||||
}
|
||||
bool Empty() const {
|
||||
return Size() == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable MutexLock mutex_;
|
||||
Condition notEmpty_;
|
||||
std::queue<T> queue_;
|
||||
}; // class BlockingQueue
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_BLOCKINGQUEUE_HPP
|
67
deps/limonp/BoundedBlockingQueue.hpp
vendored
67
deps/limonp/BoundedBlockingQueue.hpp
vendored
@ -1,67 +0,0 @@
|
||||
#ifndef LIMONP_BOUNDED_BLOCKING_QUEUE_HPP
|
||||
#define LIMONP_BOUNDED_BLOCKING_QUEUE_HPP
|
||||
|
||||
#include "BoundedQueue.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
template<typename T>
|
||||
class BoundedBlockingQueue : NonCopyable {
|
||||
public:
|
||||
explicit BoundedBlockingQueue(size_t maxSize)
|
||||
: mutex_(),
|
||||
notEmpty_(mutex_),
|
||||
notFull_(mutex_),
|
||||
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() {
|
||||
MutexLockGuard lock(mutex_);
|
||||
while (queue_.Empty()) {
|
||||
notEmpty_.Wait();
|
||||
}
|
||||
assert(!queue_.Empty());
|
||||
T res = queue_.Pop();
|
||||
notFull_.Notify();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Empty() const {
|
||||
MutexLockGuard lock(mutex_);
|
||||
return queue_.Empty();
|
||||
}
|
||||
|
||||
bool Full() const {
|
||||
MutexLockGuard lock(mutex_);
|
||||
return queue_.Full();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
MutexLockGuard lock(mutex_);
|
||||
return queue_.size();
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return queue_.capacity();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable MutexLock mutex_;
|
||||
Condition notEmpty_;
|
||||
Condition notFull_;
|
||||
BoundedQueue<T> queue_;
|
||||
}; // class BoundedBlockingQueue
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_BOUNDED_BLOCKING_QUEUE_HPP
|
65
deps/limonp/BoundedQueue.hpp
vendored
65
deps/limonp/BoundedQueue.hpp
vendored
@ -1,65 +0,0 @@
|
||||
#ifndef LIMONP_BOUNDED_QUEUE_HPP
|
||||
#define LIMONP_BOUNDED_QUEUE_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
namespace limonp {
|
||||
using namespace std;
|
||||
template<class T>
|
||||
class BoundedQueue {
|
||||
public:
|
||||
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular_buffer_(capacity) {
|
||||
head_ = 0;
|
||||
tail_ = 0;
|
||||
size_ = 0;
|
||||
assert(capacity_);
|
||||
}
|
||||
~BoundedQueue() {
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
head_ = 0;
|
||||
tail_ = 0;
|
||||
size_ = 0;
|
||||
}
|
||||
bool Empty() const {
|
||||
return !size_;
|
||||
}
|
||||
bool Full() const {
|
||||
return capacity_ == size_;
|
||||
}
|
||||
size_t Size() const {
|
||||
return size_;
|
||||
}
|
||||
size_t Capacity() const {
|
||||
return capacity_;
|
||||
}
|
||||
|
||||
void Push(const T& t) {
|
||||
assert(!Full());
|
||||
circular_buffer_[tail_] = t;
|
||||
tail_ = (tail_ + 1) % capacity_;
|
||||
size_ ++;
|
||||
}
|
||||
|
||||
T Pop() {
|
||||
assert(!Empty());
|
||||
size_t oldPos = head_;
|
||||
head_ = (head_ + 1) % capacity_;
|
||||
size_ --;
|
||||
return circular_buffer_[oldPos];
|
||||
}
|
||||
|
||||
private:
|
||||
size_t head_;
|
||||
size_t tail_;
|
||||
size_t size_;
|
||||
const size_t capacity_;
|
||||
vector<T> circular_buffer_;
|
||||
|
||||
}; // class BoundedQueue
|
||||
} // namespace limonp
|
||||
|
||||
#endif
|
206
deps/limonp/Closure.hpp
vendored
206
deps/limonp/Closure.hpp
vendored
@ -1,206 +0,0 @@
|
||||
#ifndef LIMONP_CLOSURE_HPP
|
||||
#define LIMONP_CLOSURE_HPP
|
||||
|
||||
namespace limonp {
|
||||
|
||||
class ClosureInterface {
|
||||
public:
|
||||
virtual ~ClosureInterface() {
|
||||
}
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
template <class Funct>
|
||||
class Closure0: public ClosureInterface {
|
||||
public:
|
||||
Closure0(Funct fun) {
|
||||
fun_ = fun;
|
||||
}
|
||||
virtual ~Closure0() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(*fun_)();
|
||||
}
|
||||
private:
|
||||
Funct fun_;
|
||||
};
|
||||
|
||||
template <class Funct, class Arg1>
|
||||
class Closure1: public ClosureInterface {
|
||||
public:
|
||||
Closure1(Funct fun, Arg1 arg1) {
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
}
|
||||
virtual ~Closure1() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(*fun_)(arg1_);
|
||||
}
|
||||
private:
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
};
|
||||
|
||||
template <class Funct, class Arg1, class Arg2>
|
||||
class Closure2: public ClosureInterface {
|
||||
public:
|
||||
Closure2(Funct fun, Arg1 arg1, Arg2 arg2) {
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
arg2_ = arg2;
|
||||
}
|
||||
virtual ~Closure2() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(*fun_)(arg1_, arg2_);
|
||||
}
|
||||
private:
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
};
|
||||
|
||||
template <class Funct, class Arg1, class Arg2, class Arg3>
|
||||
class Closure3: public ClosureInterface {
|
||||
public:
|
||||
Closure3(Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
arg2_ = arg2;
|
||||
arg3_ = arg3;
|
||||
}
|
||||
virtual ~Closure3() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(*fun_)(arg1_, arg2_, arg3_);
|
||||
}
|
||||
private:
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
};
|
||||
|
||||
template <class Obj, class Funct>
|
||||
class ObjClosure0: public ClosureInterface {
|
||||
public:
|
||||
ObjClosure0(Obj* p, Funct fun) {
|
||||
p_ = p;
|
||||
fun_ = fun;
|
||||
}
|
||||
virtual ~ObjClosure0() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(p_->*fun_)();
|
||||
}
|
||||
private:
|
||||
Obj* p_;
|
||||
Funct fun_;
|
||||
};
|
||||
|
||||
template <class Obj, class Funct, class Arg1>
|
||||
class ObjClosure1: public ClosureInterface {
|
||||
public:
|
||||
ObjClosure1(Obj* p, Funct fun, Arg1 arg1) {
|
||||
p_ = p;
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
}
|
||||
virtual ~ObjClosure1() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(p_->*fun_)(arg1_);
|
||||
}
|
||||
private:
|
||||
Obj* p_;
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
};
|
||||
|
||||
template <class Obj, class Funct, class Arg1, class Arg2>
|
||||
class ObjClosure2: public ClosureInterface {
|
||||
public:
|
||||
ObjClosure2(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2) {
|
||||
p_ = p;
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
arg2_ = arg2;
|
||||
}
|
||||
virtual ~ObjClosure2() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(p_->*fun_)(arg1_, arg2_);
|
||||
}
|
||||
private:
|
||||
Obj* p_;
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
};
|
||||
template <class Obj, class Funct, class Arg1, class Arg2, class Arg3>
|
||||
class ObjClosure3: public ClosureInterface {
|
||||
public:
|
||||
ObjClosure3(Obj* p, Funct fun, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
|
||||
p_ = p;
|
||||
fun_ = fun;
|
||||
arg1_ = arg1;
|
||||
arg2_ = arg2;
|
||||
arg3_ = arg3;
|
||||
}
|
||||
virtual ~ObjClosure3() {
|
||||
}
|
||||
virtual void Run() {
|
||||
(p_->*fun_)(arg1_, arg2_, arg3_);
|
||||
}
|
||||
private:
|
||||
Obj* p_;
|
||||
Funct fun_;
|
||||
Arg1 arg1_;
|
||||
Arg2 arg2_;
|
||||
Arg3 arg3_;
|
||||
};
|
||||
|
||||
template<class R>
|
||||
ClosureInterface* NewClosure(R (*fun)()) {
|
||||
return new Closure0<R (*)()>(fun);
|
||||
}
|
||||
|
||||
template<class R, class Arg1>
|
||||
ClosureInterface* NewClosure(R (*fun)(Arg1), Arg1 arg1) {
|
||||
return new Closure1<R (*)(Arg1), Arg1>(fun, arg1);
|
||||
}
|
||||
|
||||
template<class R, class Arg1, class Arg2>
|
||||
ClosureInterface* NewClosure(R (*fun)(Arg1, Arg2), Arg1 arg1, Arg2 arg2) {
|
||||
return new Closure2<R (*)(Arg1, Arg2), Arg1, Arg2>(fun, arg1, arg2);
|
||||
}
|
||||
|
||||
template<class R, class Arg1, class Arg2, class 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);
|
||||
}
|
||||
|
||||
template<class R, class Obj>
|
||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)()) {
|
||||
return new ObjClosure0<Obj, R (Obj::* )()>(obj, fun);
|
||||
}
|
||||
|
||||
template<class R, class Obj, class Arg1>
|
||||
ClosureInterface* NewClosure(Obj* obj, R (Obj::* fun)(Arg1), Arg1 arg1) {
|
||||
return new ObjClosure1<Obj, R (Obj::* )(Arg1), Arg1>(obj, fun, arg1);
|
||||
}
|
||||
|
||||
template<class R, class Obj, class Arg1, class 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return new ObjClosure3<Obj, R (Obj::*)(Arg1, Arg2, Arg3), Arg1, Arg2, Arg3>(obj, fun, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_CLOSURE_HPP
|
31
deps/limonp/Colors.hpp
vendored
31
deps/limonp/Colors.hpp
vendored
@ -1,31 +0,0 @@
|
||||
#ifndef LIMONP_COLOR_PRINT_HPP
|
||||
#define LIMONP_COLOR_PRINT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace limonp {
|
||||
|
||||
using std::string;
|
||||
|
||||
enum Color {
|
||||
BLACK = 30,
|
||||
RED,
|
||||
GREEN,
|
||||
YELLOW,
|
||||
BLUE,
|
||||
PURPLE
|
||||
}; // enum Color
|
||||
|
||||
static void ColorPrintln(enum Color color, const char * fmt, ...) {
|
||||
va_list ap;
|
||||
printf("\033[0;%dm", color);
|
||||
va_start(ap, fmt);
|
||||
vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
printf("\033[0m\n"); // if not \n , in some situation , the next lines will be set the same color unexpectedly
|
||||
}
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_COLOR_PRINT_HPP
|
38
deps/limonp/Condition.hpp
vendored
38
deps/limonp/Condition.hpp
vendored
@ -1,38 +0,0 @@
|
||||
#ifndef LIMONP_CONDITION_HPP
|
||||
#define LIMONP_CONDITION_HPP
|
||||
|
||||
#include "MutexLock.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
class Condition : NonCopyable {
|
||||
public:
|
||||
explicit Condition(MutexLock& mutex)
|
||||
: mutex_(mutex) {
|
||||
XCHECK(!pthread_cond_init(&pcond_, NULL));
|
||||
}
|
||||
|
||||
~Condition() {
|
||||
XCHECK(!pthread_cond_destroy(&pcond_));
|
||||
}
|
||||
|
||||
void Wait() {
|
||||
XCHECK(!pthread_cond_wait(&pcond_, mutex_.GetPthreadMutex()));
|
||||
}
|
||||
|
||||
void Notify() {
|
||||
XCHECK(!pthread_cond_signal(&pcond_));
|
||||
}
|
||||
|
||||
void NotifyAll() {
|
||||
XCHECK(!pthread_cond_broadcast(&pcond_));
|
||||
}
|
||||
|
||||
private:
|
||||
MutexLock& mutex_;
|
||||
pthread_cond_t pcond_;
|
||||
}; // class Condition
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_CONDITION_HPP
|
103
deps/limonp/Config.hpp
vendored
103
deps/limonp/Config.hpp
vendored
@ -1,103 +0,0 @@
|
||||
/************************************
|
||||
* file enc : utf8
|
||||
* author : wuyanyi09@gmail.com
|
||||
************************************/
|
||||
#ifndef LIMONP_CONFIG_H
|
||||
#define LIMONP_CONFIG_H
|
||||
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include "StringUtil.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Config {
|
||||
public:
|
||||
explicit Config(const string& 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 {
|
||||
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
|
||||
|
||||
inline ostream& operator << (ostream& os, const Config& config) {
|
||||
return os << config.map_;
|
||||
}
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_CONFIG_H
|
74
deps/limonp/FileLock.hpp
vendored
74
deps/limonp/FileLock.hpp
vendored
@ -1,74 +0,0 @@
|
||||
#ifndef LIMONP_FILELOCK_HPP
|
||||
#define LIMONP_FILELOCK_HPP
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace limonp {
|
||||
|
||||
using std::string;
|
||||
|
||||
class FileLock {
|
||||
public:
|
||||
FileLock() : fd_(-1), ok_(true) {
|
||||
}
|
||||
~FileLock() {
|
||||
if(fd_ > 0) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
void Open(const string& fname) {
|
||||
assert(fd_ == -1);
|
||||
fd_ = open(fname.c_str(), O_RDWR | O_CREAT, 0644);
|
||||
if(fd_ < 0) {
|
||||
ok_ = false;
|
||||
err_ = strerror(errno);
|
||||
}
|
||||
}
|
||||
void Close() {
|
||||
::close(fd_);
|
||||
}
|
||||
void Lock() {
|
||||
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);
|
||||
}
|
||||
|
||||
int fd_;
|
||||
bool ok_;
|
||||
string err_;
|
||||
}; // class FileLock
|
||||
|
||||
}// namespace limonp
|
||||
|
||||
#endif // LIMONP_FILELOCK_HPP
|
7
deps/limonp/ForcePublic.hpp
vendored
7
deps/limonp/ForcePublic.hpp
vendored
@ -1,7 +0,0 @@
|
||||
#ifndef LIMONP_FORCE_PUBLIC_H
|
||||
#define LIMONP_FORCE_PUBLIC_H
|
||||
|
||||
#define private public
|
||||
#define protected public
|
||||
|
||||
#endif // LIMONP_FORCE_PUBLIC_H
|
139
deps/limonp/LocalVector.hpp
vendored
139
deps/limonp/LocalVector.hpp
vendored
@ -1,139 +0,0 @@
|
||||
#ifndef LIMONP_LOCAL_VECTOR_HPP
|
||||
#define LIMONP_LOCAL_VECTOR_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace limonp {
|
||||
using namespace std;
|
||||
/*
|
||||
* LocalVector<T> : T must be primitive type (char , int, size_t), if T is struct or class, LocalVector<T> may be dangerous..
|
||||
* LocalVector<T> is simple and not well-tested.
|
||||
*/
|
||||
const size_t LOCAL_VECTOR_BUFFER_SIZE = 16;
|
||||
template <class T>
|
||||
class LocalVector {
|
||||
public:
|
||||
typedef const T* const_iterator ;
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
private:
|
||||
T buffer_[LOCAL_VECTOR_BUFFER_SIZE];
|
||||
T * ptr_;
|
||||
size_t size_;
|
||||
size_t capacity_;
|
||||
public:
|
||||
LocalVector() {
|
||||
init_();
|
||||
};
|
||||
LocalVector(const LocalVector<T>& vec) {
|
||||
init_();
|
||||
*this = vec;
|
||||
}
|
||||
LocalVector(const_iterator begin, const_iterator end) { // TODO: make it faster
|
||||
init_();
|
||||
while(begin != end) {
|
||||
push_back(*begin++);
|
||||
}
|
||||
}
|
||||
LocalVector(size_t size, const T& t) { // TODO: make it faster
|
||||
init_();
|
||||
while(size--) {
|
||||
push_back(t);
|
||||
}
|
||||
}
|
||||
~LocalVector() {
|
||||
if(ptr_ != buffer_) {
|
||||
free(ptr_);
|
||||
}
|
||||
};
|
||||
public:
|
||||
LocalVector<T>& operator = (const LocalVector<T>& vec) {
|
||||
clear();
|
||||
size_ = vec.size();
|
||||
capacity_ = vec.capacity();
|
||||
if(vec.buffer_ == vec.ptr_) {
|
||||
memcpy(buffer_, vec.buffer_, sizeof(T) * size_);
|
||||
ptr_ = buffer_;
|
||||
} else {
|
||||
ptr_ = (T*) malloc(vec.capacity() * sizeof(T));
|
||||
assert(ptr_);
|
||||
memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
void init_() {
|
||||
ptr_ = buffer_;
|
||||
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;
|
||||
}
|
||||
void reserve(size_t size) {
|
||||
if(size <= capacity_) {
|
||||
return;
|
||||
}
|
||||
T * next = (T*)malloc(sizeof(T) * size);
|
||||
assert(next);
|
||||
T * old = ptr_;
|
||||
ptr_ = next;
|
||||
memcpy(ptr_, old, sizeof(T) * capacity_);
|
||||
capacity_ = size;
|
||||
if(old != buffer_) {
|
||||
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_();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
ostream & operator << (ostream& os, const LocalVector<T>& vec) {
|
||||
if(vec.empty()) {
|
||||
return os << "[]";
|
||||
}
|
||||
os<<"[\""<<vec[0];
|
||||
for(size_t i = 1; i < vec.size(); i++) {
|
||||
os<<"\", \""<<vec[i];
|
||||
}
|
||||
os<<"\"]";
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
76
deps/limonp/Logging.hpp
vendored
76
deps/limonp/Logging.hpp
vendored
@ -1,76 +0,0 @@
|
||||
#ifndef LIMONP_LOGGING_HPP
|
||||
#define LIMONP_LOGGING_HPP
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef XLOG
|
||||
#error "XLOG has been defined already"
|
||||
#endif // XLOG
|
||||
#ifdef XCHECK
|
||||
#error "XCHECK has been defined already"
|
||||
#endif // XCHECK
|
||||
|
||||
#define XLOG(level) limonp::Logger(limonp::LL_##level, __FILE__, __LINE__).Stream()
|
||||
#define XCHECK(exp) if(!(exp)) XLOG(FATAL) << "exp: ["#exp << "] false. "
|
||||
|
||||
namespace limonp {
|
||||
|
||||
enum {
|
||||
LL_DEBUG = 0,
|
||||
LL_INFO = 1,
|
||||
LL_WARNING = 2,
|
||||
LL_ERROR = 3,
|
||||
LL_FATAL = 4,
|
||||
}; // enum
|
||||
|
||||
static const char * LOG_LEVEL_ARRAY[] = {"DEBUG","INFO","WARN","ERROR","FATAL"};
|
||||
static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
Logger(size_t level, const char* filename, int lineno)
|
||||
: level_(level) {
|
||||
#ifdef LOGGING_LEVEL
|
||||
if (level_ < LOGGING_LEVEL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
assert(level_ <= sizeof(LOG_LEVEL_ARRAY)/sizeof(*LOG_LEVEL_ARRAY));
|
||||
char buf[32];
|
||||
time_t now;
|
||||
time(&now);
|
||||
strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&now));
|
||||
stream_ << buf
|
||||
<< " " << filename
|
||||
<< ":" << lineno
|
||||
<< " " << LOG_LEVEL_ARRAY[level_]
|
||||
<< " ";
|
||||
}
|
||||
~Logger() {
|
||||
#ifdef LOGGING_LEVEL
|
||||
if (level_ < LOGGING_LEVEL) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
std::cerr << stream_.str() << std::endl;
|
||||
if (level_ == LL_FATAL) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& Stream() {
|
||||
return stream_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostringstream stream_;
|
||||
size_t level_;
|
||||
}; // class Logger
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_LOGGING_HPP
|
411
deps/limonp/Md5.hpp
vendored
411
deps/limonp/Md5.hpp
vendored
@ -1,411 +0,0 @@
|
||||
#ifndef __MD5_H__
|
||||
#define __MD5_H__
|
||||
|
||||
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
// rights reserved.
|
||||
|
||||
// License to copy and use this software is granted provided that it
|
||||
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
// Algorithm" in all material mentioning or referencing this software
|
||||
// or this function.
|
||||
//
|
||||
// License is also granted to make and use derivative works provided
|
||||
// that such works are identified as "derived from the RSA Data
|
||||
// Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
// mentioning or referencing the derived work.
|
||||
//
|
||||
// RSA Data Security, Inc. makes no representations concerning either
|
||||
// the merchantability of this software or the suitability of this
|
||||
// software for any particular purpose. It is provided "as is"
|
||||
// without express or implied warranty of any kind.
|
||||
//
|
||||
// These notices must be retained in any copies of any part of this
|
||||
// documentation and/or software.
|
||||
|
||||
|
||||
|
||||
// The original md5 implementation avoids external libraries.
|
||||
// This version has dependency on stdio.h for file input and
|
||||
// string.h for memcpy.
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
namespace limonp {
|
||||
|
||||
//#pragma region MD5 defines
|
||||
// Constants for MD5Transform routine.
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
// ROTATE_LEFT rotates x left n bits.
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
//#pragma endregion
|
||||
|
||||
|
||||
typedef unsigned char BYTE ;
|
||||
|
||||
// POINTER defines a generic pointer type
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
// UINT2 defines a two byte word
|
||||
typedef unsigned short int UINT2;
|
||||
|
||||
// UINT4 defines a four byte word
|
||||
typedef unsigned int UINT4;
|
||||
|
||||
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,
|
||||
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
|
||||
// the C-functions for use in C++ only
|
||||
class MD5 {
|
||||
private:
|
||||
struct __context_t {
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
} context ;
|
||||
|
||||
//#pragma region static helper functions
|
||||
// The core of the MD5 algorithm is here.
|
||||
// MD5 basic transformation. Transforms state based on block.
|
||||
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];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
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
|
||||
// a multiple of 4.
|
||||
static void Decode( UINT4 *output, unsigned char *input, unsigned int len ) {
|
||||
unsigned int i, j;
|
||||
|
||||
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
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
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) {
|
||||
if (NULL == str) {
|
||||
res = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
const char *pRes = md5.digestString(str);
|
||||
if (NULL == pRes) {
|
||||
res = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
res = pRes;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool md5File(const char* filepath, std::string& res) {
|
||||
if (NULL == filepath || strcmp(filepath, "") == 0) {
|
||||
res = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
const char *pRes = md5.digestFile(filepath);
|
||||
|
||||
if (NULL == pRes) {
|
||||
res = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
res = pRes;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
51
deps/limonp/MutexLock.hpp
vendored
51
deps/limonp/MutexLock.hpp
vendored
@ -1,51 +0,0 @@
|
||||
#ifndef LIMONP_MUTEX_LOCK_HPP
|
||||
#define LIMONP_MUTEX_LOCK_HPP
|
||||
|
||||
#include <pthread.h>
|
||||
#include "NonCopyable.hpp"
|
||||
#include "Logging.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
class MutexLock: NonCopyable {
|
||||
public:
|
||||
MutexLock() {
|
||||
XCHECK(!pthread_mutex_init(&mutex_, NULL));
|
||||
}
|
||||
~MutexLock() {
|
||||
XCHECK(!pthread_mutex_destroy(&mutex_));
|
||||
}
|
||||
pthread_mutex_t* GetPthreadMutex() {
|
||||
return &mutex_;
|
||||
}
|
||||
|
||||
private:
|
||||
void Lock() {
|
||||
XCHECK(!pthread_mutex_lock(&mutex_));
|
||||
}
|
||||
void Unlock() {
|
||||
XCHECK(!pthread_mutex_unlock(&mutex_));
|
||||
}
|
||||
friend class MutexLockGuard;
|
||||
|
||||
pthread_mutex_t mutex_;
|
||||
}; // class MutexLock
|
||||
|
||||
class MutexLockGuard: NonCopyable {
|
||||
public:
|
||||
explicit MutexLockGuard(MutexLock & mutex)
|
||||
: mutex_(mutex) {
|
||||
mutex_.Lock();
|
||||
}
|
||||
~MutexLockGuard() {
|
||||
mutex_.Unlock();
|
||||
}
|
||||
private:
|
||||
MutexLock & mutex_;
|
||||
}; // class MutexLockGuard
|
||||
|
||||
#define MutexLockGuard(x) XCHECK(false);
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_MUTEX_LOCK_HPP
|
21
deps/limonp/NonCopyable.hpp
vendored
21
deps/limonp/NonCopyable.hpp
vendored
@ -1,21 +0,0 @@
|
||||
/************************************
|
||||
************************************/
|
||||
#ifndef LIMONP_NONCOPYABLE_H
|
||||
#define LIMONP_NONCOPYABLE_H
|
||||
|
||||
namespace limonp {
|
||||
|
||||
class NonCopyable {
|
||||
protected:
|
||||
NonCopyable() {
|
||||
}
|
||||
~NonCopyable() {
|
||||
}
|
||||
private:
|
||||
NonCopyable(const NonCopyable& );
|
||||
const NonCopyable& operator=(const NonCopyable& );
|
||||
}; // class NonCopyable
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_NONCOPYABLE_H
|
157
deps/limonp/StdExtension.hpp
vendored
157
deps/limonp/StdExtension.hpp
vendored
@ -1,157 +0,0 @@
|
||||
#ifndef LIMONP_STD_EXTEMSION_HPP
|
||||
#define LIMONP_STD_EXTEMSION_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#elif(__cplusplus >= 201103L)
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#elif defined _MSC_VER
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#else
|
||||
#include <tr1/unordered_map>
|
||||
#include <tr1/unordered_set>
|
||||
namespace std {
|
||||
using std::tr1::unordered_map;
|
||||
using std::tr1::unordered_set;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename T>
|
||||
ostream& operator << (ostream& os, const vector<T>& v) {
|
||||
if(v.empty()) {
|
||||
return os << "[]";
|
||||
}
|
||||
os<<"["<<v[0];
|
||||
for(size_t i = 1; i < v.size(); i++) {
|
||||
os<<", "<<v[i];
|
||||
}
|
||||
os<<"]";
|
||||
return os;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ostream& operator << (ostream& os, const vector<string>& v) {
|
||||
if(v.empty()) {
|
||||
return os << "[]";
|
||||
}
|
||||
os<<"[\""<<v[0];
|
||||
for(size_t i = 1; i < v.size(); i++) {
|
||||
os<<"\", \""<<v[i];
|
||||
}
|
||||
os<<"\"]";
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ostream& operator << (ostream& os, const deque<T>& dq) {
|
||||
if(dq.empty()) {
|
||||
return os << "[]";
|
||||
}
|
||||
os<<"[\""<<dq[0];
|
||||
for(size_t i = 1; i < dq.size(); i++) {
|
||||
os<<"\", \""<<dq[i];
|
||||
}
|
||||
os<<"\"]";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template<class T1, class T2>
|
||||
ostream& operator << (ostream& os, const pair<T1, T2>& pr) {
|
||||
os << pr.first << ":" << pr.second ;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
string& operator << (string& str, const T& obj) {
|
||||
stringstream ss;
|
||||
ss << obj; // call ostream& operator << (ostream& os,
|
||||
return str = ss.str();
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
ostream& operator << (ostream& os, const map<T1, T2>& mp) {
|
||||
if(mp.empty()) {
|
||||
os<<"{}";
|
||||
return os;
|
||||
}
|
||||
os<<'{';
|
||||
typename map<T1, T2>::const_iterator it = mp.begin();
|
||||
os<<*it;
|
||||
it++;
|
||||
while(it != mp.end()) {
|
||||
os<<", "<<*it;
|
||||
it++;
|
||||
}
|
||||
os<<'}';
|
||||
return os;
|
||||
}
|
||||
template<class T1, class T2>
|
||||
ostream& operator << (ostream& os, const std::unordered_map<T1, T2>& mp) {
|
||||
if(mp.empty()) {
|
||||
return os << "{}";
|
||||
}
|
||||
os<<'{';
|
||||
typename std::unordered_map<T1, T2>::const_iterator it = mp.begin();
|
||||
os<<*it;
|
||||
it++;
|
||||
while(it != mp.end()) {
|
||||
os<<", "<<*it++;
|
||||
}
|
||||
return os<<'}';
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ostream& operator << (ostream& os, const set<T>& st) {
|
||||
if(st.empty()) {
|
||||
os << "{}";
|
||||
return os;
|
||||
}
|
||||
os<<'{';
|
||||
typename set<T>::const_iterator it = st.begin();
|
||||
os<<*it;
|
||||
it++;
|
||||
while(it != st.end()) {
|
||||
os<<", "<<*it;
|
||||
it++;
|
||||
}
|
||||
os<<'}';
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class KeyType, class ContainType>
|
||||
bool IsIn(const ContainType& contain, const KeyType& key) {
|
||||
return contain.end() != contain.find(key);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
basic_string<T> & operator << (basic_string<T> & s, ifstream & ifs) {
|
||||
return s.assign((istreambuf_iterator<T>(ifs)), istreambuf_iterator<T>());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ofstream & operator << (ofstream & ofs, const basic_string<T>& s) {
|
||||
ostreambuf_iterator<T> itr (ofs);
|
||||
copy(s.begin(), s.end(), itr);
|
||||
return ofs;
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
365
deps/limonp/StringUtil.hpp
vendored
365
deps/limonp/StringUtil.hpp
vendored
@ -1,365 +0,0 @@
|
||||
/************************************
|
||||
* file enc : ascii
|
||||
* author : wuyanyi09@gmail.com
|
||||
************************************/
|
||||
#ifndef LIMONP_STR_FUNCTS_H
|
||||
#define LIMONP_STR_FUNCTS_H
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <memory.h>
|
||||
#include <functional>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <sys/types.h>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include "StdExtension.hpp"
|
||||
|
||||
namespace limonp {
|
||||
using namespace std;
|
||||
inline string StringFormat(const char* fmt, ...) {
|
||||
int size = 256;
|
||||
std::string str;
|
||||
va_list ap;
|
||||
while (1) {
|
||||
str.resize(size);
|
||||
va_start(ap, fmt);
|
||||
int n = vsnprintf((char *)str.c_str(), size, fmt, ap);
|
||||
va_end(ap);
|
||||
if (n > -1 && n < size) {
|
||||
str.resize(n);
|
||||
return str;
|
||||
}
|
||||
if (n > -1)
|
||||
size = n + 1;
|
||||
else
|
||||
size *= 2;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Join(T begin, T end, string& res, const string& connector) {
|
||||
if(begin == end) {
|
||||
return;
|
||||
}
|
||||
stringstream ss;
|
||||
ss<<*begin;
|
||||
begin++;
|
||||
while(begin != end) {
|
||||
ss << connector << *begin;
|
||||
begin ++;
|
||||
}
|
||||
res = ss.str();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
string Join(T begin, T end, const string& connector) {
|
||||
string res;
|
||||
Join(begin ,end, res, connector);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline string& Upper(string& str) {
|
||||
transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);
|
||||
return str;
|
||||
}
|
||||
|
||||
inline string& Lower(string& str) {
|
||||
transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower);
|
||||
return str;
|
||||
}
|
||||
|
||||
inline bool IsSpace(unsigned c) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
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))));
|
||||
return 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());
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::string& Trim(std::string &s) {
|
||||
return LTrim(RTrim(s));
|
||||
}
|
||||
|
||||
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))));
|
||||
return s;
|
||||
}
|
||||
|
||||
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());
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::string& Trim(std::string &s, char x) {
|
||||
return LTrim(RTrim(s, x), x);
|
||||
}
|
||||
|
||||
inline void Split(const string& src, vector<string>& res, const string& pattern, size_t maxsplit = string::npos) {
|
||||
res.clear();
|
||||
size_t Start = 0;
|
||||
size_t end = 0;
|
||||
string sub;
|
||||
while(Start < src.size()) {
|
||||
end = src.find_first_of(pattern, Start);
|
||||
if(string::npos == end || res.size() >= maxsplit) {
|
||||
sub = src.substr(Start);
|
||||
res.push_back(sub);
|
||||
return;
|
||||
}
|
||||
sub = src.substr(Start, end - Start);
|
||||
res.push_back(sub);
|
||||
Start = end + 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
inline vector<string> Split(const string& src, const string& pattern, size_t maxsplit = string::npos) {
|
||||
vector<string> res;
|
||||
Split(src, res, pattern, maxsplit);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline bool StartsWith(const string& str, const string& prefix) {
|
||||
if(prefix.length() > str.length()) {
|
||||
return false;
|
||||
}
|
||||
return 0 == str.compare(0, prefix.length(), prefix);
|
||||
}
|
||||
|
||||
inline bool EndsWith(const string& str, const string& suffix) {
|
||||
if(suffix.length() > str.length()) {
|
||||
return false;
|
||||
}
|
||||
return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix);
|
||||
}
|
||||
|
||||
inline bool IsInStr(const string& str, char ch) {
|
||||
return str.find(ch) != string::npos;
|
||||
}
|
||||
|
||||
inline uint16_t TwocharToUint16(char high, char low) {
|
||||
return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff));
|
||||
}
|
||||
|
||||
template <class Uint16Container>
|
||||
bool Utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) {
|
||||
if(!str) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Uint16Container>
|
||||
bool Utf8ToUnicode(const string& str, Uint16Container& vec) {
|
||||
return Utf8ToUnicode(str.c_str(), str.size(), vec);
|
||||
}
|
||||
|
||||
template <class Uint32Container>
|
||||
bool Utf8ToUnicode32(const string& str, Uint32Container& vec) {
|
||||
uint32_t tmp;
|
||||
vec.clear();
|
||||
for(size_t i = 0; i < str.size();) {
|
||||
if(!(str[i] & 0x80)) { // 0xxxxxxx
|
||||
// 7bit, total 7bit
|
||||
tmp = (uint8_t)(str[i]) & 0x7f;
|
||||
i++;
|
||||
} else if ((uint8_t)str[i] <= 0xdf && i + 1 < str.size()) { // 110xxxxxx
|
||||
// 5bit, total 5bit
|
||||
tmp = (uint8_t)(str[i]) & 0x1f;
|
||||
|
||||
// 6bit, total 11bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
||||
i += 2;
|
||||
} else if((uint8_t)str[i] <= 0xef && i + 2 < str.size()) { // 1110xxxxxx
|
||||
// 4bit, total 4bit
|
||||
tmp = (uint8_t)(str[i]) & 0x0f;
|
||||
|
||||
// 6bit, total 10bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
||||
|
||||
// 6bit, total 16bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+2]) & 0x3f;
|
||||
|
||||
i += 3;
|
||||
} else if((uint8_t)str[i] <= 0xf7 && i + 3 < str.size()) { // 11110xxxx
|
||||
// 3bit, total 3bit
|
||||
tmp = (uint8_t)(str[i]) & 0x07;
|
||||
|
||||
// 6bit, total 9bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+1]) & 0x3f;
|
||||
|
||||
// 6bit, total 15bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+2]) & 0x3f;
|
||||
|
||||
// 6bit, total 21bit
|
||||
tmp <<= 6;
|
||||
tmp |= (uint8_t)(str[i+3]) & 0x3f;
|
||||
|
||||
i += 4;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
vec.push_back(tmp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Uint32ContainerConIter>
|
||||
void Unicode32ToUtf8(Uint32ContainerConIter begin, Uint32ContainerConIter end, string& res) {
|
||||
res.clear();
|
||||
uint32_t ui;
|
||||
while(begin != end) {
|
||||
ui = *begin;
|
||||
if(ui <= 0x7f) {
|
||||
res += char(ui);
|
||||
} else if(ui <= 0x7ff) {
|
||||
res += char(((ui >> 6) & 0x1f) | 0xc0);
|
||||
res += char((ui & 0x3f) | 0x80);
|
||||
} else if(ui <= 0xffff) {
|
||||
res += char(((ui >> 12) & 0x0f) | 0xe0);
|
||||
res += char(((ui >> 6) & 0x3f) | 0x80);
|
||||
res += char((ui & 0x3f) | 0x80);
|
||||
} else {
|
||||
res += char(((ui >> 18) & 0x03) | 0xf0);
|
||||
res += char(((ui >> 12) & 0x3f) | 0x80);
|
||||
res += char(((ui >> 6) & 0x3f) | 0x80);
|
||||
res += char((ui & 0x3f) | 0x80);
|
||||
}
|
||||
begin ++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Uint16ContainerConIter>
|
||||
void UnicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
||||
res.clear();
|
||||
uint16_t ui;
|
||||
while(begin != end) {
|
||||
ui = *begin;
|
||||
if(ui <= 0x7f) {
|
||||
res += char(ui);
|
||||
} else if(ui <= 0x7ff) {
|
||||
res += char(((ui>>6) & 0x1f) | 0xc0);
|
||||
res += char((ui & 0x3f) | 0x80);
|
||||
} else {
|
||||
res += char(((ui >> 12) & 0x0f )| 0xe0);
|
||||
res += char(((ui>>6) & 0x3f )| 0x80 );
|
||||
res += char((ui & 0x3f) | 0x80);
|
||||
}
|
||||
begin ++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Uint16Container>
|
||||
bool GBKTrans(const char* const str, size_t len, Uint16Container& vec) {
|
||||
vec.clear();
|
||||
if(!str) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Uint16Container>
|
||||
bool GBKTrans(const string& str, Uint16Container& vec) {
|
||||
return GBKTrans(str.c_str(), str.size(), vec);
|
||||
}
|
||||
|
||||
template <class Uint16ContainerConIter>
|
||||
void GBKTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
|
||||
res.clear();
|
||||
//pair<char, char> pa;
|
||||
char first, second;
|
||||
while(begin != end) {
|
||||
//pa = uint16ToChar2(*begin);
|
||||
first = ((*begin)>>8) & 0x00ff;
|
||||
second = (*begin) & 0x00ff;
|
||||
if(first & 0x80) {
|
||||
res += first;
|
||||
res += second;
|
||||
} else {
|
||||
res += second;
|
||||
}
|
||||
begin++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* format example: "%Y-%m-%d %H:%M:%S"
|
||||
*/
|
||||
inline void GetTime(const string& format, string& timeStr) {
|
||||
time_t timeNow;
|
||||
time(&timeNow);
|
||||
timeStr.resize(64);
|
||||
size_t len = strftime((char*)timeStr.c_str(), timeStr.size(), format.c_str(), localtime(&timeNow));
|
||||
timeStr.resize(len);
|
||||
}
|
||||
|
||||
inline string PathJoin(const string& path1, const string& path2) {
|
||||
if(EndsWith(path1, "/")) {
|
||||
return path1 + path2;
|
||||
}
|
||||
return path1 + "/" + path2;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
44
deps/limonp/Thread.hpp
vendored
44
deps/limonp/Thread.hpp
vendored
@ -1,44 +0,0 @@
|
||||
#ifndef LIMONP_THREAD_HPP
|
||||
#define LIMONP_THREAD_HPP
|
||||
|
||||
#include "Logging.hpp"
|
||||
#include "NonCopyable.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
class IThread: NonCopyable {
|
||||
public:
|
||||
IThread(): isStarted(false), isJoined(false) {
|
||||
}
|
||||
virtual ~IThread() {
|
||||
if(isStarted && !isJoined) {
|
||||
XCHECK(!pthread_detach(thread_));
|
||||
}
|
||||
};
|
||||
|
||||
virtual void Run() = 0;
|
||||
void Start() {
|
||||
XCHECK(!isStarted);
|
||||
XCHECK(!pthread_create(&thread_, NULL, Worker, this));
|
||||
isStarted = true;
|
||||
}
|
||||
void Join() {
|
||||
XCHECK(!isJoined);
|
||||
XCHECK(!pthread_join(thread_, NULL));
|
||||
isJoined = true;
|
||||
}
|
||||
private:
|
||||
static void * Worker(void * data) {
|
||||
IThread * ptr = (IThread* ) data;
|
||||
ptr->Run();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_t thread_;
|
||||
bool isStarted;
|
||||
bool isJoined;
|
||||
}; // class IThread
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_THREAD_HPP
|
86
deps/limonp/ThreadPool.hpp
vendored
86
deps/limonp/ThreadPool.hpp
vendored
@ -1,86 +0,0 @@
|
||||
#ifndef LIMONP_THREAD_POOL_HPP
|
||||
#define LIMONP_THREAD_POOL_HPP
|
||||
|
||||
#include "Thread.hpp"
|
||||
#include "BlockingQueue.hpp"
|
||||
#include "BoundedBlockingQueue.hpp"
|
||||
#include "Closure.hpp"
|
||||
|
||||
namespace limonp {
|
||||
|
||||
using namespace std;
|
||||
|
||||
//class ThreadPool;
|
||||
class ThreadPool: NonCopyable {
|
||||
public:
|
||||
class Worker: public IThread {
|
||||
public:
|
||||
Worker(ThreadPool* pool): ptThreadPool_(pool) {
|
||||
assert(ptThreadPool_);
|
||||
}
|
||||
virtual ~Worker() {
|
||||
}
|
||||
|
||||
virtual void Run() {
|
||||
while (true) {
|
||||
ClosureInterface* closure = ptThreadPool_->queue_.Pop();
|
||||
if (closure == NULL) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
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)
|
||||
: threads_(thread_num),
|
||||
queue_(thread_num) {
|
||||
assert(thread_num);
|
||||
for(size_t i = 0; i < threads_.size(); i ++) {
|
||||
threads_[i] = new Worker(this);
|
||||
}
|
||||
}
|
||||
~ThreadPool() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Start() {
|
||||
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();
|
||||
}
|
||||
|
||||
void Add(ClosureInterface* task) {
|
||||
assert(task);
|
||||
queue_.Push(task);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Worker;
|
||||
|
||||
vector<IThread*> threads_;
|
||||
BoundedBlockingQueue<ClosureInterface*> queue_;
|
||||
}; // class ThreadPool
|
||||
|
||||
} // namespace limonp
|
||||
|
||||
#endif // LIMONP_THREAD_POOL_HPP
|
Loading…
x
Reference in New Issue
Block a user