├── .gitignore ├── README.md ├── cpp_inc ├── astar.h ├── buffer_view.h ├── coroutine_default_sche.h ├── coroutine_helper.h ├── cpp_compiler_define.h ├── heap_timer.h ├── lexical_cast.h ├── misc.h ├── std_any_pointer_guard.h └── string_helper.h ├── inc ├── all.h ├── compiler_define.h ├── component │ ├── dataqueue.h │ ├── log.h │ ├── memheap_mt.h │ ├── memref.h │ ├── net_channel_ex.h │ ├── net_reactor.h │ ├── rbtimer.h │ ├── stack_co_sche.h │ └── switch_co_sche.h ├── crt │ ├── cXML.h │ ├── dynarr.h │ ├── json.h │ ├── protocol │ │ ├── hiredis_cli_protocol.h │ │ ├── httpframe.h │ │ └── websocketframe.h │ └── string.h ├── datastruct │ ├── arrheap.h │ ├── base64.h │ ├── bstree.h │ ├── graph.h │ ├── hash.h │ ├── hashtable.h │ ├── lengthfieldframe.h │ ├── list.h │ ├── md5.h │ ├── memfunc.h │ ├── memheap.h │ ├── random.h │ ├── rbtree.h │ ├── sha1.h │ ├── transport_ctx.h │ ├── tree.h │ └── url.h ├── platform_define.h └── sysapi │ ├── aio.h │ ├── assert.h │ ├── atomic.h │ ├── error.h │ ├── file.h │ ├── io_overlapped.h │ ├── ipc.h │ ├── misc.h │ ├── mmap.h │ ├── module.h │ ├── nio.h │ ├── process.h │ ├── socket.h │ ├── statistics.h │ ├── terminal.h │ └── time.h ├── lib_compile.sh ├── makefile └── src ├── component ├── dataqueue.c ├── log.c ├── memheap_mt.c ├── memref.c ├── net_channel_ex.c ├── net_reactor.c ├── rbtimer.c ├── stack_co_sche.c └── switch_co_sche.c ├── crt ├── cXML.c ├── dynarr.c ├── json.c ├── protocol │ ├── hiredis_cli_protocol.c │ ├── httpframe.c │ └── websocketframe.c └── string.c ├── datastruct ├── base64.c ├── bstree.c ├── graph.c ├── hash.c ├── hashtable.c ├── lengthfieldframe.c ├── list.c ├── md5.c ├── memfunc.c ├── memheap.c ├── random.c ├── rbtree.c ├── sha1.c ├── transport_ctx.c ├── tree.c └── url.c └── sysapi ├── aio.c ├── error.c ├── file.c ├── io_overlapped.c ├── ipc.c ├── misc.c ├── mmap.c ├── module.c ├── nio.c ├── process.c ├── socket.c ├── statistics.c ├── terminal.c ├── time.c └── win32_misc.c /.gitignore: -------------------------------------------------------------------------------- 1 | .gitattributes 2 | *.a 3 | *.so 4 | .xmake 5 | build 6 | tags 7 | /*.dSYM 8 | /x64 9 | /Debug 10 | /Release -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # util工具库,C/C++代码分离,可运行于linux/windows/macOS平台,可直接集成到项目中,或抽取部分文件使用. 2 | 设计原则:单一接口和模块尽可能做到绝对原子和功能分层设计,绝不做不属于它本身的事情(例如绝不把协程与io混为一个大模块,协程就是协程,io就是io). 3 | 4 | util/ 5 | .gitignore 用于git忽略一些无用文件 6 | makefile unix系统编译动态链接库 7 | lib_compile.sh unix系统编译静态链接库脚本 8 | 9 | CPP部分 10 | cpp_inc/ 11 | astar 基于格子和邻接点的A*寻路算法 12 | coroutine_default_sche.h 基于C++20的无栈协程调度器,nodejs风格 13 | coroutine_helper.h 基于C++20的无栈协程结构定义,nodejs风格 14 | cpp_compiler_define 判断编译器当前指定的CPP版本 15 | heap_timer 基于标准库堆结构实现的定时器 16 | lexical_cast 简陋但可用的通用类型转换接口 17 | misc 一些无法归类的,方便兼容C风格的 18 | string_helper 一些简陋的字符串分割和to_string方法 19 | 20 | 纯C部分 21 | inc/ 22 | all 自动include所有库内头文件 23 | compiler_define 根据编译器不同,给出统一的关键字,定一缺失类型,必须的预处理语句,频闭不需要的警告等 24 | platform_define 根据系统平台的不同,给出统一的关键字,定义缺失类型,必须的预处理语句,频闭不需要的警告等 25 | 26 | component/ 27 | net_channel_rw 基于下面的reactor模块提供TCP/UDP传输,并发的可靠UDP传输与监听 28 | dataqueue 用于线程间通信的消息队列 29 | log 用于日志读写,支持异步/同步写入文件,且内置日志轮替机制 30 | memheap_mt 基于共享内存的多进程/线程安全的内存管理 31 | memref 基于引用计数实现的内存强引用和观察者 32 | reactor Reactor模型的网络套接字库 33 | rbtimer 一个基于红黑树结构的定时器模块 34 | stack_co_sche 基于系统平台API实现的有栈协程调度器 35 | switch_co_sche 基于switch case语法的无栈协程调度器 36 | crt/ 37 | protocol/ 38 | hiredis_cli_protocol 基于hiredis代码的裁剪,只保留了客户端对RESP协议解析和构造部分 39 | httpframe 用于解析与组装HTTP协议报文 40 | websocketframe 用于解析与组装WebSocket协议报文(13版本) 41 | cXML 用于解析XML 42 | dynarr 模拟泛型的动态数组 43 | json 用于解析JSON,沿用cJSON的命名风格,内部采用和cJSON不同的实现方式 44 | math 一些实用的数学运算接口 45 | datastruct/ 46 | arrheap 最小堆,最大堆 47 | base64 提供base64编解码接口 48 | bstree 类型无关的二叉搜索树 49 | hash 提供一些常用的hash算法 50 | hashtable 类型无关的哈希表 51 | lengthfieldframe 用于解析与组装包含长度字段的协议报文 52 | list 类型无关的双向链表,顺带支持栈/队列的PUSH/POP操作 53 | md5 MD5编码生成 54 | memfunc 不涉及分配释放的内存与字符串操作函数 55 | memheap 简单内存堆分配与释放 56 | random 随机数算法,提供rand48与MT19937算法 57 | rbtree 类型无关的红黑树(内部基于linux内核红黑树代码) 58 | serial_exec 任务串行执行队列结构 59 | sha1 SHA1编解码,来源于Redis源码 60 | transport_ctx 提供ACK确认与滑动窗口的传输控制接口,不包含OS对应的IO系统接口,并于标准库无关 61 | tree 类型无关的普通树 62 | url URL解析与编解码接口 63 | sysapi/ 64 | aio 提供统一AIO接口(基于iocp/io_uring) 65 | assert 提供一个相对于assert的高级断言 66 | atomic 提供统一的原子操作接口 67 | error 提供统一的系统错误码接口 68 | file 提供统一的文件与目录操作接口 69 | io_overlapped 提供OVERLAPPED结构与接口,用于NIO/AIO 70 | ipc 提供统一的OS锁接口 71 | misc 杂项接口 72 | mmap 提供统一的文件内存映射与共享内存接口 73 | nio 提供统一网络NIO接口(基于iocp/epoll/kevent,reactor模式) 74 | process 提供统一的进程/线程/协程接口 75 | socket 提供统一的socket接口 76 | statistics 一些杂项统计接口 77 | terminal 提供终端控制台的操作接口 78 | time 提供统一的线程安全的时间接口 79 | -------------------------------------------------------------------------------- /cpp_inc/astar.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 20-11-9. 3 | // 4 | 5 | #ifndef UTIL_CPP_ASTAR_H 6 | #define UTIL_CPP_ASTAR_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace util { 17 | class AStarWalkImpl; 18 | 19 | class AStarNodeBase { 20 | friend class AStarWalkImpl; 21 | public: 22 | AStarNodeBase() : from(NULL), g(0), h(0), f(0) {} 23 | virtual ~AStarNodeBase() {} 24 | 25 | static bool openheapCompare(const AStarNodeBase* a, const AStarNodeBase* b) { return a->f > b->f; } 26 | 27 | public: 28 | AStarNodeBase* from; 29 | int g, h, f; 30 | }; 31 | 32 | template 33 | class AStarNode : public AStarNodeBase { 34 | public: 35 | AStarNode() : AStarNodeBase() {} 36 | AStarNode(const Element& v) : AStarNodeBase(), e(v) {} 37 | 38 | public: 39 | Element e; 40 | }; 41 | 42 | class AStarWalkImpl { 43 | public: 44 | AStarWalkImpl() : m_cur_search_num(0), m_max_search_num(-1) {} 45 | virtual ~AStarWalkImpl() {} 46 | 47 | void setMaxSearchNum(size_t num) { 48 | m_max_search_num = num; 49 | if (m_max_search_num != -1) { 50 | m_openheap.reserve(m_max_search_num); 51 | } 52 | } 53 | 54 | bool reachMaxSearch() const { 55 | return m_cur_search_num >= m_max_search_num && m_max_search_num != -1; 56 | } 57 | 58 | bool addOpenHeap(AStarNodeBase* node, AStarNodeBase* from_node) { 59 | if (m_cur_search_num < m_max_search_num) { 60 | m_cur_search_num++; 61 | } 62 | else if (m_max_search_num != -1) { 63 | return false; 64 | } 65 | node->f = node->h + node->g; 66 | node->from = from_node; 67 | m_openheap.push_back(node); 68 | std::push_heap(m_openheap.begin(), m_openheap.end(), AStarNodeBase::openheapCompare); 69 | return true; 70 | } 71 | 72 | AStarNodeBase* popOpenHeap() { 73 | if (m_openheap.empty()) { 74 | return NULL; 75 | } 76 | AStarNodeBase* next_node = m_openheap.front(); 77 | std::pop_heap(m_openheap.begin(), m_openheap.end(), AStarNodeBase::openheapCompare); 78 | m_openheap.pop_back(); 79 | return next_node; 80 | } 81 | 82 | protected: 83 | size_t m_cur_search_num; 84 | size_t m_max_search_num; 85 | std::vector m_openheap; 86 | }; 87 | 88 | template > 89 | class AStarWalkBase : public AStarWalkImpl { 90 | public: 91 | void doStart(const NodeId_t& start_node_id) { 92 | m_closeset.clear(); 93 | m_closeset.insert(start_node_id); 94 | m_openheap.resize(0); 95 | m_cur_search_num = 0; 96 | } 97 | 98 | bool useNodeId(const NodeId_t& id) { 99 | return m_closeset.insert(id).second; 100 | } 101 | 102 | private: 103 | std::unordered_set m_closeset; 104 | }; 105 | 106 | ////////////////////////////////////////////////////////////////////////////// 107 | 108 | template 109 | struct AStarPoint2D { 110 | union { 111 | T v[2]; 112 | struct { 113 | T x; 114 | T y; 115 | }; 116 | }; 117 | 118 | AStarPoint2D() : x(0), y(0) {} 119 | AStarPoint2D(T px, T py) : x(px), y(py) {} 120 | 121 | bool operator==(const AStarPoint2D& p) const { 122 | return this->x == p.x && this->y == p.y; 123 | } 124 | bool operator!=(const AStarPoint2D& p) const { 125 | return this->x != p.x || this->y != p.y; 126 | } 127 | T getManhattanDistance(const AStarPoint2D& p) const { 128 | T deltaX = this->x - p.x; 129 | T deltaY = this->y - p.y; 130 | return std::abs(this->x - p.x) + std::abs(this->y - p.y); 131 | } 132 | }; 133 | 134 | template > 135 | class AStarNode_Grid2D : public AStarNodeBase { 136 | public: 137 | AStarNode_Grid2D() : util::AStarNodeBase() {} 138 | AStarNode_Grid2D(T x, T y) : util::AStarNodeBase(), p(x, y) {} 139 | 140 | public: 141 | static void merge(const AStarNode_Grid2D* end_node, std::list& poslist) { 142 | if (!end_node) { 143 | return; 144 | } 145 | std::list templist; 146 | templist.push_front(end_node->p); 147 | const AStarNode_Grid2D* prev_node = end_node; 148 | T dx = 0; 149 | T dy = 0; 150 | for (const AStarNode_Grid2D* node = (const AStarNode_Grid2D*)end_node->from; 151 | node; node = (const AStarNode_Grid2D*)node->from) 152 | { 153 | int new_dx = node->p.x - prev_node->p.x; 154 | int new_dy = node->p.y - prev_node->p.y; 155 | if (new_dx != dx || new_dy != dy) { 156 | dx = new_dx; 157 | dy = new_dy; 158 | templist.push_front(node->p); 159 | } 160 | else { 161 | templist.front() = node->p; 162 | } 163 | prev_node = node; 164 | } 165 | poslist.splice(poslist.end(), templist); 166 | } 167 | 168 | public: 169 | Point2D p; 170 | }; 171 | } 172 | 173 | namespace std { 174 | template 175 | struct hash > { 176 | typedef util::AStarPoint2D argument_type; 177 | typedef size_t result_type; 178 | 179 | result_type operator()(const argument_type& p) const noexcept { return p.x + p.y; } 180 | }; 181 | } 182 | 183 | #endif 184 | -------------------------------------------------------------------------------- /cpp_inc/buffer_view.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 25-1-20 3 | // 4 | 5 | #ifndef UTIL_CPP_BUFFER_VIEW_H 6 | #define UTIL_CPP_BUFFER_VIEW_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace util { 13 | struct buffer_view { 14 | buffer_view() : m_ptr(NULL), m_length(0) {} 15 | buffer_view(const void* ptr, size_t length) { 16 | if (ptr && length) { 17 | m_ptr = (char*)ptr; 18 | m_length = length; 19 | } 20 | else { 21 | m_ptr = NULL; 22 | m_length = 0; 23 | } 24 | } 25 | 26 | bool valid(size_t off, size_t len) const { 27 | return off < m_length && len < m_length - off; 28 | } 29 | 30 | template 31 | size_t read(size_t off, T* v) const { 32 | if (!valid(off, sizeof(T))) { 33 | return -1; 34 | } 35 | *v = *(T*)(m_ptr + off); 36 | return off + sizeof(T); 37 | } 38 | 39 | size_t read(size_t off, void* p, size_t len) const { 40 | if (!valid(off, len)) { 41 | return -1; 42 | } 43 | memcpy(p, m_ptr + off, len); 44 | return off + len; 45 | } 46 | 47 | size_t read(size_t off, std::string* v, size_t len) const { 48 | if (!valid(off, len)) { 49 | return -1; 50 | } 51 | v->assign(m_ptr + off, len); 52 | return off + len; 53 | } 54 | 55 | size_t read(size_t off, std::vector* v, size_t len) const { 56 | if (!valid(off, len)) { 57 | return -1; 58 | } 59 | v->resize(len); 60 | memcpy(v->data(), m_ptr + off, len); 61 | return off + len; 62 | } 63 | 64 | size_t read(size_t off, std::vector* v, size_t len) const { 65 | if (!valid(off, len)) { 66 | return -1; 67 | } 68 | v->resize(len); 69 | memcpy(v->data(), m_ptr + off, len); 70 | return off + len; 71 | } 72 | 73 | template 74 | size_t write(size_t off, const T& v) const { 75 | if (!valid(off, sizeof(T))) { 76 | return -1; 77 | } 78 | *(T*)(m_ptr + off) = v; 79 | return off + sizeof(T); 80 | } 81 | 82 | size_t write(size_t off, const void* p, size_t len) const { 83 | if (!valid(off, len)) { 84 | return -1; 85 | } 86 | memcpy(m_ptr + off, p, len); 87 | return off + len; 88 | } 89 | 90 | size_t write(size_t off, const std::string& v) const { 91 | return write(off, v.data(), v.size()); 92 | } 93 | 94 | size_t write(size_t off, const std::vector& v) const { 95 | return write(off, v.data(), v.size()); 96 | } 97 | 98 | size_t write(size_t off, const std::vector& v) const { 99 | return write(off, v.data(), v.size()); 100 | } 101 | 102 | private: 103 | char* m_ptr; 104 | size_t m_length; 105 | }; 106 | } 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /cpp_inc/cpp_compiler_define.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_CPP_CPP_COMPILER_DEFINE_H 6 | #define UTIL_CPP_CPP_COMPILER_DEFINE_H 7 | 8 | #ifdef __cplusplus 9 | 10 | #include "../inc/compiler_define.h" 11 | 12 | #ifdef _MSC_VER 13 | #ifndef __CPP_VERSION 14 | #define __CPP_VERSION _MSVC_LANG 15 | #endif 16 | #else 17 | #ifndef __CPP_VERSION 18 | #define __CPP_VERSION __cplusplus 19 | #endif 20 | #endif 21 | 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /cpp_inc/heap_timer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 20-11-9. 3 | // 4 | 5 | #ifndef UTIL_CPP_HEAP_TIMER_H 6 | #define UTIL_CPP_HEAP_TIMER_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace util { 13 | class HeapTimer; 14 | class HeapTimerEvent; 15 | typedef std::function HeapTimerFunction; 16 | 17 | class HeapTimerEvent { 18 | friend class HeapTimer; 19 | public: 20 | HeapTimerEvent(const HeapTimerFunction& f = nullptr) : 21 | m_ptrSched(nullptr), 22 | m_timer(nullptr), 23 | m_timestamp(0), 24 | m_func(f) 25 | {} 26 | 27 | virtual ~HeapTimerEvent() { detach(); } 28 | 29 | int64_t timestamp() const { return m_timestamp; } 30 | 31 | const HeapTimerFunction& func() const { return m_func; } 32 | void set_func(const HeapTimerFunction& f) { m_func = f; } 33 | 34 | void callback() { 35 | if (m_func) { 36 | m_func(m_timer, this); 37 | } 38 | } 39 | 40 | bool sched() const { return m_ptrSched != nullptr; } 41 | 42 | void detach() { 43 | if (m_ptrSched) { 44 | *m_ptrSched = nullptr; 45 | m_ptrSched = nullptr; 46 | m_timer = nullptr; 47 | } 48 | } 49 | 50 | private: 51 | HeapTimerEvent(const HeapTimerEvent&) {} 52 | HeapTimerEvent& operator=(const HeapTimerEvent&) { return *this; } 53 | 54 | private: 55 | HeapTimerEvent** m_ptrSched; 56 | HeapTimer* m_timer; 57 | int64_t m_timestamp; 58 | HeapTimerFunction m_func; 59 | }; 60 | 61 | class HeapTimer { 62 | public: 63 | HeapTimer() {} 64 | 65 | virtual ~HeapTimer() { clearEvents(); } 66 | 67 | HeapTimerEvent* setEvent(const HeapTimerFunction& f, int64_t timestamp) { 68 | if (timestamp < 0) { 69 | return nullptr; 70 | } 71 | HeapTimerEvent* e = new HeapTimerEvent(f); 72 | try { 73 | if (!setEvent(e, timestamp)) { 74 | delete e; 75 | return nullptr; 76 | } 77 | return e; 78 | } 79 | catch (...) { 80 | delete e; 81 | return nullptr; 82 | } 83 | } 84 | 85 | bool setEvent(HeapTimerEvent* e, int64_t timestamp) { 86 | if (timestamp < 0) { 87 | return false; 88 | } 89 | if (e->m_ptrSched) { 90 | if (e->m_timer != this) { 91 | return false; 92 | } 93 | if (e->m_timestamp != timestamp) { 94 | e->m_timestamp = timestamp; 95 | std::make_heap(m_eventHeap.begin(), m_eventHeap.end(), heapCompare); 96 | } 97 | } 98 | else { 99 | e->m_timestamp = timestamp; 100 | HeapTimerEvent** ep = new HeapTimerEvent*(e); 101 | try { 102 | m_eventHeap.push_back(ep); 103 | std::push_heap(m_eventHeap.begin(), m_eventHeap.end(), heapCompare); 104 | } 105 | catch (...) { 106 | delete ep; 107 | return false; 108 | } 109 | e->m_timer = this; 110 | e->m_ptrSched = ep; 111 | } 112 | return true; 113 | } 114 | 115 | void clearEvents() { 116 | for (size_t i = 0; i < m_eventHeap.size(); ++i) { 117 | HeapTimerEvent** ep = m_eventHeap[i]; 118 | HeapTimerEvent* e = *ep; 119 | if (e) { 120 | e->m_timer = nullptr; 121 | e->m_ptrSched = nullptr; 122 | } 123 | delete ep; 124 | } 125 | m_eventHeap.clear(); 126 | } 127 | 128 | HeapTimerEvent* popTimeoutEvent(int64_t timestamp) { 129 | while (!m_eventHeap.empty()) { 130 | HeapTimerEvent** ep = m_eventHeap.front(); 131 | HeapTimerEvent* e = *ep; 132 | if (e && e->m_timestamp > timestamp) { 133 | break; 134 | } 135 | std::pop_heap(m_eventHeap.begin(), m_eventHeap.end(), heapCompare); 136 | m_eventHeap.pop_back(); 137 | delete ep; 138 | if (!e) { 139 | continue; 140 | } 141 | e->m_ptrSched = nullptr; 142 | return e; 143 | } 144 | return nullptr; 145 | } 146 | 147 | int64_t getNextTimestamp() { 148 | while (!m_eventHeap.empty()) { 149 | HeapTimerEvent** ep = m_eventHeap.front(); 150 | HeapTimerEvent* e = *ep; 151 | if (e) { 152 | return e->m_timestamp; 153 | } 154 | std::pop_heap(m_eventHeap.begin(), m_eventHeap.end(), heapCompare); 155 | m_eventHeap.pop_back(); 156 | delete ep; 157 | } 158 | return -1; 159 | } 160 | 161 | private: 162 | HeapTimer(const HeapTimer&) {} 163 | HeapTimer& operator=(const HeapTimer&) { return *this; } 164 | 165 | static bool heapCompare(HeapTimerEvent** ap, HeapTimerEvent** bp) { 166 | return (*ap ? (*ap)->m_timestamp : 0) > ( *bp ? (*bp)->m_timestamp : 0); 167 | } 168 | 169 | private: 170 | std::vector m_eventHeap; 171 | }; 172 | } 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /cpp_inc/lexical_cast.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 19-10-21. 3 | // 4 | 5 | #ifndef UTIL_CPP_LEXICAL_CAST_H 6 | #define UTIL_CPP_LEXICAL_CAST_H 7 | 8 | #include 9 | #include 10 | 11 | namespace util { 12 | class bad_lexical_cast : public std::bad_cast { 13 | public: 14 | virtual const char* what(void) const throw() { 15 | return "bad lexical cast: source type could not be interpreted as target type"; 16 | } 17 | }; 18 | 19 | template 20 | T lexical_cast(const F& f) { 21 | std::stringstream ss; 22 | ss << f; 23 | if (!ss) 24 | throw bad_lexical_cast(); 25 | T t; 26 | ss >> t; 27 | if (!ss) 28 | throw bad_lexical_cast(); 29 | return t; 30 | } 31 | 32 | template 33 | T lexical_cast_nothrow(const F& f) { 34 | std::stringstream ss; 35 | ss << f; 36 | if (!ss) 37 | return T(); 38 | T t; 39 | ss >> t; 40 | if (!ss) 41 | return T(); 42 | return t; 43 | } 44 | 45 | template 46 | bool lexical_cast(const F& f, T& t) { 47 | std::stringstream ss; 48 | ss << f; 49 | if (!ss) 50 | return false; 51 | ss >> t; 52 | if (!ss) 53 | return false; 54 | return true; 55 | } 56 | } 57 | 58 | #endif // !UTIL_CPP_LEXICAL_CAST_H 59 | -------------------------------------------------------------------------------- /cpp_inc/misc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 22-3-16 3 | // 4 | 5 | #ifndef UTIL_CPP_MISC_H 6 | #define UTIL_CPP_MISC_H 7 | 8 | #include 9 | 10 | namespace util { 11 | template 12 | struct cstruct_raii : public T { 13 | cstruct_raii() {} 14 | cstruct_raii(int ch) { 15 | memset((T*)this, ch, sizeof(T)); 16 | } 17 | ~cstruct_raii() { 18 | Deleter(this); 19 | } 20 | }; 21 | 22 | template 23 | void delete_fn(void* p) { delete (T*)p; } 24 | template 25 | void delete_fn(T* p) { delete p; } 26 | template 27 | void delete_arr_fn(T* p) { delete [] p; } 28 | template 29 | void delete_arr_fn(void* p) { delete [] (T*)p; } 30 | template 31 | void free_fn(T* p) { free((void*)p); } 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /cpp_inc/std_any_pointer_guard.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 24-9-7. 3 | // 4 | 5 | #ifndef UTIL_CPP_STD_ANY_POINTER_GUARD_H 6 | #define UTIL_CPP_STD_ANY_POINTER_GUARD_H 7 | 8 | #include 9 | #include 10 | 11 | namespace util { 12 | class StdAnyPointerGuard { 13 | private: 14 | template 15 | struct Impl { 16 | Impl(T* v, void(*dt)(T*)) : m_v(v), m_dt(dt) {} 17 | Impl(const Impl& other) : m_v(other.m_v), m_dt(other.m_dt) 18 | { 19 | (const_cast(other)).m_v = nullptr; 20 | } 21 | ~Impl() { 22 | if (m_v) { 23 | m_dt(m_v); 24 | } 25 | } 26 | Impl& operator=(const Impl&) = delete; 27 | 28 | T* m_v; 29 | void(*m_dt)(T*); 30 | }; 31 | 32 | public: 33 | template 34 | static std::unique_ptr transfer_unique_ptr(const std::any& a) { 35 | auto& g = const_cast&>(std::any_cast&>(a)); 36 | std::unique_ptr p(g.m_v, g.m_dt); 37 | g.m_v = nullptr; 38 | (const_cast(a)).reset(); 39 | return p; 40 | } 41 | 42 | template 43 | static std::any to_any(T* v, void(*dt)(T*)) { 44 | return std::any(Impl(v, dt)); 45 | } 46 | }; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /cpp_inc/string_helper.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 20-2-22. 3 | // 4 | 5 | #ifndef UTIL_CPP_STRING_HELPER_H 6 | #define UTIL_CPP_STRING_HELPER_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace util { 16 | class string { 17 | public: 18 | static void split(const char* str, int delim, std::vector& v) { 19 | const char* p; 20 | for (p = str; *str; ++str) { 21 | if (delim == *str) { 22 | v.push_back(std::string(p, str - p)); 23 | p = str + 1; 24 | } 25 | } 26 | if (str != p) { 27 | v.push_back(std::string(p, str - p)); 28 | } 29 | } 30 | 31 | static void split(const char* str, const char* delim, std::vector& v) { 32 | const char* p, *dp; 33 | for (p = str; *str; ++str) { 34 | for (dp = delim; *dp; ++dp) { 35 | if (*dp == *str) { 36 | v.push_back(std::string(p, str - p)); 37 | p = str + 1; 38 | break; 39 | } 40 | } 41 | } 42 | if (str != p) { 43 | v.push_back(std::string(p, str - p)); 44 | } 45 | } 46 | 47 | static void splits(const char* str, const char* delim, std::vector& v) { 48 | const char* p; 49 | size_t delim_len = strlen(delim); 50 | while ((p = strstr(str, delim))) { 51 | v.push_back(std::string(str, p - str)); 52 | str = p + delim_len; 53 | } 54 | if (*str) { 55 | v.push_back(str); 56 | } 57 | } 58 | 59 | static std::string format(const char* format, ...) { 60 | char test_buf; 61 | char* buf; 62 | int len; 63 | va_list varg; 64 | va_start(varg, format); 65 | len = vsnprintf(&test_buf, 0, format, varg); 66 | va_end(varg); 67 | if (len <= 0) { 68 | return std::string(); 69 | } 70 | buf = (char*)malloc(len + 1); 71 | if (!buf) { 72 | return std::string(); 73 | } 74 | va_start(varg, format); 75 | len = vsnprintf(buf, len + 1, format, varg); 76 | va_end(varg); 77 | if (len <= 0) { 78 | free(buf); 79 | return std::string(); 80 | } 81 | std::string s(buf, len); 82 | free(buf); 83 | return s; 84 | } 85 | }; 86 | } 87 | 88 | #endif // !UTIL_CPP_STRING_HELPER_H 89 | -------------------------------------------------------------------------------- /inc/all.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_ALL_H 6 | #define UTIL_C_ALL_H 7 | 8 | #include "compiler_define.h" 9 | #include "platform_define.h" 10 | #include "datastruct/arrheap.h" 11 | #include "datastruct/base64.h" 12 | #include "datastruct/bstree.h" 13 | #include "datastruct/graph.h" 14 | #include "datastruct/hash.h" 15 | #include "datastruct/hashtable.h" 16 | #include "datastruct/lengthfieldframe.h" 17 | #include "datastruct/list.h" 18 | #include "datastruct/md5.h" 19 | #include "datastruct/memfunc.h" 20 | #include "datastruct/memheap.h" 21 | #include "datastruct/random.h" 22 | #include "datastruct/rbtree.h" 23 | #include "datastruct/sha1.h" 24 | #include "datastruct/transport_ctx.h" 25 | #include "datastruct/tree.h" 26 | #include "datastruct/url.h" 27 | #include "crt/cXML.h" 28 | #include "crt/dynarr.h" 29 | #include "crt/json.h" 30 | #include "crt/string.h" 31 | #include "crt/protocol/hiredis_cli_protocol.h" 32 | #include "crt/protocol/httpframe.h" 33 | #include "crt/protocol/websocketframe.h" 34 | #include "sysapi/aio.h" 35 | #include "sysapi/assert.h" 36 | #include "sysapi/atomic.h" 37 | #include "sysapi/error.h" 38 | #include "sysapi/file.h" 39 | #include "sysapi/io_overlapped.h" 40 | #include "sysapi/ipc.h" 41 | #include "sysapi/misc.h" 42 | #include "sysapi/mmap.h" 43 | #include "sysapi/module.h" 44 | #include "sysapi/nio.h" 45 | #include "sysapi/process.h" 46 | #include "sysapi/socket.h" 47 | #include "sysapi/statistics.h" 48 | #include "sysapi/terminal.h" 49 | #include "sysapi/time.h" 50 | #include "component/net_channel_ex.h" 51 | #include "component/dataqueue.h" 52 | #include "component/log.h" 53 | #include "component/memheap_mt.h" 54 | #include "component/memref.h" 55 | #include "component/rbtimer.h" 56 | #include "component/net_reactor.h" 57 | #include "component/stack_co_sche.h" 58 | #include "component/switch_co_sche.h" 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /inc/compiler_define.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_COMPILER_DEFINE_H 6 | #define UTIL_C_COMPILER_DEFINE_H 7 | 8 | #define __MACRO_TOSTRING(m) #m 9 | #define __MACRO_APPEND(m1, m2) m1##m2 10 | 11 | #define MACRO_TOSTRING(m) __MACRO_TOSTRING(m) 12 | #define MACRO_APPEND(m1, m2) __MACRO_APPEND(m1, m2) 13 | 14 | #ifndef STATIC_ASSERT 15 | #define STATIC_ASSERT(exp,msg) typedef char MACRO_APPEND(__static_assert_line, __LINE__)[(exp) ? 1 : -1] 16 | #endif 17 | STATIC_ASSERT(sizeof(char) == 1, ""); 18 | STATIC_ASSERT(sizeof(signed char) == 1, ""); 19 | STATIC_ASSERT(sizeof(unsigned char) == 1, ""); 20 | STATIC_ASSERT(sizeof(short) == 2, ""); 21 | STATIC_ASSERT(sizeof(unsigned short) == 2, ""); 22 | STATIC_ASSERT(sizeof(int) == 4, ""); 23 | STATIC_ASSERT(sizeof(unsigned int) == 4, ""); 24 | STATIC_ASSERT(sizeof(long long) == 8, ""); 25 | STATIC_ASSERT(sizeof(unsigned long long) == 8, ""); 26 | 27 | #define field_sizeof(type, field) sizeof(((type*)0)->field) 28 | #define pod_offsetof(type, field) ((char*)(&((type *)0)->field) - (char*)(0)) 29 | #define pod_container_of(address, type, field) ((type *)((char*)(address) - (char*)(&((type *)0)->field))) 30 | 31 | #ifdef _MSC_VER 32 | #pragma warning(disable:4200) 33 | #pragma warning(disable:4018) 34 | #pragma warning(disable:4244) 35 | #pragma warning(disable:4267) 36 | #pragma warning(disable:4800) 37 | #pragma warning(disable:4819) 38 | #pragma warning(disable:4996) 39 | #pragma warning(disable:6255) 40 | #pragma warning(disable:26451) 41 | 42 | #define __declspec_align(alignment) __declspec(align(alignment)) 43 | 44 | #define __declspec_code_seg(name) __declspec(code_seg(name)) 45 | #define __declspec_data_seg(name) __pragma(data_seg(name)) 46 | #define __declspec_bss_seg(name) __pragma(bss_seg(name)) 47 | #define __declspec_const_seg(name) __pragma(const_seg(name)) 48 | 49 | #define __declspec_dllexport __declspec(dllexport) 50 | #define __declspec_dllimport __declspec(dllimport) 51 | 52 | #ifdef DECLSPEC_DLL_EXPORT 53 | #define __declspec_dll __declspec_dllexport 54 | #elif DECLSPEC_DLL_IMPORT 55 | #define __declspec_dll __declspec_dllimport 56 | #else 57 | #define __declspec_dll 58 | #endif 59 | 60 | #define __declspec_noinline __declspec(noinline) 61 | 62 | #ifdef _WIN64 63 | typedef __int64 SignedPtr_t; 64 | typedef unsigned __int64 UnsignedPtr_t; 65 | #elif _WIN32 66 | typedef __int32 SignedPtr_t; 67 | typedef unsigned __int32 UnsignedPtr_t; 68 | #endif 69 | STATIC_ASSERT(sizeof(SignedPtr_t) == sizeof(void*), ""); 70 | STATIC_ASSERT(sizeof(UnsignedPtr_t) == sizeof(void*), ""); 71 | 72 | #elif defined(__GNUC__) || defined(__GNUG__) 73 | #ifndef NDEBUG /* ANSI define */ 74 | #ifndef _DEBUG 75 | #define _DEBUG /* same as VC */ 76 | #endif 77 | #else 78 | #undef _DEBUG /* same as VC */ 79 | #endif 80 | 81 | #define __declspec_align(alignment) __attribute__ ((aligned(alignment))) 82 | 83 | #define __declspec_code_seg(name) __attribute__((section(name))) 84 | #define __declspec_data_seg(name) __attribute__((section(name))) 85 | #define __declspec_bss_seg(name) __attribute__((section(name))) 86 | #define __declspec_const_seg(name) __attribute__((section(name))) 87 | 88 | #define __declspec_dllexport __attribute__((visibility("default"))) 89 | #define __declspec_dllimport 90 | 91 | #ifdef DECLSPEC_DLL_EXPORT 92 | #define __declspec_dll __declspec_dllexport 93 | #elif DECLSPEC_DLL_IMPORT 94 | #define __declspec_dll __declspec_dllimport 95 | #else 96 | #define __declspec_dll 97 | #endif 98 | 99 | #define __declspec_noinline __attribute__ ((noinline)) 100 | 101 | STATIC_ASSERT(sizeof(long) == sizeof(void*), ""); 102 | STATIC_ASSERT(sizeof(unsigned long) == sizeof(void*), ""); 103 | typedef long SignedPtr_t; 104 | typedef unsigned long UnsignedPtr_t; 105 | #ifdef __clang__ 106 | #if __has_feature(address_sanitizer) 107 | #ifndef __SANITIZE_ADDRESS__ 108 | #define __SANITIZE_ADDRESS__ 109 | #endif 110 | #endif 111 | #endif 112 | 113 | #else 114 | #error "Unknown Compiler" 115 | #endif 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /inc/component/dataqueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_DATAQUEUE_H 6 | #define UTIL_C_COMPONENT_DATAQUEUE_H 7 | 8 | #include "../datastruct/list.h" 9 | #include "../sysapi/atomic.h" 10 | #include "../sysapi/ipc.h" 11 | 12 | typedef struct DataQueue_t { 13 | CriticalSection_t m_cslock; 14 | ConditionVariable_t m_condition; 15 | List_t m_datalist; 16 | Atom8_t m_wakeup; 17 | char m_initok; 18 | } DataQueue_t; 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | __declspec_dll DataQueue_t* dataqueueInit(DataQueue_t* dq); 25 | __declspec_dll void dataqueuePush(DataQueue_t* dq, ListNode_t* data); 26 | __declspec_dll void dataqueuePushList(DataQueue_t* dq, List_t* list); 27 | __declspec_dll ListNode_t* dataqueuePopWait(DataQueue_t* dq, int msec, size_t expect_cnt); 28 | __declspec_dll void dataqueueWake(DataQueue_t* dq); 29 | __declspec_dll ListNode_t* dataqueueClean(DataQueue_t* dq); 30 | __declspec_dll ListNode_t* dataqueueDestroy(DataQueue_t* dq); 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /inc/component/log.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_LOG_H 6 | #define UTIL_C_COMPONENT_LOG_H 7 | 8 | #include "../../inc/platform_define.h" 9 | #include 10 | #include 11 | 12 | struct Log_t; 13 | 14 | typedef struct LogItemInfo_t { 15 | const char* priority_str; 16 | const char* source_file; 17 | unsigned int source_line; 18 | struct tm dt; 19 | time_t timestamp_sec; 20 | } LogItemInfo_t; 21 | 22 | typedef struct LogFileRotateOption_t { 23 | int rotate_timelen_sec; 24 | const char*(*fn_new_fullpath)(const char* base_path, const char* key, const struct tm* dt); 25 | void(*fn_free_path)(char*); 26 | } LogFileRotateOption_t; 27 | 28 | typedef struct LogFileOutputOption_t { 29 | int(*fn_prefix_length)(const LogItemInfo_t*); 30 | void(*fn_sprintf_prefix)(char*, const LogItemInfo_t*); 31 | int async_output; 32 | } LogFileOutputOption_t; 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | __declspec_dll struct Log_t* logOpen(void); 39 | __declspec_dll struct Log_t* logEnableAsyncOuputThreads(struct Log_t* log, size_t thrd_cnt); 40 | __declspec_dll void logDestroy(struct Log_t* log); 41 | 42 | __declspec_dll struct Log_t* logEnableFile(struct Log_t* log, const char* key, const char* base_path, const LogFileOutputOption_t* output_opt, const LogFileRotateOption_t* rotate_opt); 43 | __declspec_dll const LogFileOutputOption_t* logFileOutputOptionDefault(void); 44 | __declspec_dll const LogFileRotateOption_t* logFileRotateOptionDefaultDay(void); 45 | __declspec_dll const LogFileRotateOption_t* logFileRotateOptionDefaultHour(void); 46 | __declspec_dll const LogFileRotateOption_t* logFileRotateOptionDefaultMinute(void); 47 | 48 | __declspec_dll int logFilterPriorityLess(int log_priority, int filter_priority); 49 | __declspec_dll int logFilterPriorityLessEqual(int log_priority, int filter_priority); 50 | __declspec_dll int logFilterPriorityGreater(int log_priority, int filter_priority); 51 | __declspec_dll int logFilterPriorityGreaterEqual(int log_priority, int filter_priority); 52 | __declspec_dll int logFilterPriorityEqual(int log_priority, int filter_priority); 53 | __declspec_dll int logFilterPriorityNotEqual(int log_priority, int filter_priority); 54 | __declspec_dll void logSetPriorityFilter(struct Log_t* log, int filter_priority, int(*fn_priority_filter)(int, int)); 55 | __declspec_dll int logCheckPriorityEnabled(struct Log_t* log, unsigned int priority); 56 | 57 | __declspec_dll void logPrintlnNoFilter(struct Log_t* log, const char* key, int priority, LogItemInfo_t* ii, const char* format, ...); 58 | 59 | #define logPrintlnTempletePrivate(log, key, priority, format, ...) \ 60 | if (logCheckPriorityEnabled(log, priority)) { \ 61 | LogItemInfo_t ii; \ 62 | ii.source_file = __FILE__; \ 63 | ii.source_line = __LINE__; \ 64 | logPrintlnNoFilter(log, key, priority, &ii, "" format, ##__VA_ARGS__); \ 65 | } 66 | 67 | #define logTrace(log, key, format, ...) logPrintlnTempletePrivate(log, key, 0, format, ##__VA_ARGS__) 68 | #define logInfo(log, key, format, ...) logPrintlnTempletePrivate(log, key, 1, format, ##__VA_ARGS__) 69 | #define logDebug(log, key, format, ...) logPrintlnTempletePrivate(log, key, 2, format, ##__VA_ARGS__) 70 | #define logError(log, key, format, ...) logPrintlnTempletePrivate(log, key, 3, format, ##__VA_ARGS__) 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /inc/component/memheap_mt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_MEMHEAP_MT_H 6 | #define UTIL_C_COMPONENT_MEMHEAP_MT_H 7 | 8 | #include "../../inc/sysapi/ipc.h" 9 | #include "../../inc/sysapi/mmap.h" 10 | 11 | struct MemHeap_t; 12 | 13 | typedef struct MemHeapMt_t { 14 | Semaphore_t seminit; 15 | Semaphore_t semlock; 16 | ShareMemMap_t mm; 17 | struct MemHeap_t* ptr; 18 | size_t len; 19 | short initok; 20 | short is_open; 21 | char* name_ext; 22 | size_t namelen; 23 | } MemHeapMt_t; 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | __declspec_dll MemHeapMt_t* memheapmtCreate(MemHeapMt_t* memheap, size_t len, const char* name); 30 | __declspec_dll MemHeapMt_t* memheapmtOpen(MemHeapMt_t* memheap, size_t len, const char* name); 31 | __declspec_dll void* memheapmtAlloc(MemHeapMt_t* memheap, size_t nbytes); 32 | __declspec_dll void memheapmtFree(MemHeapMt_t* memheap, void* addr); 33 | __declspec_dll void memheapmtClose(MemHeapMt_t* memheap); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif 38 | 39 | #endif -------------------------------------------------------------------------------- /inc/component/memref.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_MEMREF_H 6 | #define UTIL_C_COMPONENT_MEMREF_H 7 | 8 | #include "../../inc/platform_define.h" 9 | 10 | struct MemRef_t; 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | __declspec_dll struct MemRef_t* memrefCreate(void* p, void(*fn_free)(void*)); 17 | __declspec_dll void* memrefGetPtr(struct MemRef_t* ref); 18 | __declspec_dll struct MemRef_t* memrefIncr(struct MemRef_t* ref); 19 | __declspec_dll void memrefDecr(struct MemRef_t** p_ref); 20 | 21 | __declspec_dll struct MemRef_t* memrefLockWeak(struct MemRef_t* ref); 22 | __declspec_dll struct MemRef_t* memrefIncrWeak(struct MemRef_t* ref); 23 | __declspec_dll void memrefDecrWeak(struct MemRef_t** p_ref); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /inc/component/net_channel_ex.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 2019-7-11. 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_NET_CHANNEL_RW_H 6 | #define UTIL_C_COMPONENT_NET_CHANNEL_RW_H 7 | 8 | #include "net_reactor.h" 9 | 10 | typedef struct NetChannelInbufDecodeResult_t { 11 | char err; 12 | char incomplete; 13 | char fragment_eof; 14 | char pktype; 15 | char ignore; 16 | unsigned int pkseq; 17 | unsigned int decodelen; 18 | unsigned int bodylen; 19 | unsigned char* bodyptr; 20 | } NetChannelInbufDecodeResult_t; 21 | 22 | typedef struct NetChannelExProc_t { 23 | void(*on_decode)(struct NetChannel_t* channel, unsigned char* buf, size_t len, NetChannelInbufDecodeResult_t* result); 24 | void(*on_recv)(struct NetChannel_t* channel, unsigned char* bodyptr, size_t bodylen, const struct sockaddr* from_addr, socklen_t addrlen); 25 | void(*on_encode)(struct NetChannel_t* channel, NetPacket_t* packet); 26 | void(*on_reply_ack)(struct NetChannel_t* channel, unsigned int seq, const struct sockaddr* to_addr, socklen_t addrlen); 27 | } NetChannelExProc_t; 28 | 29 | typedef struct NetChannelExData_t { 30 | /* public */ 31 | struct { 32 | union { 33 | struct { /* listener use */ 34 | int halfconn_maxwaitcnt; 35 | int m_halfconn_curwaitcnt; 36 | }; 37 | struct { /* client or server use */ 38 | int m_synpacket_status; 39 | NetPacket_t* m_synpacket; 40 | }; 41 | }; 42 | struct { 43 | unsigned short rto; 44 | unsigned char resend_maxtimes; 45 | }; 46 | } dgram; 47 | 48 | const NetChannelExProc_t* proc; 49 | } NetChannelExData_t; 50 | 51 | typedef struct NetChannelExHookProc_t { 52 | int(*on_read)(NetChannel_t* channel, unsigned char* buf, unsigned int len, long long timestamp_msec, const struct sockaddr* from_addr, socklen_t addrlen); 53 | int(*on_pre_send)(NetChannel_t* channel, NetPacket_t* packet, long long timestamp_msec); 54 | void(*on_exec)(NetChannel_t* channel, long long timestamp_msec); 55 | void(*on_free)(NetChannel_t* channel); 56 | } NetChannelExHookProc_t; 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | __declspec_dll const NetChannelExHookProc_t* NetChannelEx_get_hook(int channel_flag, int socktype); 63 | __declspec_dll void NetChannelEx_init(NetChannel_t* channel, NetChannelExData_t* rw, const NetChannelExProc_t* rw_proc); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /inc/component/net_reactor.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 2019-07-14. 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_REACTOR_H 6 | #define UTIL_C_COMPONENT_REACTOR_H 7 | 8 | #include "../sysapi/nio.h" 9 | #include "../sysapi/io_overlapped.h" 10 | #include "../sysapi/ipc.h" 11 | #include "../sysapi/socket.h" 12 | #include "../datastruct/list.h" 13 | #include "../datastruct/transport_ctx.h" 14 | 15 | enum { 16 | NET_REACTOR_REG_ERR = 1, 17 | NET_REACTOR_IO_READ_ERR = 2, 18 | NET_REACTOR_IO_WRITE_ERR = 3, 19 | NET_REACTOR_IO_CONNECT_ERR = 4, 20 | NET_REACTOR_IO_ACCEPT_ERR = 5, 21 | NET_REACTOR_ZOMBIE_ERR = 6, 22 | NET_REACTOR_CACHE_READ_OVERFLOW_ERR = 7, 23 | NET_REACTOR_CACHE_WRITE_OVERFLOW_ERR = 8 24 | }; 25 | enum { 26 | NET_CHANNEL_SIDE_CLIENT = 1, 27 | NET_CHANNEL_SIDE_SERVER = 2, 28 | NET_CHANNEL_SIDE_LISTEN = 3 29 | }; 30 | 31 | struct NetReactor_t; 32 | struct NetChannel_t; 33 | 34 | typedef struct NetChannelSession_t { 35 | int type; 36 | struct NetChannel_t* channel; 37 | } NetChannelSession_t; 38 | 39 | typedef struct NetChannelProc_t { 40 | void(*on_exec)(struct NetChannel_t* self, long long timestamp_msec); /* optional */ 41 | /* return > 0 decode length, == 0 imcomplete, < 0 decode error */ 42 | int(*on_read)(struct NetChannel_t* self, unsigned char* buf, unsigned int len, long long timestamp_msec, const struct sockaddr* from_addr, socklen_t addrlen); 43 | unsigned int(*on_hdrsize)(struct NetChannel_t* self, unsigned int bodylen); /* optional */ 44 | int(*on_pre_send)(struct NetChannel_t* self, NetPacket_t* packet, long long timestamp_msec); /* optional */ 45 | void(*on_heartbeat)(struct NetChannel_t* self, int heartbeat_times); /* heartbeat_sender use, optional */ 46 | void(*on_detach)(struct NetChannel_t* self); 47 | void(*on_free)(struct NetChannel_t* self); /* optional */ 48 | } NetChannelProc_t; 49 | 50 | typedef struct NetReactorCmd_t { 51 | ListNode_t _; 52 | int type; 53 | } NetReactorCmd_t; 54 | 55 | typedef struct NetReactorPacket_t { 56 | NetReactorCmd_t cmd; 57 | struct NetChannel_t* channel; 58 | struct sockaddr* addr; 59 | socklen_t addrlen; 60 | NetPacket_t _; 61 | } NetReactorPacket_t; 62 | 63 | typedef struct NetReactorObject_t { 64 | /* public */ 65 | NioFD_t niofd; 66 | int inbuf_maxlen; 67 | char inbuf_saved; 68 | /* private */ 69 | struct NetChannel_t* m_channel; 70 | struct { 71 | long long m_connect_end_msec; 72 | ListNode_t m_connect_endnode; 73 | } stream; 74 | char m_connected; 75 | unsigned char* m_inbuf; 76 | int m_inbuflen; 77 | int m_inbufsize; 78 | } NetReactorObject_t; 79 | 80 | typedef struct NetChannel_t { 81 | /* public */ 82 | NetReactorObject_t* o; 83 | struct NetReactor_t* reactor; 84 | int domain; 85 | int socktype; 86 | int protocol; 87 | Sockaddr_t to_addr; 88 | socklen_t to_addrlen; 89 | int heartbeat_timeout_msec; /* optional, > 0 enable heartbeat */ 90 | short heartbeat_sender; /* optional, if true, will call proc.on_heartbeat */ 91 | unsigned short heartbeat_max_times; /* optional */ 92 | char has_recvfin; 93 | char has_sendfin; 94 | char valid; 95 | unsigned char write_fragment_with_hdr; 96 | unsigned short side; /* read-only, TCP must set this field */ 97 | short detach_error; 98 | long long event_msec; 99 | unsigned int write_fragment_size; 100 | unsigned int readcache_max_size; 101 | unsigned int sendcache_max_size; 102 | void* userdata; /* user use, library not use these field */ 103 | const struct NetChannelProc_t* proc; /* user use, set your IO callback */ 104 | NetChannelSession_t* session; /* user use, set your logic session status */ 105 | union { 106 | struct { /* listener use */ 107 | void(*on_ack_halfconn)(struct NetChannel_t* self, FD_t newfd, const struct sockaddr* peer_addr, socklen_t addrlen, long long ts_msec); 108 | Sockaddr_t listen_addr; 109 | socklen_t listen_addrlen; 110 | int listen_backlog; 111 | }; 112 | struct { /* client use */ 113 | void(*on_syn_ack)(struct NetChannel_t* self, long long timestamp_msec); /* optional */ 114 | Sockaddr_t connect_addr; 115 | socklen_t connect_addrlen; 116 | int connect_timeout_msec; /* optional */ 117 | }; 118 | }; 119 | /* private */ 120 | void* m_ext_impl; /* internal or other ext */ 121 | union { 122 | struct { 123 | StreamTransportCtx_t stream_ctx; 124 | int stream_writeev_wnd_bytes; 125 | NetReactorCmd_t m_stream_fincmd; 126 | char m_stream_delay_send_fin; 127 | }; 128 | DgramTransportCtx_t dgram_ctx; 129 | }; 130 | long long m_heartbeat_msec; 131 | unsigned short m_heartbeat_times; /* client use */ 132 | Atom32_t m_refcnt; 133 | char m_has_detached; 134 | char m_catch_fincmd; 135 | Atom8_t m_has_commit_fincmd; 136 | Atom8_t m_reghaspost; 137 | NetReactorCmd_t m_regcmd; 138 | NetReactorCmd_t m_freecmd; 139 | } NetChannel_t; 140 | 141 | #ifdef __cplusplus 142 | extern "C" { 143 | #endif 144 | 145 | __declspec_dll struct NetReactor_t* NetReactor_create(void); 146 | __declspec_dll void NetReactor_wake(struct NetReactor_t* reactor); 147 | __declspec_dll int NetReactor_handle(struct NetReactor_t* reactor, NioEv_t e[], int n, int wait_msec); 148 | __declspec_dll void NetReactor_destroy(struct NetReactor_t* reactor); 149 | 150 | __declspec_dll NetChannel_t* NetChannel_open(unsigned short side, const NetChannelProc_t* proc, int domain, int socktype, int protocol); 151 | __declspec_dll NetChannel_t* NetChannel_open_with_fd(unsigned short side, const NetChannelProc_t* proc, FD_t fd, int domain, int protocol); 152 | __declspec_dll NetChannel_t* NetChannel_set_operator_sockaddr(NetChannel_t* channel, const struct sockaddr* op_addr, socklen_t op_addrlen); 153 | __declspec_dll NetChannel_t* NetChannel_add_ref(NetChannel_t* channel); 154 | __declspec_dll void NetChannel_reg(struct NetReactor_t* reactor, NetChannel_t* channel); 155 | __declspec_dll void NetChannel_close_ref(NetChannel_t* channel); 156 | 157 | __declspec_dll void NetChannel_send_fin(NetChannel_t* channel); 158 | __declspec_dll void NetChannel_send(NetChannel_t* channel, const void* data, size_t len, int pktype, const struct sockaddr* to_addr, socklen_t to_addrlen); 159 | __declspec_dll void NetChannel_sendv(NetChannel_t* channel, const Iobuf_t iov[], unsigned int iovcnt, int pktype, const struct sockaddr* to_addr, socklen_t to_addrlen); 160 | 161 | #ifdef __cplusplus 162 | } 163 | #endif 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /inc/component/rbtimer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-24. 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_RBTIMER_H 6 | #define UTIL_C_COMPONENT_RBTIMER_H 7 | 8 | #include "../platform_define.h" 9 | #include "../datastruct/list.h" 10 | #include "../datastruct/rbtree.h" 11 | 12 | typedef struct RBTimer_t { 13 | /* private */ 14 | RBTree_t m_rbtree; 15 | void* m_first_evlist; 16 | } RBTimer_t; 17 | 18 | typedef struct RBTimerEvent_t { 19 | /* private */ 20 | ListNode_t m_listnode; 21 | struct RBTimer_t* m_timer; 22 | void* m_internal_evlist; 23 | /* public */ 24 | long long timestamp; /* read-only */ 25 | long long interval; 26 | void(*callback)(RBTimer_t*, struct RBTimerEvent_t*); 27 | void* arg; 28 | } RBTimerEvent_t; 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | __declspec_dll RBTimer_t* rbtimerInit(RBTimer_t* timer); 35 | __declspec_dll long long rbtimerMiniumTimestamp(RBTimer_t* timer); 36 | __declspec_dll RBTimerEvent_t* rbtimerSetEvent(RBTimer_t* timer, RBTimerEvent_t* e, long long timestamp); 37 | __declspec_dll BOOL rbtimerCheckEventScheduled(RBTimerEvent_t* e); 38 | __declspec_dll void rbtimerDetachEvent(RBTimerEvent_t* e); 39 | __declspec_dll RBTimerEvent_t* rbtimerTimeoutPopup(RBTimer_t* timer, long long timestamp); 40 | __declspec_dll void rbtimerDestroy(RBTimer_t* timer); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /inc/component/stack_co_sche.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 2022-10-30 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_STACK_CO_SCHE_H 6 | #define UTIL_C_COMPONENT_STACK_CO_SCHE_H 7 | 8 | #include "../compiler_define.h" 9 | #include "../datastruct/list.h" 10 | #include 11 | 12 | enum { 13 | STACK_CO_STATUS_CANCEL = -3, 14 | STACK_CO_STATUS_ERROR = -2, 15 | STACK_CO_STATUS_FINISH = -1, 16 | STACK_CO_STATUS_START = 0 17 | }; 18 | 19 | typedef struct StackCoAsyncParam_t { 20 | void* value; 21 | void(*fn_value_free)(void*); 22 | } StackCoAsyncParam_t; 23 | 24 | typedef struct StackCoBlock_t { 25 | int64_t id; /* unique id, user read only */ 26 | int status; /* switch status, user read only */ 27 | StackCoAsyncParam_t resume_param; /* resume param */ 28 | } StackCoBlock_t; 29 | 30 | typedef struct StackCoBlockGroup_t { 31 | /* user not visit these fields */ 32 | List_t wait_block_list; 33 | List_t ready_block_list; 34 | } StackCoBlockGroup_t; 35 | 36 | struct StackCoSche_t; 37 | struct StackCoLock_t; 38 | struct StackCoLockOwner_t; 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | __declspec_dll struct StackCoSche_t* StackCoSche_new(size_t stack_size, void* userdata); 45 | __declspec_dll void StackCoSche_destroy(struct StackCoSche_t* sche); 46 | __declspec_dll int StackCoSche_sche(struct StackCoSche_t* sche, int idle_msec); 47 | __declspec_dll void StackCoSche_wake_up(struct StackCoSche_t* sche); 48 | __declspec_dll void StackCoSche_exit(struct StackCoSche_t* sche); 49 | __declspec_dll void* StackCoSche_userdata(struct StackCoSche_t* sche); 50 | __declspec_dll void StackCoSche_set_handle_cnt(struct StackCoSche_t* sche, int handle_cnt); 51 | __declspec_dll int StackCoSche_has_exit(struct StackCoSche_t* sche); 52 | __declspec_dll void StackCoSche_at_exit(struct StackCoSche_t* sche, void(*fn_at_exit)(struct StackCoSche_t*, void*), void* arg, void(*fn_arg_free)(void*)); 53 | 54 | __declspec_dll int StackCoSche_function(struct StackCoSche_t* sche, void(*proc)(struct StackCoSche_t*, StackCoAsyncParam_t*), const StackCoAsyncParam_t* param); 55 | __declspec_dll int StackCoSche_timeout_util(struct StackCoSche_t* sche, long long tm_msec, void(*proc)(struct StackCoSche_t*, StackCoAsyncParam_t*), const StackCoAsyncParam_t* param); 56 | 57 | __declspec_dll StackCoBlock_t* StackCoSche_block_point_util(struct StackCoSche_t* sche, long long tm_msec, StackCoBlockGroup_t* group); 58 | __declspec_dll StackCoBlock_t* StackCoSche_sleep_util(struct StackCoSche_t* sche, long long tm_msec, StackCoBlockGroup_t* group); 59 | __declspec_dll void StackCoSche_resume_block_by_id(struct StackCoSche_t* sche, int64_t block_id, int status, const StackCoAsyncParam_t* param); 60 | 61 | __declspec_dll struct StackCoLockOwner_t* StackCoSche_new_lock_owner(const char* s, size_t slen); 62 | __declspec_dll struct StackCoLockOwner_t* StackCoSche_clone_lock_owner(const struct StackCoLockOwner_t* owner); 63 | __declspec_dll void StackCoSche_free_lock_owner(struct StackCoLockOwner_t* owner); 64 | __declspec_dll struct StackCoLock_t* StackCoSche_lock(struct StackCoSche_t* sche, const struct StackCoLockOwner_t* owner, const char* name); 65 | __declspec_dll struct StackCoLock_t* StackCoSche_try_lock(struct StackCoSche_t* sche, const struct StackCoLockOwner_t* owner, const char* name); 66 | __declspec_dll void StackCoSche_unlock(struct StackCoSche_t* sche, struct StackCoLock_t* lock); 67 | 68 | __declspec_dll StackCoBlock_t* StackCoSche_yield(struct StackCoSche_t* sche); 69 | __declspec_dll int StackCoSche_group_is_empty(StackCoBlockGroup_t* group); 70 | __declspec_dll StackCoBlock_t* StackCoSche_yield_group(struct StackCoSche_t* sche, StackCoBlockGroup_t* group); 71 | 72 | __declspec_dll void StackCoSche_cleanup_async_param(StackCoAsyncParam_t* ap); 73 | 74 | __declspec_dll void StackCoSche_reuse_block(struct StackCoSche_t* sche, StackCoBlock_t* block); 75 | __declspec_dll void StackCoSche_reuse_block_group(struct StackCoSche_t* sche, StackCoBlockGroup_t* group); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /inc/component/switch_co_sche.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 2022-10-30 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_SWITCH_CO_SCHE_H 6 | #define UTIL_C_COMPONENT_SWITCH_CO_SCHE_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | enum { 11 | SWITCH_STATUS_CANCEL = -3, 12 | SWITCH_STATUS_DOING = -2, 13 | SWITCH_STATUS_FINISH = -1, 14 | SWITCH_STATUS_START = 0 15 | }; 16 | 17 | typedef struct SwitchCo_t { 18 | int id; /* unique id, user read only */ 19 | int status; /* switch status, user read only */ 20 | void* ctx; /* hold routine execute context */ 21 | void(*fn_ctx_free)(void*); /* free execute context */ 22 | void* resume_ret; /* resume result, user read only */ 23 | struct SwitchCo_t* await_co; /* cache current async wait sub co, user read only */ 24 | } SwitchCo_t; 25 | 26 | struct SwitchCoSche_t; 27 | 28 | #define SwitchCo_code_begin_no_ctx(co) \ 29 | switch (co->status) { \ 30 | case SWITCH_STATUS_START: \ 31 | co->status = SWITCH_STATUS_DOING; \ 32 | do 33 | 34 | #define SwitchCo_code_begin(co, ctx, ctx_create_expr, fn_ctx_free) \ 35 | *(void**)&ctx = co->ctx; \ 36 | switch (co->status) { \ 37 | case SWITCH_STATUS_START: \ 38 | co->ctx = ctx_create_expr; \ 39 | if (!co->ctx) { \ 40 | co->status = SWITCH_STATUS_CANCEL; \ 41 | SwitchCoSche_reuse_co(sche, co); \ 42 | break; \ 43 | } \ 44 | co->fn_ctx_free = fn_ctx_free; \ 45 | *(void**)&ctx = co->ctx; \ 46 | co->status = SWITCH_STATUS_DOING; \ 47 | do 48 | 49 | #define SwitchCo_code_end(sche, co) \ 50 | while (0); \ 51 | default: \ 52 | if (SWITCH_STATUS_DOING == co->status) { \ 53 | co->status = SWITCH_STATUS_FINISH; \ 54 | } \ 55 | if (co->fn_ctx_free) { \ 56 | co->fn_ctx_free(co->ctx); \ 57 | co->fn_ctx_free = NULL; \ 58 | } \ 59 | SwitchCoSche_reuse_co(sche, co); \ 60 | } 61 | 62 | #define SwitchCo_yield(co) do { (co)->status = __COUNTER__ + 1; return; case __COUNTER__: (co)->status = SWITCH_STATUS_DOING; } while(0) 63 | 64 | #define SwitchCo_await_co(sche, co, child_co) \ 65 | do { \ 66 | if (SwitchCoSche_call_co(sche, child_co)->status < 0) \ 67 | break; \ 68 | SwitchCo_yield(co); \ 69 | } while (1) 70 | 71 | #define SwitchCo_await(sche, co, func_expr) \ 72 | do { \ 73 | co->await_co = SwitchCoSche_new_child_co(sche, co); \ 74 | do { \ 75 | func_expr; \ 76 | if (co->await_co->status < 0) \ 77 | break; \ 78 | SwitchCo_yield(co); \ 79 | } while (1); \ 80 | SwitchCoSche_reuse_co(sche, co->await_co); \ 81 | } while (0) 82 | 83 | #ifdef __cplusplus 84 | extern "C" { 85 | #endif 86 | 87 | __declspec_dll struct SwitchCoSche_t* SwitchCoSche_new(void* userdata); 88 | __declspec_dll void SwitchCoSche_destroy(struct SwitchCoSche_t* sche); 89 | __declspec_dll int SwitchCoSche_sche(struct SwitchCoSche_t* sche, int idle_msec); 90 | __declspec_dll void SwitchCoSche_wake_up(struct SwitchCoSche_t* sche); 91 | __declspec_dll void SwitchCoSche_exit(struct SwitchCoSche_t* sche); 92 | __declspec_dll void* SwitchCoSche_userdata(struct SwitchCoSche_t* sche); 93 | __declspec_dll void SwitchCoSche_at_exit(struct SwitchCoSche_t* sche, void(*fn_at_exit)(struct SwitchCoSche_t*, void*), void* arg, void(*fn_arg_free)(void*)); 94 | 95 | __declspec_dll SwitchCo_t* SwitchCoSche_root_function(struct SwitchCoSche_t* sche, void(*proc)(struct SwitchCoSche_t*, SwitchCo_t*, void*), void* arg, void(*fn_arg_free)(void*)); 96 | __declspec_dll SwitchCo_t* SwitchCoSche_timeout_util(struct SwitchCoSche_t* sche, long long tm_msec, void(*proc)(struct SwitchCoSche_t*, SwitchCo_t*, void*), void* arg, void(*fn_arg_free)(void*)); 97 | __declspec_dll SwitchCo_t* SwitchCoSche_new_child_co(struct SwitchCoSche_t* sche, SwitchCo_t* parent_co); 98 | __declspec_dll SwitchCo_t* SwitchCoSche_sleep_util(struct SwitchCoSche_t* sche, SwitchCo_t* parent_co, long long tm_msec); 99 | __declspec_dll SwitchCo_t* SwitchCoSche_block_point_util(struct SwitchCoSche_t* sche, SwitchCo_t* parent_co, long long tm_msec); 100 | 101 | __declspec_dll void SwitchCoSche_no_arg_free(SwitchCo_t* co); 102 | __declspec_dll void* SwitchCoSche_pop_resume_ret(SwitchCo_t* co); 103 | __declspec_dll void SwitchCoSche_reuse_co(struct SwitchCoSche_t* sche, SwitchCo_t* co); 104 | __declspec_dll SwitchCo_t* SwitchCoSche_call_co(struct SwitchCoSche_t* sche, SwitchCo_t* co); 105 | __declspec_dll void SwitchCoSche_resume_co_by_id(struct SwitchCoSche_t* sche, int co_id, int status, void* ret, void(*fn_ret_free)(void*)); 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /inc/crt/cXML.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_CRT_XML_H 6 | #define UTIL_C_CRT_XML_H 7 | 8 | #include "../compiler_define.h" 9 | #include 10 | 11 | struct cXML_t; 12 | 13 | typedef struct cXMLAttr_t { 14 | char* name; 15 | char* value; 16 | size_t szname; 17 | size_t szvalue; 18 | 19 | struct cXMLAttr_t *prev, *next; 20 | struct cXML_t* node; 21 | int deep_copy; 22 | int need_free; 23 | } cXMLAttr_t; 24 | 25 | typedef struct cXML_t { 26 | char* name; 27 | char* content; 28 | size_t szname; 29 | size_t szcontent; 30 | unsigned int numattr; 31 | unsigned int numchild; 32 | int deep_copy; 33 | int need_free; 34 | 35 | struct cXML_t* parent; 36 | struct cXML_t* child; 37 | struct cXML_t* left; 38 | struct cXML_t* right; 39 | cXMLAttr_t* attr; 40 | } cXML_t; 41 | 42 | typedef struct cXMLHooks_t { 43 | void*(*malloc_fn)(size_t); 44 | void(*free_fn)(void*); 45 | } cXMLHooks_t; 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | __declspec_dll void cXML_SetHooks(cXMLHooks_t* hooks); 52 | __declspec_dll cXMLHooks_t* cXML_GetHooks(cXMLHooks_t* hooks); 53 | 54 | __declspec_dll cXML_t* cXML_Create(cXML_t* node, int deep_copy); 55 | __declspec_dll cXMLAttr_t* cXML_CreateAttr(cXMLAttr_t* attr, int deep_copy); 56 | __declspec_dll cXML_t* cXML_AddAttr(cXML_t* node, cXMLAttr_t* attr); 57 | __declspec_dll cXMLAttr_t* cXML_DetachAttr(cXMLAttr_t* attr); 58 | __declspec_dll void cXML_DeleteAttr(cXMLAttr_t* attr); 59 | __declspec_dll cXML_t* cXML_Add(cXML_t* node, cXML_t* item); 60 | __declspec_dll cXML_t* cXML_Detach(cXML_t* node); 61 | __declspec_dll void cXML_Delete(cXML_t* node); 62 | 63 | __declspec_dll cXML_t* cXML_Parse(const char* data, int deep_copy); 64 | __declspec_dll cXML_t* cXML_ParseFromFile(const char* path); 65 | __declspec_dll cXML_t* cXML_FirstChild(cXML_t* node, const char* name); 66 | __declspec_dll cXML_t* cXML_NextChild(cXML_t* node); 67 | __declspec_dll cXMLAttr_t* cXML_GetAttr(cXML_t* node, const char* name); 68 | __declspec_dll size_t cXML_ByteSize(cXML_t* root); 69 | __declspec_dll char* cXML_Print(cXML_t* root, char* buffer); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /inc/crt/dynarr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_CRT_DYNARR_H 6 | #define UTIL_C_CRT_DYNARR_H 7 | 8 | #include "../compiler_define.h" 9 | #include 10 | 11 | typedef struct DynArrRaw_t { 12 | void* buf; 13 | size_t len; 14 | size_t capacity; 15 | } DynArrRaw_t; 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | __declspec_dll void* dynarrReserve_raw(DynArrRaw_t* dynarr, size_t capacity, size_t ele_size); 22 | __declspec_dll void* dynarrResize_raw(DynArrRaw_t* dynarr, size_t len, size_t ele_size); 23 | __declspec_dll void dynarrSwap_raw(DynArrRaw_t* a1, DynArrRaw_t* a2); 24 | __declspec_dll void dynarrInitZero_raw(DynArrRaw_t* dynarr); 25 | __declspec_dll void dynarrFreeMemory_raw(DynArrRaw_t* dynarr); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #define DynArr_t(type)\ 32 | union {\ 33 | struct {\ 34 | type* buf;\ 35 | size_t len;\ 36 | size_t capacity;\ 37 | };\ 38 | DynArrRaw_t raw;\ 39 | } 40 | 41 | #define dynarrInitZero(dynarr) dynarrInitZero_raw(&(dynarr)->raw) 42 | 43 | #define dynarrIsEmpty(dynarr) (0 == (dynarr)->len) 44 | 45 | #define dynarrReserve(dynarr, capacity) dynarrReserve_raw(&(dynarr)->raw, capacity, sizeof((dynarr)->buf[0])) 46 | 47 | #define dynarrResize(dynarr, len) dynarrResize_raw(&(dynarr)->raw, len, sizeof((dynarr)->buf[0])) 48 | 49 | #define dynarrClearData(dynarr) ((dynarr)->len = 0) 50 | 51 | #define dynarrFreeMemory(dynarr) dynarrFreeMemory_raw(&(dynarr)->raw) 52 | 53 | #define dynarrSwap(a1, a2) dynarrSwap_raw(&(a1)->raw, &(a2)->raw) 54 | 55 | #define dynarrInsert(dynarr, idx, val, ret_ok)\ 56 | do {\ 57 | size_t __i, __idx;\ 58 | if (!dynarrReserve(dynarr, (dynarr)->len + 1)) {\ 59 | ret_ok = 0;\ 60 | break;\ 61 | }\ 62 | ret_ok = 1;\ 63 | __idx = idx;\ 64 | for (__i = (dynarr)->len; __i > __idx; --__i) {\ 65 | (dynarr)->buf[__i] = (dynarr)->buf[__i - 1];\ 66 | }\ 67 | (dynarr)->buf[__i] = val;\ 68 | ++((dynarr)->len);\ 69 | } while (0) 70 | 71 | #define dynarrRemoveIdx(dynarr, idx)\ 72 | do {\ 73 | size_t __i = idx;\ 74 | if (__i >= (dynarr)->len) {\ 75 | break;\ 76 | }\ 77 | for (; __i + 1 < (dynarr)->len; ++__i) {\ 78 | (dynarr)->buf[__i] = (dynarr)->buf[__i + 1];\ 79 | }\ 80 | --((dynarr)->len);\ 81 | } while (0) 82 | 83 | #define dynarrSwapRemoveIdx(dynarr, idx)\ 84 | do {\ 85 | size_t __i = idx;\ 86 | if (__i >= (dynarr)->len) {\ 87 | break;\ 88 | }\ 89 | (dynarr)->buf[__i] = (dynarr)->buf[(dynarr)->len - 1];\ 90 | --((dynarr)->len);\ 91 | } while (0) 92 | 93 | #define dynarrCopyAppend(dst, _buf, _len, ret_ok)\ 94 | do {\ 95 | size_t __i;\ 96 | if (!dynarrReserve(dst, (dst)->len + _len)) {\ 97 | ret_ok = 0;\ 98 | break;\ 99 | }\ 100 | ret_ok = 1;\ 101 | for (__i = 0; __i < _len; ++__i) {\ 102 | (dst)->buf[((dst)->len)++] = _buf[__i];\ 103 | }\ 104 | } while (0) 105 | 106 | #define dynarrFindValue(dynarr, val, ret_idx)\ 107 | do {\ 108 | size_t __i;\ 109 | ret_idx = -1;\ 110 | for (__i = 0; __i < (dynarr)->len; ++__i) {\ 111 | if ((val) == (dynarr)->buf[__i]) {\ 112 | ret_idx = __i;\ 113 | break;\ 114 | }\ 115 | }\ 116 | } while (0) 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /inc/crt/json.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_CRT_JSON_H 6 | #define UTIL_C_CRT_JSON_H 7 | 8 | #include "../compiler_define.h" 9 | #include 10 | 11 | typedef struct cJSON_Setting { 12 | void *(*malloc_fn)(size_t sz); 13 | void (*free_fn)(void *ptr); 14 | unsigned int precision; 15 | } cJSON_Setting; 16 | 17 | typedef struct cJSON { 18 | /* private */ 19 | short type; 20 | short value_type; 21 | short name_deep_copy; 22 | short value_deep_copy; 23 | 24 | /* public read only */ 25 | char *name; 26 | size_t name_length; 27 | 28 | /* private */ 29 | char *value_string; 30 | size_t value_strlen; 31 | long long value_integer; 32 | double value_double; 33 | 34 | /* public read only */ 35 | struct cJSON *parent; 36 | struct cJSON *next, *prev; 37 | struct cJSON *child; 38 | struct cJSON* child_last; 39 | size_t child_num; 40 | } cJSON; 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | __declspec_dll cJSON_Setting* cJSON_GetSetting(cJSON_Setting* s); 47 | __declspec_dll void cJSON_SetSetting(const cJSON_Setting* s); 48 | 49 | __declspec_dll cJSON* cJSON_GetField(cJSON* root, const char* name); 50 | __declspec_dll cJSON* cJSON_GetIndex(cJSON* root, size_t idx); 51 | __declspec_dll size_t cJSON_ChildNum(cJSON* root); 52 | 53 | __declspec_dll long long cJSON_GetInteger(cJSON* node); 54 | __declspec_dll double cJSON_GetDouble(cJSON* node); 55 | __declspec_dll const char* cJSON_GetStringPtr(cJSON* node); 56 | __declspec_dll size_t cJSON_GetStringLength(cJSON* node); 57 | 58 | __declspec_dll cJSON* cJSON_SetInteger(cJSON* node, long long v); 59 | __declspec_dll cJSON* cJSON_SetDouble(cJSON* node, double v); 60 | __declspec_dll cJSON* cJSON_SetString(cJSON* node, const char* s, size_t slen); 61 | 62 | __declspec_dll cJSON* cJSON_NewRoot(void); 63 | __declspec_dll cJSON* cJSON_NewRootArray(void); 64 | __declspec_dll cJSON* cJSON_AppendObject(cJSON* parent, const char* name); 65 | __declspec_dll cJSON* cJSON_AppendArray(cJSON* parent, const char* name); 66 | __declspec_dll cJSON* cJSON_AppendInteger(cJSON* parent, const char* name, long long v); 67 | __declspec_dll cJSON* cJSON_AppendDouble(cJSON* parent, const char* name, double v); 68 | __declspec_dll cJSON* cJSON_AppendString(cJSON* parent, const char* name, const char* v); 69 | 70 | __declspec_dll cJSON* cJSON_Append(cJSON* parent, cJSON* node); 71 | __declspec_dll cJSON* cJSON_Detach(cJSON* node); 72 | __declspec_dll void cJSON_Delete(cJSON* node); 73 | 74 | __declspec_dll cJSON* cJSON_FromString(const char* s, int deep_copy); 75 | __declspec_dll cJSON* cJSON_FromFile(const char* path); 76 | __declspec_dll size_t cJSON_BytesNum(cJSON* root); 77 | __declspec_dll char* cJSON_ToString(cJSON* root, char* buf); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /inc/crt/protocol/hiredis_cli_protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2011, Salvatore Sanfilippo 3 | * Copyright (c) 2010-2011, Pieter Noordhuis 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* All Code is from HIREDIS 33 | * https://github.com/redis/hiredis 34 | * 35 | * hiredis version: 36 | * 37 | #define HIREDIS_MAJOR 1 38 | #define HIREDIS_MINOR 0 39 | #define HIREDIS_PATCH 3 40 | #define HIREDIS_SONAME 1.0.3-dev 41 | */ 42 | 43 | #ifndef __HIREDIS_CLI_PROTOCOL_H 44 | #define __HIREDIS_CLI_PROTOCOL_H 45 | 46 | #ifdef _MSC_VER 47 | #ifndef __declspec_dll 48 | #ifdef DECLSPEC_DLL_EXPORT 49 | #define __declspec_dll __declspec(dllexport) 50 | #elif DECLSPEC_DLL_IMPORT 51 | #define __declspec_dll __declspec(dllimport) 52 | #else 53 | #define __declspec_dll 54 | #endif 55 | #endif 56 | #else 57 | #ifndef __declspec_dll 58 | #ifdef DECLSPEC_DLL_EXPORT 59 | #define __declspec_dll __attribute__((visibility("default"))) 60 | #else 61 | #define __declspec_dll 62 | #endif 63 | #endif 64 | #endif 65 | 66 | #include 67 | #include 68 | 69 | #define REDIS_ERR -1 70 | #define REDIS_OK 0 71 | 72 | /* When an error occurs, the err flag in a context is set to hold the type of 73 | * error that occurred. REDIS_ERR_IO means there was an I/O error and you 74 | * should use the "errno" variable to find out what is wrong. 75 | * For other values, the "errstr" field will hold a description. */ 76 | #define REDIS_ERR_IO 1 /* Error in read or write */ 77 | #define REDIS_ERR_EOF 3 /* End of file */ 78 | #define REDIS_ERR_PROTOCOL 4 /* Protocol error */ 79 | #define REDIS_ERR_OOM 5 /* Out of memory */ 80 | #define REDIS_ERR_TIMEOUT 6 /* Timed out */ 81 | #define REDIS_ERR_OTHER 2 /* Everything else... */ 82 | 83 | #define REDIS_REPLY_STRING 1 84 | #define REDIS_REPLY_ARRAY 2 85 | #define REDIS_REPLY_INTEGER 3 86 | #define REDIS_REPLY_NIL 4 87 | #define REDIS_REPLY_STATUS 5 88 | #define REDIS_REPLY_ERROR 6 89 | #define REDIS_REPLY_DOUBLE 7 90 | #define REDIS_REPLY_BOOL 8 91 | #define REDIS_REPLY_MAP 9 92 | #define REDIS_REPLY_SET 10 93 | #define REDIS_REPLY_ATTR 11 94 | #define REDIS_REPLY_PUSH 12 95 | #define REDIS_REPLY_BIGNUM 13 96 | #define REDIS_REPLY_VERB 14 97 | 98 | /* Structure pointing to our actually configured allocators */ 99 | typedef struct RedisProtocolAllocFuncs_t { 100 | void *(*mallocFn)(size_t); 101 | void *(*callocFn)(size_t,size_t); 102 | void *(*reallocFn)(void*,size_t); 103 | char *(*strdupFn)(const char*); 104 | void (*freeFn)(void*); 105 | } RedisProtocolAllocFuncs_t; 106 | 107 | /* This is the reply object */ 108 | typedef struct RedisReply_t { 109 | int type; /* REDIS_REPLY_* */ 110 | long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ 111 | double dval; /* The double when type is REDIS_REPLY_DOUBLE */ 112 | size_t len; /* Length of string */ 113 | char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING 114 | REDIS_REPLY_VERB, REDIS_REPLY_DOUBLE (in additional to dval), 115 | and REDIS_REPLY_BIGNUM. */ 116 | char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null 117 | terminated 3 character content type, such as "txt". */ 118 | size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ 119 | struct RedisReply_t **element; /* elements vector for REDIS_REPLY_ARRAY */ 120 | } RedisReply_t; 121 | 122 | struct RedisReplyReadTask_t; /* note: hide detail */ 123 | struct RedisReplyObjectFunctions_t; /* note: hide detail */ 124 | 125 | typedef struct RedisReplyReader_t { 126 | int err; /* Error flags, 0 when there is no error */ 127 | char errstr[128]; /* String representation of error when applicable */ 128 | 129 | char *buf; /* Read buffer */ 130 | size_t pos; /* Buffer cursor */ 131 | size_t len; /* Buffer length */ 132 | size_t maxbuf; /* Max length of unused buffer */ 133 | long long maxelements; /* Max multi-bulk elements */ 134 | 135 | struct RedisReplyReadTask_t **task; 136 | int tasks; 137 | 138 | int ridx; /* Index of current read task */ 139 | void *reply; /* Temporary reply pointer *//* default is struct RedisReply_t */ 140 | 141 | const struct RedisReplyObjectFunctions_t *fn; 142 | void *privdata; 143 | } RedisReplyReader_t; 144 | 145 | #ifdef __cplusplus 146 | extern "C" { 147 | #endif 148 | 149 | __declspec_dll RedisProtocolAllocFuncs_t RedisProtocolAllocFuncs_set(const RedisProtocolAllocFuncs_t *ha); 150 | __declspec_dll void RedisProtocolAllocFuncs_reset(void); 151 | 152 | __declspec_dll RedisReplyReader_t *RedisReplyReader_create(void); 153 | __declspec_dll void RedisReplyReader_free(RedisReplyReader_t *r); 154 | __declspec_dll int RedisReplyReader_feed(RedisReplyReader_t *r, const char *buf, size_t len); 155 | __declspec_dll int RedisReplyReader_pop_reply(RedisReplyReader_t *r, RedisReply_t **reply); 156 | __declspec_dll void RedisReply_free(RedisReply_t *reply); 157 | 158 | __declspec_dll int RedisCommand_vformat(char **target, const char *format, va_list ap); 159 | __declspec_dll int RedisCommand_format(char **target, const char *format, ...); 160 | __declspec_dll size_t RedisCommand_format_argv(char **target, int argc, const char **argv, const size_t *argvlen); 161 | __declspec_dll void RedisCommand_free(char *target); 162 | 163 | #ifdef __cplusplus 164 | } 165 | #endif 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /inc/crt/protocol/httpframe.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-18. 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_HTTPFRAME_H 6 | #define UTIL_C_COMPONENT_HTTPFRAME_H 7 | 8 | #include "../../compiler_define.h" 9 | #include "../../datastruct/hashtable.h" 10 | #include "../../datastruct/list.h" 11 | 12 | typedef struct HttpFrameHeaderField_t { 13 | HashtableNode_t m_hashnode; 14 | const char* key; 15 | const char* value; 16 | } HttpFrameHeaderField_t; 17 | 18 | typedef struct HttpMultipartFormData_t { 19 | ListNode_t listnode; 20 | Hashtable_t headers; 21 | HashtableNode_t* m_headerbulks[5]; 22 | unsigned int datalen; 23 | unsigned char data[1]; 24 | } HttpMultipartFormData_t; 25 | 26 | typedef struct HttpFrame_t { 27 | /* header */ 28 | int status_code; 29 | char method[8]; 30 | char* uri; 31 | char* query; 32 | unsigned int pathlen; 33 | Hashtable_t headers; 34 | HashtableNode_t* m_bulks[11]; 35 | /* body */ 36 | const char* multipart_form_data_boundary; 37 | List_t multipart_form_datalist; 38 | unsigned int content_length; 39 | } HttpFrame_t; 40 | 41 | #define HTTP_SIMPLE_RESP_FMT \ 42 | "HTTP/1.1 %u %s\r\n"\ 43 | "Access-Control-Allow-Origin: *\r\n"\ 44 | "Content-Length:%u\r\n"\ 45 | "\r\n"\ 46 | "%s"\ 47 | 48 | #define HTTP_SIMPLE_RESP_VALUE(status_code, strdata, strdatalen) \ 49 | status_code, httpframeStatusDesc(status_code), strdatalen, strdata 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | __declspec_dll HttpFrame_t* httpframeInit(HttpFrame_t* frame); 56 | __declspec_dll HttpFrame_t* httpframeReset(HttpFrame_t* frame); 57 | __declspec_dll const char* httpframeGetHeader(Hashtable_t* headers, const char* key); 58 | __declspec_dll const char* httpframeStatusDesc(int status_code); 59 | 60 | __declspec_dll int httpframeDecodeHeader(HttpFrame_t* frame, const char* buf, unsigned int len); 61 | __declspec_dll int httpframeDecodeChunked(const char* buf, unsigned int len, unsigned char** data, unsigned int* datalen); 62 | __declspec_dll void httpframeEncodeChunked(unsigned int datalen, char txtbuf[11]); 63 | __declspec_dll int httpframeDecodeMultipartFormData(const char* boundary, const unsigned char* buf, unsigned int len, HttpMultipartFormData_t** form_data); 64 | __declspec_dll HttpFrame_t* httpframeDecodeMultipartFormDataList(HttpFrame_t* frame, const unsigned char* buf, unsigned int content_length); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /inc/crt/protocol/websocketframe.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-17. 3 | // 4 | 5 | #ifndef UTIL_C_COMPONENT_WEBSOCKETFRAME_H 6 | #define UTIL_C_COMPONENT_WEBSOCKETFRAME_H 7 | 8 | #include "../../compiler_define.h" 9 | 10 | enum { 11 | WEBSOCKET_CONTINUE_FRAME = 0, 12 | WEBSOCKET_TEXT_FRAME = 1, 13 | WEBSOCKET_BINARY_FRAME = 2, 14 | WEBSOCKET_CLOSE_FRAME = 8, 15 | WEBSOCKET_PING_FRAME = 9, 16 | WEBSOCKET_PONG_FRAME = 10 17 | }; 18 | 19 | #define WEBSOCKET_MAX_ENCODE_HEADLENGTH 10 20 | 21 | #define WEBSOCKET_SIMPLE_HTTP_HANDSHAKE_REQUEST_FMT \ 22 | "GET %s HTTP/1.1\r\n" \ 23 | "Upgrade: websocket\r\n" \ 24 | "Connection: Upgrade\r\n" \ 25 | "Sec-WebSocket-Version: 13\r\n" \ 26 | "Sec-WebSocket-Key: %s\r\n" \ 27 | "\r\n" \ 28 | 29 | #define WEBSOCKET_SIMPLE_HTTP_HANDSHAKE_REQUEST_WITH_PROTOCOL_FMT \ 30 | "GET %s HTTP/1.1\r\n" \ 31 | "Upgrade: websocket\r\n" \ 32 | "Connection: Upgrade\r\n" \ 33 | "Sec-WebSocket-Version: 13\r\n" \ 34 | "Sec-WebSocket-Key: %s\r\n" \ 35 | "Sec-WebSocket-Protocol: %s\r\n" \ 36 | "\r\n" \ 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | __declspec_dll char* websocketframeComputeSecAccept(const char* sec_key, unsigned int sec_keylen, char sec_accept[60]); 43 | __declspec_dll int websocketframeDecodeHandshakeRequest(const char* data, unsigned int datalen, const char** sec_key, unsigned int* sec_keylen, const char** sec_protocol, unsigned int* sec_protocol_len); 44 | __declspec_dll char* websocketframeEncodeHandshakeResponse(const char* sec_accept, unsigned int sec_accept_len, char buf[162]); 45 | __declspec_dll char* websocketframeEncodeHandshakeResponseWithProtocol(const char* sec_accept_key, unsigned int sec_accept_len, const char* sec_protocol, unsigned int sec_protocol_len); 46 | __declspec_dll void websocketframeFreeString(char* s); 47 | __declspec_dll int websocketframeDecode(unsigned char* buf, unsigned long long len, unsigned char** data, unsigned long long* datalen, int* is_fin, int* type); 48 | __declspec_dll unsigned int websocketframeEncodeHeadLength(unsigned long long datalen); 49 | __declspec_dll void websocketframeEncode(void* headbuf, int is_fin, int prev_is_fin, int type, unsigned long long datalen); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /inc/crt/string.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_CRT_STRING_H 6 | #define UTIL_C_CRT_STRING_H 7 | 8 | #include "../datastruct/memfunc.h" 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | __declspec_dll int strFormatLen(const char* format, ...); 16 | __declspec_dll char* strFormat(int* out_len, const char* format, ...); 17 | __declspec_dll void strFreeMemory(char* s); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // !UTIL_C_CRT_STRING_H 24 | -------------------------------------------------------------------------------- /inc/datastruct/arrheap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_ARRHEAP_H 6 | #define UTIL_C_DATASTRUCT_ARRHEAP_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #define arrheapInsert(type, buf, len, cmp)\ 11 | do {\ 12 | UnsignedPtr_t __ci;\ 13 | if (len <= 1) {\ 14 | break;\ 15 | }\ 16 | __ci = len - 1;\ 17 | while (__ci > 0) {\ 18 | UnsignedPtr_t __pi = ((__ci - 1) >> 1);\ 19 | if (cmp(&buf[__pi], &buf[__ci]) > 0) {\ 20 | type __temp = buf[__pi];\ 21 | buf[__pi] = buf[__ci];\ 22 | buf[__ci] = __temp;\ 23 | __ci = __pi;\ 24 | } else break;\ 25 | }\ 26 | } while (0) 27 | 28 | #define arrheapPop(type, buf, len, cmp)\ 29 | do {\ 30 | UnsignedPtr_t __pi, __ci;\ 31 | if (len <= 1) {\ 32 | break;\ 33 | }\ 34 | buf[0] = buf[len - 1];\ 35 | __pi = 0;\ 36 | __ci = (__pi << 1) + 1;\ 37 | while (__ci < len - 1) {\ 38 | if (__ci + 1 < len - 1) {\ 39 | if (cmp(&buf[__ci], &buf[__ci + 1]) > 0) {\ 40 | __ci += 1;\ 41 | }\ 42 | }\ 43 | if (cmp(&buf[__pi], &buf[__ci]) > 0) {\ 44 | type __temp = buf[__pi];\ 45 | buf[__pi] = buf[__ci];\ 46 | buf[__ci] = __temp;\ 47 | __pi = __ci;\ 48 | __ci = (__pi << 1) + 1;\ 49 | } else break;\ 50 | }\ 51 | } while (0) 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /inc/datastruct/base64.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_BASE64_H 6 | #define UTIL_C_DATASTRUCT_BASE64_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #define base64EncodeLength(len) (((len) + 2) / 3 * 4) 15 | __declspec_dll UnsignedPtr_t base64Encode(const unsigned char* src, UnsignedPtr_t srclen, char* dst); 16 | #define base64DecodeLength(len) (((len) + 3) / 4 * 3) 17 | __declspec_dll UnsignedPtr_t base64Decode(const char* src, UnsignedPtr_t srclen, unsigned char* dst); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // !UTIL_C_DATASTRUCT_BASE64_H 24 | -------------------------------------------------------------------------------- /inc/datastruct/bstree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_BSTREE_H 6 | #define UTIL_C_DATASTRUCT_BSTREE_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef union { 11 | const void* ptr; 12 | SignedPtr_t int_ptr; 13 | UnsignedPtr_t uint_ptr; 14 | int i32; 15 | unsigned int u32; 16 | long long i64; 17 | unsigned long long u64; 18 | } BSTreeNodeKey_t; 19 | 20 | typedef struct BSTreeNode_t { 21 | BSTreeNodeKey_t key; 22 | struct BSTreeNode_t* bs_left; 23 | struct BSTreeNode_t* bs_right; 24 | struct BSTreeNode_t* bs_parent; 25 | } BSTreeNode_t; 26 | 27 | typedef struct BSTree_t { 28 | struct BSTreeNode_t* bs_root; 29 | int (*keycmp)(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 30 | UnsignedPtr_t count; 31 | } BSTree_t; 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | __declspec_dll int bstreeDefaultKeyCmpU32(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 38 | __declspec_dll int bstreeDefaultKeyCmpI32(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 39 | __declspec_dll int bstreeDefaultKeyCmpU64(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 40 | __declspec_dll int bstreeDefaultKeyCmpI64(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 41 | __declspec_dll int bstreeDefaultKeyCmpSSZ(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 42 | __declspec_dll int bstreeDefaultKeyCmpSZ(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 43 | __declspec_dll int bstreeDefaultKeyCmpStr(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*); 44 | 45 | __declspec_dll struct BSTree_t* bstreeInit(struct BSTree_t* tree, int(*keycmp)(const BSTreeNodeKey_t*, const BSTreeNodeKey_t*)); 46 | __declspec_dll struct BSTreeNode_t* bstreeInsertNode(struct BSTree_t* tree, struct BSTreeNode_t* node); 47 | __declspec_dll void bstreeReplaceNode(struct BSTree_t* tree, struct BSTreeNode_t* old_node, struct BSTreeNode_t* new_node); 48 | __declspec_dll void bstreeRemoveNode(struct BSTree_t* tree, struct BSTreeNode_t* node); 49 | __declspec_dll struct BSTreeNode_t* bstreeMinNode(const struct BSTreeNode_t* node); 50 | __declspec_dll struct BSTreeNode_t* bstreeMaxNode(const struct BSTreeNode_t* node); 51 | __declspec_dll struct BSTreeNode_t* bstreeSearchKey(struct BSTree_t* tree, const BSTreeNodeKey_t key); 52 | __declspec_dll struct BSTreeNode_t* bstreeRemoveKey(struct BSTree_t* tree, const BSTreeNodeKey_t key); 53 | __declspec_dll struct BSTreeNode_t* bstreeFirstNode(const struct BSTree_t* tree); 54 | __declspec_dll struct BSTreeNode_t* bstreeLastNode(const struct BSTree_t* tree); 55 | __declspec_dll struct BSTreeNode_t* bstreeNextNode(struct BSTreeNode_t* node); 56 | __declspec_dll struct BSTreeNode_t* bstreePrevNode(struct BSTreeNode_t* node); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /inc/datastruct/graph.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_GRAPH_H 6 | #define UTIL_C_DATASTRUCT_GRAPH_H 7 | 8 | #include "hashtable.h" 9 | #include "list.h" 10 | 11 | typedef struct Graph_t { 12 | List_t vnodelist; 13 | int dfs_visit; 14 | } Graph_t; 15 | 16 | struct GraphEdge_t; 17 | typedef struct GraphNode_t { 18 | ListNode_t node; 19 | Graph_t* graph; 20 | List_t edgelist[2]; 21 | UnsignedPtr_t degree[2]; 22 | struct { 23 | struct GraphEdge_t* visit_from_edgenode; 24 | int dfs_visit; 25 | }; 26 | } GraphNode_t; 27 | 28 | typedef struct GraphEdge_t { 29 | union { 30 | GraphNode_t* v[2]; 31 | struct { 32 | GraphNode_t* v_start; 33 | GraphNode_t* v_end; 34 | }; 35 | }; 36 | ListNode_t edgelistnode[2]; 37 | ListNode_t viewnode; 38 | } GraphEdge_t; 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | __declspec_dll Graph_t* graphInit(Graph_t* g); 45 | __declspec_dll Graph_t* graphAddNode(Graph_t* g, GraphNode_t* v); 46 | __declspec_dll void graphRemoveNode(Graph_t* g, GraphNode_t* v, List_t* unlink_edgelist); 47 | 48 | __declspec_dll GraphEdge_t* graphLinkEdge(GraphEdge_t* e); 49 | __declspec_dll void graphUnlinkEdge(GraphEdge_t* e); 50 | __declspec_dll void graphUnlinkNode(GraphNode_t* v, List_t* unlink_edgelist); 51 | 52 | __declspec_dll GraphNode_t* graphDFSFirst(Graph_t* g, GraphNode_t* v); 53 | __declspec_dll GraphNode_t* graphDFSNext(GraphNode_t* v); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /inc/datastruct/hash.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_HASH_H 6 | #define UTIL_C_DATASTRUCT_HASH_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | __declspec_dll unsigned int hashBKDR(const char *str); 15 | __declspec_dll unsigned int hashDJB(const char *str); 16 | __declspec_dll unsigned int hashJenkins(const char *key, UnsignedPtr_t keylen); 17 | __declspec_dll unsigned int hashMurmur2(const char *key, UnsignedPtr_t keylen); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // !UTIL_C_DATASTRUCT_HASH_H 24 | -------------------------------------------------------------------------------- /inc/datastruct/hashtable.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_HASHTABLE_H 6 | #define UTIL_C_DATASTRUCT_HASHTABLE_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef union { 11 | const void* ptr; 12 | SignedPtr_t int_ptr; 13 | UnsignedPtr_t uint_ptr; 14 | int i32; 15 | unsigned int u32; 16 | long long i64; 17 | unsigned long long u64; 18 | } HashtableNodeKey_t; 19 | 20 | struct Hashtable_t; 21 | typedef struct HashtableNode_t { 22 | HashtableNodeKey_t key; 23 | struct HashtableNode_t *prev, *next; 24 | struct HashtableNode_t *ele_prev, *ele_next; 25 | unsigned int bucket_index; 26 | } HashtableNode_t; 27 | 28 | typedef struct Hashtable_t { 29 | struct HashtableNode_t** buckets; 30 | unsigned int buckets_size; 31 | int (*keycmp)(const HashtableNodeKey_t*, const HashtableNodeKey_t*); 32 | unsigned int (*keyhash)(const HashtableNodeKey_t*); 33 | struct HashtableNode_t *head, *tail; 34 | UnsignedPtr_t count; 35 | } Hashtable_t; 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | __declspec_dll int hashtableDefaultKeyCmp32(const HashtableNodeKey_t*, const HashtableNodeKey_t*); 42 | __declspec_dll unsigned int hashtableDefaultKeyHash32(const HashtableNodeKey_t*); 43 | __declspec_dll int hashtableDefaultKeyCmp64(const HashtableNodeKey_t*, const HashtableNodeKey_t*); 44 | __declspec_dll unsigned int hashtableDefaultKeyHash64(const HashtableNodeKey_t*); 45 | __declspec_dll int hashtableDefaultKeyCmpSZ(const HashtableNodeKey_t*, const HashtableNodeKey_t*); 46 | __declspec_dll unsigned int hashtableDefaultKeyHashSZ(const HashtableNodeKey_t*); 47 | __declspec_dll int hashtableDefaultKeyCmpStr(const HashtableNodeKey_t*, const HashtableNodeKey_t*); 48 | __declspec_dll unsigned int hashtableDefaultKeyHashStr(const HashtableNodeKey_t*); 49 | 50 | __declspec_dll struct Hashtable_t* hashtableInit(struct Hashtable_t* hashtable, 51 | struct HashtableNode_t** buckets, unsigned int buckets_size, 52 | int (*keycmp)(const HashtableNodeKey_t*, const HashtableNodeKey_t*), 53 | unsigned int (*keyhash)(const HashtableNodeKey_t*)); 54 | 55 | __declspec_dll struct HashtableNode_t* hashtableInsertNode(struct Hashtable_t* hashtable, struct HashtableNode_t* node); 56 | __declspec_dll void hashtableReplaceNode(struct Hashtable_t* hashtable, struct HashtableNode_t* old_node, struct HashtableNode_t* new_node); 57 | __declspec_dll void hashtableRemoveNode(struct Hashtable_t* hashtable, struct HashtableNode_t* node); 58 | 59 | __declspec_dll struct HashtableNode_t* hashtableSearchKey(const struct Hashtable_t* hashtable, const HashtableNodeKey_t key); 60 | __declspec_dll struct HashtableNode_t* hashtableRemoveKey(struct Hashtable_t* hashtable, const HashtableNodeKey_t key); 61 | 62 | __declspec_dll int hashtableIsEmpty(const struct Hashtable_t* hashtable); 63 | __declspec_dll struct HashtableNode_t* hashtableFirstNode(const struct Hashtable_t* hashtable); 64 | __declspec_dll struct HashtableNode_t* hashtableNextNode(struct HashtableNode_t* node); 65 | __declspec_dll struct HashtableNode_t* hashtableLastNode(const struct Hashtable_t* hashtable); 66 | __declspec_dll struct HashtableNode_t* hashtablePrevNode(struct HashtableNode_t* node); 67 | 68 | __declspec_dll void hashtableRehash(struct Hashtable_t* hashtable, struct HashtableNode_t** buckets, unsigned int buckets_size); 69 | __declspec_dll void hashtableSwap(struct Hashtable_t* h1, struct Hashtable_t* h2); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /inc/datastruct/lengthfieldframe.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-17. 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_LENGTHFIELDFRAME_H 6 | #define UTIL_C_DATASTRUCT_LENGTHFIELDFRAME_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | __declspec_dll int lengthfieldframeDecode(unsigned short lengthfieldsize, 15 | const unsigned char* buf, unsigned int len, unsigned char** data, unsigned int* datalen); 16 | __declspec_dll int lengthfieldframeEncode(void* lengthfieldbuf, unsigned short lengthfieldsize, unsigned int datalen); 17 | __declspec_dll int lengthfieldframeDecode2(unsigned short lengthfieldsize, unsigned char* buf, unsigned int len); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /inc/datastruct/list.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_LIST_H 6 | #define UTIL_C_DATASTRUCT_LIST_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef struct ListNode_t { 11 | struct ListNode_t *prev, *next; 12 | } ListNode_t; 13 | typedef struct List_t { 14 | struct ListNode_t *head, *tail; 15 | } List_t; 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | __declspec_dll struct List_t* listInit(struct List_t* list); 22 | __declspec_dll struct ListNode_t* listFindNode(const struct List_t* list, int(*cmp)(const struct ListNode_t*, const void*), const void* key); 23 | __declspec_dll void listInsertNodeFront(struct List_t* list, struct ListNode_t* node, struct ListNode_t* new_node); 24 | __declspec_dll void listInsertNodeBack(struct List_t* list, struct ListNode_t* node, struct ListNode_t* new_node); 25 | __declspec_dll void listInsertNodeSorted(struct List_t* list, struct ListNode_t* new_node, int(*cmp)(struct ListNode_t*, struct ListNode_t*)); 26 | __declspec_dll void listRemoveNode(struct List_t* list, struct ListNode_t* node); 27 | __declspec_dll void listReplaceNode(struct List_t* list, struct ListNode_t* node, struct ListNode_t* new_node); 28 | 29 | __declspec_dll struct List_t* listPushNodeFront(struct List_t* list, struct ListNode_t* node); 30 | __declspec_dll struct List_t* listPushNodeBack(struct List_t* list, struct ListNode_t* node); 31 | __declspec_dll struct ListNode_t* listPopNodeFront(struct List_t* list); 32 | __declspec_dll struct ListNode_t* listPopNodeBack(struct List_t* list); 33 | __declspec_dll struct ListNode_t* listAt(const struct List_t* list, UnsignedPtr_t index); 34 | __declspec_dll struct ListNode_t* listAtMost(const struct List_t* list, UnsignedPtr_t index); 35 | __declspec_dll UnsignedPtr_t listNodeCount(const struct List_t* list); 36 | __declspec_dll int listIsEmpty(const struct List_t* list); 37 | 38 | __declspec_dll void listAppend(struct List_t* to, struct List_t* from); 39 | __declspec_dll void listSwap(struct List_t* one, struct List_t* two); 40 | __declspec_dll void listReverse(struct List_t* list); 41 | __declspec_dll struct List_t listSplit(struct List_t* old_list, struct ListNode_t* head, struct ListNode_t* tail); 42 | __declspec_dll struct List_t listSplitByHead(struct List_t* old_list, struct ListNode_t* new_head); 43 | __declspec_dll struct List_t listSplitByTail(struct List_t* old_list, struct ListNode_t* new_tail); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /inc/datastruct/md5.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_MD5_H 6 | #define UTIL_C_DATASTRUCT_MD5_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef struct { 11 | unsigned int count[2]; 12 | unsigned int state[4]; 13 | unsigned char buffer[64]; 14 | } MD5_CTX; 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | __declspec_dll void MD5Transform(unsigned int state[4], unsigned char block[64]); 21 | __declspec_dll void MD5Init(MD5_CTX *context); 22 | __declspec_dll void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen); 23 | __declspec_dll void MD5Final(MD5_CTX *context, unsigned char digest[16]); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif // !UTIL_C_DATASTRUCT_MD5_H 30 | -------------------------------------------------------------------------------- /inc/datastruct/memfunc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_MEMFUNC_H 6 | #define UTIL_C_DATASTRUCT_MEMFUNC_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | __declspec_dll int byteorderIsLE(void); 15 | __declspec_dll unsigned short memToBE16(unsigned short v); 16 | __declspec_dll unsigned short memToLE16(unsigned short v); 17 | __declspec_dll unsigned short memFromBE16(unsigned short v); 18 | __declspec_dll unsigned short memFromLE16(unsigned short v); 19 | __declspec_dll unsigned int memToBE32(unsigned int v); 20 | __declspec_dll unsigned int memToLE32(unsigned int v); 21 | __declspec_dll unsigned int memFromBE32(unsigned int v); 22 | __declspec_dll unsigned int memFromLE32(unsigned int v); 23 | __declspec_dll unsigned long long memToBE64(unsigned long long v); 24 | __declspec_dll unsigned long long memToLE64(unsigned long long v); 25 | __declspec_dll unsigned long long memFromBE64(unsigned long long v); 26 | __declspec_dll unsigned long long memFromLE64(unsigned long long v); 27 | 28 | __declspec_dll int memBitCheck(char* arr, UnsignedPtr_t bit_idx); 29 | __declspec_dll void memBitSet(char* arr, UnsignedPtr_t bit_idx); 30 | __declspec_dll void memBitUnset(char* arr, UnsignedPtr_t bit_idx); 31 | 32 | __declspec_dll void memSwap(void* p1, void* p2, UnsignedPtr_t n); 33 | __declspec_dll void* memCopy(void* dst, const void* src, UnsignedPtr_t n); 34 | __declspec_dll unsigned char* memSkipByte(const void* p, UnsignedPtr_t n, const unsigned char* delim, UnsignedPtr_t dn); 35 | __declspec_dll void* memZero(void* p, UnsignedPtr_t n); 36 | __declspec_dll void* memReverse(void* p, UnsignedPtr_t len); 37 | __declspec_dll unsigned short memCheckSum16(const void* buffer, int len); 38 | #define memCheckSumIsOk(cksum) (0 == (cksum)) 39 | __declspec_dll void* memSearch(const void* buf, UnsignedPtr_t n, const void* s, UnsignedPtr_t sn); 40 | __declspec_dll void* memSearchValue(const void* buf, UnsignedPtr_t n, const void* d, UnsignedPtr_t dn); 41 | 42 | __declspec_dll char* strSkipByte(const char* s, const char* delim); 43 | __declspec_dll char* strChr(const char* s, UnsignedPtr_t n, char c); 44 | __declspec_dll char* strStr(const char* s1, UnsignedPtr_t s1len, const char* s2, UnsignedPtr_t s2len); 45 | __declspec_dll char* strSplit(const char* str, UnsignedPtr_t len, const char** p_sc, const char* delim); 46 | __declspec_dll UnsignedPtr_t strLenUtf8(const char* s, UnsignedPtr_t s_bytelen); 47 | __declspec_dll int strUtf8CharacterByteNum(const char* s); 48 | __declspec_dll int strCmpNoCase(const char* s1, const char* s2, UnsignedPtr_t n); 49 | __declspec_dll int strIsInteger(const char* s, UnsignedPtr_t n); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif // !UTIL_C_DATASTRUCT_MEMFUNC_H 56 | -------------------------------------------------------------------------------- /inc/datastruct/memheap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_MEMHEAP_H 6 | #define UTIL_C_DATASTRUCT_MEMHEAP_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | struct MemHeap_t; 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | __declspec_dll UnsignedPtr_t memheapLength(struct MemHeap_t* h); 17 | __declspec_dll void* memheapStartAddr(struct MemHeap_t* memheap); 18 | 19 | __declspec_dll struct MemHeap_t* memheapSetup(void* addr, UnsignedPtr_t len); 20 | __declspec_dll void* memheapAlloc(struct MemHeap_t* memheap, UnsignedPtr_t nbytes); 21 | __declspec_dll void* memheapAlignAlloc(struct MemHeap_t* memheap, UnsignedPtr_t nbytes, UnsignedPtr_t alignment); 22 | __declspec_dll void* memheapRealloc(struct MemHeap_t* memheap, void* addr, UnsignedPtr_t nbytes); 23 | __declspec_dll void memheapFree(struct MemHeap_t* memheap, void* addr); 24 | __declspec_dll void memheapFreeAll(struct MemHeap_t* memheap); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /inc/datastruct/random.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_RANDOM_H 6 | #define UTIL_C_DATASTRUCT_RANDOM_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* linear congruential */ 15 | typedef struct Rand48_t { unsigned int x[3], a[3], c; } Rand48_t; 16 | __declspec_dll void rand48Seed(Rand48_t* ctx, int seedval); 17 | __declspec_dll int rand48_l(Rand48_t* ctx); 18 | #define rand48_ul(ctx) ((unsigned int)rand48_l(ctx)) 19 | __declspec_dll int rand48Range(Rand48_t* ctx, int start, int end); 20 | /* mt19937 */ 21 | typedef struct RandMT19937_t { unsigned long long x[312]; int k; } RandMT19937_t; 22 | __declspec_dll void mt19937Seed(RandMT19937_t* ctx, int seedval); 23 | __declspec_dll unsigned long long mt19937_ull(RandMT19937_t* ctx); 24 | #define mt19937_ll(ctx) ((long long)mt19937_ull(ctx)) 25 | __declspec_dll long long mt19937Range(RandMT19937_t* ctx, long long start, long long end); 26 | /* random string */ 27 | __declspec_dll char* randAlphabetNumber(int seedval, char* s, UnsignedPtr_t length); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /inc/datastruct/rbtree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_RBTREE_H 6 | #define UTIL_C_DATASTRUCT_RBTREE_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef union { 11 | const void* ptr; 12 | SignedPtr_t int_ptr; 13 | UnsignedPtr_t uint_ptr; 14 | int i32; 15 | unsigned int u32; 16 | long long i64; 17 | unsigned long long u64; 18 | } RBTreeNodeKey_t; 19 | 20 | typedef struct RBTreeNode_t { 21 | RBTreeNodeKey_t key; 22 | unsigned long rb_color; 23 | struct RBTreeNode_t *rb_parent; 24 | struct RBTreeNode_t *rb_right; 25 | struct RBTreeNode_t *rb_left; 26 | } RBTreeNode_t; 27 | 28 | typedef struct RBTree_t { 29 | struct RBTreeNode_t *rb_tree_node; 30 | int (*keycmp)(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 31 | UnsignedPtr_t count; 32 | } RBTree_t; 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | __declspec_dll int rbtreeDefaultKeyCmpU32(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 39 | __declspec_dll int rbtreeDefaultKeyCmpI32(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 40 | __declspec_dll int rbtreeDefaultKeyCmpU64(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 41 | __declspec_dll int rbtreeDefaultKeyCmpI64(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 42 | __declspec_dll int rbtreeDefaultKeyCmpSSZ(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 43 | __declspec_dll int rbtreeDefaultKeyCmpSZ(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 44 | __declspec_dll int rbtreeDefaultKeyCmpStr(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*); 45 | 46 | __declspec_dll struct RBTree_t* rbtreeInit(struct RBTree_t* root, int(*keycmp)(const RBTreeNodeKey_t*, const RBTreeNodeKey_t*)); 47 | 48 | __declspec_dll struct RBTreeNode_t* rbtreeInsertNode(struct RBTree_t* root, struct RBTreeNode_t* node); 49 | __declspec_dll void rbtreeReplaceNode(struct RBTree_t* root, struct RBTreeNode_t* old_node, struct RBTreeNode_t* new_node); 50 | __declspec_dll void rbtreeRemoveNode(struct RBTree_t* root, struct RBTreeNode_t* node); 51 | 52 | __declspec_dll struct RBTreeNode_t* rbtreeSearchKey(const struct RBTree_t* root, const RBTreeNodeKey_t key); 53 | __declspec_dll struct RBTreeNode_t* rbtreeLowerBoundKey(const struct RBTree_t* root, const RBTreeNodeKey_t key); 54 | __declspec_dll struct RBTreeNode_t* rbtreeUpperBoundKey(const struct RBTree_t* root, const RBTreeNodeKey_t key); 55 | __declspec_dll struct RBTreeNode_t* rbtreeRemoveKey(struct RBTree_t* root, const RBTreeNodeKey_t key); 56 | 57 | __declspec_dll struct RBTreeNode_t* rbtreeNextNode(struct RBTreeNode_t* node); 58 | __declspec_dll struct RBTreeNode_t* rbtreePrevNode(struct RBTreeNode_t* node); 59 | __declspec_dll struct RBTreeNode_t* rbtreeFirstNode(const struct RBTree_t* root); 60 | __declspec_dll struct RBTreeNode_t* rbtreeLastNode(const struct RBTree_t* root); 61 | 62 | __declspec_dll void rbtreeSwap(struct RBTree_t* root1, struct RBTree_t* root2); 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /inc/datastruct/sha1.h: -------------------------------------------------------------------------------- 1 | /* ================ sha1.h ================ */ 2 | /* 3 | SHA-1 in C 4 | By Steve Reid 5 | 100% Public Domain 6 | */ 7 | 8 | #ifndef UTIL_C_DATASTRUCT_SHA1_H 9 | #define UTIL_C_DATASTRUCT_SHA1_H 10 | 11 | #include "../compiler_define.h" 12 | 13 | typedef struct { 14 | unsigned int state[5]; 15 | unsigned int count[2]; 16 | unsigned char buffer[64]; 17 | } SHA1_CTX; 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | __declspec_dll void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]); 24 | __declspec_dll void SHA1Init(SHA1_CTX* context); 25 | __declspec_dll void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len); 26 | __declspec_dll void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | #endif -------------------------------------------------------------------------------- /inc/datastruct/transport_ctx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 2019-7-10. 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_TRANSPORT_CTX_H 6 | #define UTIL_C_DATASTRUCT_TRANSPORT_CTX_H 7 | 8 | #include "list.h" 9 | 10 | /* reliable UDP use those packet type */ 11 | enum { 12 | NETPACKET_SYN = 1, /* reliable UDP client connect use */ 13 | NETPACKET_SYN_ACK, /* reliable UDP listener use */ 14 | NETPACKET_ACK, 15 | NETPACKET_NO_ACK_FRAGMENT, 16 | NETPACKET_FIN, 17 | NETPACKET_FRAGMENT 18 | }; 19 | enum { 20 | NETPACKET_DGRAM_HAS_SEND_SEQ = NETPACKET_FIN 21 | }; 22 | 23 | typedef struct NetPacket_t { 24 | ListNode_t node; 25 | char type; 26 | char wait_ack; 27 | char cached; 28 | char fragment_eof; 29 | union { 30 | /* dgram */ 31 | struct { 32 | char resend_times; 33 | long long resend_msec; 34 | }; 35 | /* stream */ 36 | struct { 37 | unsigned int off; 38 | }; 39 | }; 40 | unsigned int seq; 41 | unsigned int hdrlen; 42 | unsigned int bodylen; 43 | unsigned char buf[1]; 44 | } NetPacket_t; 45 | 46 | typedef struct DgramTransportCtx_t { 47 | List_t recvlist; 48 | List_t sendlist; 49 | unsigned int cache_recv_bytes; 50 | unsigned int cache_send_bytes; 51 | unsigned char send_all_acked; 52 | unsigned char cwndsize; 53 | /* private */ 54 | unsigned int m_sendseq; 55 | unsigned int m_recvseq; 56 | unsigned int m_cwndseq; 57 | unsigned int m_ackseq; 58 | ListNode_t* m_recvnode; 59 | } DgramTransportCtx_t; 60 | 61 | typedef struct StreamTransportCtx_t { 62 | List_t recvlist; 63 | List_t sendlist; 64 | unsigned int cache_recv_bytes; 65 | unsigned int cache_send_bytes; 66 | } StreamTransportCtx_t; 67 | 68 | #ifdef __cplusplus 69 | extern "C" { 70 | #endif 71 | 72 | __declspec_dll DgramTransportCtx_t* dgramtransportctxInit(DgramTransportCtx_t* ctx, unsigned int initseq); 73 | __declspec_dll int dgramtransportctxRecvCheck(DgramTransportCtx_t* ctx, unsigned int seq, int pktype); 74 | __declspec_dll void dgramtransportctxCacheRecvPacket(DgramTransportCtx_t* ctx, NetPacket_t* packet); 75 | __declspec_dll int dgramtransportctxMergeRecvPacket(DgramTransportCtx_t* ctx, List_t* list); 76 | __declspec_dll unsigned int dgramtransportctxNextSendSeq(DgramTransportCtx_t* ctx, int pktype); 77 | __declspec_dll int dgramtransportctxCacheSendPacket(DgramTransportCtx_t* ctx, NetPacket_t* packet); 78 | __declspec_dll int dgramtransportctxAckSendPacket(DgramTransportCtx_t* ctx, unsigned int ackseq, NetPacket_t** ackpacket); 79 | __declspec_dll int dgramtransportctxSendWindowHasPacket(DgramTransportCtx_t* ctx, NetPacket_t* packet); 80 | 81 | __declspec_dll StreamTransportCtx_t* streamtransportctxInit(StreamTransportCtx_t* ctx); 82 | __declspec_dll void streamtransportctxCacheRecvPacket(StreamTransportCtx_t* ctx, NetPacket_t* packet); 83 | __declspec_dll int streamtransportctxMergeRecvPacket(StreamTransportCtx_t* ctx, List_t* list); 84 | __declspec_dll int streamtransportctxSendCheckBusy(StreamTransportCtx_t* ctx); 85 | __declspec_dll int streamtransportctxCacheSendPacket(StreamTransportCtx_t* ctx, NetPacket_t* packet); 86 | __declspec_dll void streamtransportctxRemoveCacheSendPacket(StreamTransportCtx_t* ctx, NetPacket_t* packet); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /inc/datastruct/tree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_TREE_H 6 | #define UTIL_C_DATASTRUCT_TREE_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef struct Tree_t { 11 | struct Tree_t *parent, *child, *left, *right; 12 | } Tree_t; 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | __declspec_dll void treeInit(struct Tree_t* node); 19 | __declspec_dll struct Tree_t* treeRoot(const struct Tree_t* node); 20 | __declspec_dll void treeInsertChild(struct Tree_t* parent_node, struct Tree_t* new_node); 21 | __declspec_dll void treeInsertLeft(struct Tree_t* node, struct Tree_t* new_node); 22 | __declspec_dll void treeInsertRight(struct Tree_t* node, struct Tree_t* new_node); 23 | __declspec_dll void treeRemove(struct Tree_t* node); 24 | 25 | __declspec_dll struct Tree_t* treeBegin(struct Tree_t* node); 26 | __declspec_dll struct Tree_t* treeNext(struct Tree_t* node); 27 | __declspec_dll struct Tree_t* treeLevelBegin(struct Tree_t* node); 28 | __declspec_dll struct Tree_t* treeLevelNext(struct Tree_t* node); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif // !UTIL_DATASTRUCT_TREE_H_ 35 | -------------------------------------------------------------------------------- /inc/datastruct/url.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_DATASTRUCT_URL_H 6 | #define UTIL_C_DATASTRUCT_URL_H 7 | 8 | #include "../compiler_define.h" 9 | 10 | typedef struct URL_t { 11 | const char* schema; 12 | const char* user; 13 | const char* pwd; 14 | const char* host; 15 | const char* port; 16 | const char* path; 17 | const char* query; 18 | const char* fragment; 19 | 20 | unsigned int schema_slen; 21 | unsigned int user_slen; 22 | unsigned int pwd_slen; 23 | unsigned int host_slen; 24 | unsigned int path_slen; 25 | unsigned int query_slen; 26 | unsigned int fragment_slen; 27 | unsigned short port_slen; 28 | unsigned short port_number; 29 | } URL_t; 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | __declspec_dll URL_t* urlParse(URL_t* url, const char* str, UnsignedPtr_t slen); 36 | __declspec_dll unsigned int urlEncode(const char* src, unsigned int srclen, char* dst); 37 | __declspec_dll unsigned int urlDecode(const char* src, unsigned int srclen, char* dst); 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /inc/platform_define.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_PLATFORM_DEFINE_H 6 | #define UTIL_C_PLATFORM_DEFINE_H 7 | 8 | #include "compiler_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #ifndef _WIN32_WINNT 12 | #define _WIN32_WINNT 0xFFFFFFFF 13 | #endif 14 | #ifndef WINVER 15 | #define WINVER 0xFFFFFFFF 16 | #endif 17 | #ifndef _WIN32_IE 18 | #define _WIN32_IE 0xFFFFFFFF 19 | #endif 20 | #ifndef _CRT_SECURE_NO_WARNINGS 21 | #define _CRT_SECURE_NO_WARNINGS 22 | #endif 23 | #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS 24 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 25 | #endif 26 | #ifndef _CRT_RAND_S 27 | #define _CRT_RAND_S 28 | #endif 29 | #ifndef UMDF_USING_NTSTATUS 30 | #define UMDF_USING_NTSTATUS 31 | #endif 32 | #ifndef NOMINMAX 33 | #define NOMINMAX 34 | #endif 35 | #include 36 | #include 37 | #include 38 | #include 39 | STATIC_ASSERT(sizeof(HANDLE) == sizeof(SOCKET), ""); 40 | typedef SOCKET FD_t; 41 | #define INVALID_FD_HANDLE ((SOCKET)INVALID_HANDLE_VALUE) 42 | typedef SSIZE_T ssize_t; 43 | #else 44 | #ifndef _REENTRANT 45 | #define _REENTRANT 46 | #endif 47 | #ifndef _XOPEN_SOURCE 48 | #define _XOPEN_SOURCE 49 | #endif 50 | #ifdef __linux__ 51 | #ifndef _GNU_SOURCE 52 | #define _GNU_SOURCE 53 | #endif 54 | #endif 55 | #undef _FILE_OFFSET_BITS 56 | #define _FILE_OFFSET_BITS 64 57 | #include 58 | #include 59 | #include 60 | #include 61 | typedef int BOOL; 62 | #define TRUE 1 63 | #define FALSE 0 64 | typedef int FD_t; 65 | #define INVALID_FD_HANDLE -1 66 | #endif 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /inc/sysapi/aio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #if defined(_WIN32) || defined(USE_UNIX_AIO_API) 6 | 7 | #ifndef UTIL_C_SYSLIB_AIO_H 8 | #define UTIL_C_SYSLIB_AIO_H 9 | 10 | #include "atomic.h" 11 | #include "io_overlapped.h" 12 | #ifdef __linux__ 13 | #include 14 | #endif 15 | 16 | #if defined(_WIN32) || defined(_WIN64) 17 | #include 18 | typedef OVERLAPPED_ENTRY AioEv_t; 19 | #pragma comment(lib, "wsock32.lib") 20 | #pragma comment(lib, "ws2_32.lib") 21 | #else 22 | typedef struct AioEv_t { 23 | IoOverlapped_t* ol; 24 | } AioEv_t; 25 | #endif 26 | 27 | typedef struct AioOverlappedStream_t { 28 | IoOverlapped_t* head; 29 | IoOverlapped_t* tail; 30 | IoOverlapped_t* running; 31 | } AioOverlappedStream_t; 32 | 33 | typedef struct AioFD_t { 34 | FD_t fd; 35 | int domain; 36 | int socktype; 37 | int protocol; 38 | AioOverlappedStream_t* stream_rq; 39 | AioOverlappedStream_t* stream_wq; 40 | /* private */ 41 | struct AioFD_t* __lprev; 42 | struct AioFD_t* __lnext; 43 | IoOverlapped_t* __ol_pending_list_tail; 44 | short __delete_flag; 45 | short __reg; 46 | } AioFD_t; 47 | 48 | typedef struct Aio_t { 49 | #if defined(_WIN32) || defined(_WIN64) 50 | HANDLE __handle; 51 | #elif __linux__ 52 | struct io_uring __r; 53 | int __wakeup_fds[2]; 54 | #endif 55 | Atom16_t __wakeup; 56 | AioFD_t* __alive_list_head; 57 | AioFD_t* __delete_list_head; 58 | AioFD_t* __dead_list_head; 59 | void(*__fn_free_aiofd)(AioFD_t*); 60 | } Aio_t; 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | __declspec_dll Aio_t* aioCreate(Aio_t* aio, void(*fn_free_aiofd)(AioFD_t*), unsigned int entries); 67 | __declspec_dll BOOL aioClose(Aio_t* aio); 68 | 69 | __declspec_dll AioFD_t* aiofdInit(AioFD_t* aiofd, FD_t fd); 70 | __declspec_dll void aiofdDelete(Aio_t* aio, AioFD_t* aiofd); 71 | 72 | __declspec_dll BOOL aioCommit(Aio_t* aio, AioFD_t* aiofd, IoOverlapped_t* ol, int ol_flags); 73 | __declspec_dll int aioWait(Aio_t* aio, AioEv_t* e, unsigned int n, int msec); 74 | __declspec_dll void aioWakeup(Aio_t* aio); 75 | __declspec_dll IoOverlapped_t* aioEventCheck(Aio_t* aio, const AioEv_t* e, AioFD_t** ol_aiofd); 76 | __declspec_dll BOOL aioAckOverlappedStream(Aio_t* aio, AioFD_t* aiofd, IoOverlapped_t* ol); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /inc/sysapi/assert.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_ASSERT_H 6 | #define UTIL_C_SYSLIB_ASSERT_H 7 | 8 | #include "../platform_define.h" 9 | #include 10 | #include 11 | #include 12 | 13 | #define assertTRUE(exp)\ 14 | if (!(exp)) {\ 15 | fputs(__FILE__"(" MACRO_TOSTRING(__LINE__) "): " #exp "\r\n", stderr);\ 16 | abort();\ 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /inc/sysapi/atomic.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_ATOMIC_H 6 | #define UTIL_C_SYSLIB_ATOMIC_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | typedef CHAR volatile Atom8_t; 12 | typedef SHORT volatile Atom16_t; 13 | typedef LONG volatile Atom32_t; 14 | typedef LONGLONG volatile Atom64_t; 15 | #define _xchg8(addr, val8) InterlockedExchange8(addr, val8) 16 | #define _xchg16(addr, val16) InterlockedExchange16(addr, val16) 17 | #define _xchg32(addr, val32) InterlockedExchange(addr, val32) 18 | #define _xchg64(addr, val64) InterlockedExchange64(addr, val64) 19 | #define _cmpxchg16(addr, val16, cmp16) InterlockedCompareExchange16(addr, val16, cmp16) 20 | #define _cmpxchg32(addr, val32, cmp32) InterlockedCompareExchange(addr, val32, cmp32) 21 | #define _cmpxchg64(addr, val64, cmp64) InterlockedCompareExchange64(addr, val64, cmp64) 22 | #define _xadd32(addr, val32) InterlockedExchangeAdd(addr, val32) 23 | #define _xadd64(addr, val64) InterlockedExchangeAdd64(addr, val64) 24 | #ifdef _WIN64 25 | #define _xchgsize _xchg64 26 | #define _cmpxchgsize _cmpxchg64 27 | #define _xaddsize _xadd64 28 | typedef Atom64_t AtomSSize_t; 29 | #else 30 | #define _xchgsize _xchg32 31 | #define _cmpxchgsize _cmpxchg32 32 | #define _xaddsize _xadd32 33 | typedef Atom32_t AtomSSize_t; 34 | #endif 35 | #else 36 | typedef signed char volatile Atom8_t; 37 | typedef short volatile Atom16_t; 38 | typedef int volatile Atom32_t; 39 | typedef long long volatile Atom64_t; 40 | typedef ssize_t volatile AtomSSize_t; 41 | #define _xchg8(addr, val8) __sync_lock_test_and_set((signed char volatile*)(addr), (signed char)(val8)) 42 | #define _xchg16(addr, val16) __sync_lock_test_and_set((short volatile*)(addr), (short)(val16)) 43 | #define _xchg32(addr, val32) __sync_lock_test_and_set((int volatile*)(addr), (int)(val32)) 44 | #define _xchg64(addr, val64) __sync_lock_test_and_set((long long volatile*)(addr), (long long)(val64)) 45 | #define _xchgsize(addr, val) __sync_lock_test_and_set((ssize_t volatile*)(addr), (ssize_t)(val)) 46 | #define _cmpxchg16(addr, val16, cmp16) __sync_val_compare_and_swap((short volatile*)(addr), (short)(cmp16), (short)(val16)) 47 | #define _cmpxchg32(addr, val32, cmp32) __sync_val_compare_and_swap((int volatile*)(addr), (int)(cmp32), (int)(val32)) 48 | #define _cmpxchg64(addr, val64, cmp64) __sync_val_compare_and_swap((long long volatile*)(addr), (long long)(cmp64), (long long)(val64)) 49 | #define _cmpxchgsize(addr, val, cmp) __sync_val_compare_and_swap((ssize_t volatile*)(addr), (ssize_t)(cmp), (ssize_t)(val)) 50 | #define _xadd32(addr, val32) __sync_fetch_and_add((int volatile*)(addr), (int)(val32)) 51 | #define _xadd64(addr, val64) __sync_fetch_and_add((long long volatile*)(addr), (long long)(val64)) 52 | #define _xaddsize(addr, val) __sync_fetch_and_add((ssize_t volatile*)(addr), (ssize_t)(val)) 53 | #endif 54 | 55 | typedef Atom8_t AtomBool_t; 56 | 57 | #endif -------------------------------------------------------------------------------- /inc/sysapi/error.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_ERROR_H 6 | #define UTIL_C_SYSLIB_ERROR_H 7 | 8 | #include "../platform_define.h" 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | __declspec_dll int errnoGet(void); 16 | __declspec_dll void errnoSet(int errnum); 17 | __declspec_dll char* errnoText(int errnum, char* buf, size_t bufsize); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /inc/sysapi/file.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_FILE_H 6 | #define UTIL_C_SYSLIB_FILE_H 7 | 8 | #include "io_overlapped.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | typedef HANDLE Dir_t; 12 | typedef WIN32_FIND_DATAA DirItem_t; 13 | typedef HANDLE FD_Mapping_t; 14 | #pragma comment(lib, "ws2_32.lib") 15 | #else 16 | #include 17 | #include 18 | #include 19 | #include 20 | typedef DIR* Dir_t; 21 | typedef struct dirent* DirItem_t; 22 | typedef int FD_Mapping_t; 23 | #endif 24 | 25 | enum { 26 | FILE_READ_BIT = 0x01, 27 | FILE_WRITE_BIT = 0x02, 28 | FILE_APPEND_BIT = 0x04, 29 | FILE_CREAT_BIT = 0x08, 30 | FILE_EXCL_BIT = 0x10, 31 | FILE_TRUNC_BIT = 0x20, 32 | FILE_DSYNC_BIT = 0x40, 33 | FILE_ASYNC_BIT = 0x80, 34 | FILE_TEMP_BIT = 0x100 35 | }; 36 | 37 | enum FDtype_t { 38 | FD_TYPE_ERROR, 39 | FD_TYPE_UNKNOWN, 40 | FD_TYPE_DIRECTORY, 41 | FD_TYPE_REGULAR, 42 | FD_TYPE_SYMLINK, 43 | FD_TYPE_SOCKET, 44 | FD_TYPE_CHAR, 45 | FD_TYPE_PIPE 46 | }; 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | 52 | /* FD_t generate operator */ 53 | __declspec_dll enum FDtype_t fdType(FD_t fd); 54 | __declspec_dll BOOL fdGetInheritFlag(FD_t fd, BOOL* bool_val); 55 | __declspec_dll BOOL fdSetInheritFlag(FD_t fd, BOOL bool_val); 56 | __declspec_dll FD_t fdDup(FD_t fd); 57 | __declspec_dll FD_t fdDup2(FD_t oldfd, FD_t newfd); 58 | /* file operator */ 59 | __declspec_dll FD_t fdOpen(const char* path, int obit); 60 | __declspec_dll ssize_t fdRead(FD_t fd, void* buf, size_t nbytes); 61 | __declspec_dll ssize_t fdWrite(FD_t fd, const void* buf, size_t nbytes); 62 | __declspec_dll ssize_t fdWritev(FD_t fd, const Iobuf_t iov[], unsigned int iov_cnt); 63 | __declspec_dll long long fdSeekFromCurrent(FD_t fd, long long offset); 64 | __declspec_dll long long fdSeekFromBegin(FD_t fd, long long offset); 65 | __declspec_dll long long fdSeekFromEnd(FD_t fd, long long offset); 66 | __declspec_dll long long fdTell(FD_t fd); 67 | __declspec_dll BOOL fdFlush(FD_t fd); 68 | __declspec_dll BOOL fdClose(FD_t fd); 69 | __declspec_dll long long fdGetSize(FD_t fd); 70 | __declspec_dll BOOL fdSetLength(FD_t fd, long long length); 71 | /* file lock */ 72 | __declspec_dll BOOL fileLockExclusive(FD_t fd, long long offset, long long nbytes, BOOL block_bool); 73 | __declspec_dll BOOL fileLockShared(FD_t fd, long long offset, long long nbytes, BOOL block_bool); 74 | __declspec_dll BOOL fileUnlock(FD_t fd, long long offset, long long nbytes); 75 | /* file name */ 76 | __declspec_dll BOOL fileIsExist(const char* path); 77 | __declspec_dll const char* fileExtName(const char* path); 78 | __declspec_dll const char* fileFileName(const char* path); 79 | __declspec_dll char* fileReadAllData(const char* path, long long* ptr_file_sz); 80 | __declspec_dll ssize_t fileWriteCoverData(const char* path, const void* data, size_t len); 81 | /* file link */ 82 | __declspec_dll BOOL fileCreateSymlink(const char* actualpath, const char* sympath); 83 | __declspec_dll BOOL fileCreateHardLink(const char* existpath, const char* newpath); 84 | __declspec_dll BOOL fileHardLinkCount(FD_t fd, unsigned int* count); 85 | __declspec_dll BOOL fileDeleteHardLink(const char* existpath); 86 | /* file memory map */ 87 | __declspec_dll BOOL fdCreateMapping(FD_t fd, FD_Mapping_t* ret_mfd); 88 | __declspec_dll BOOL fdMapping(FD_Mapping_t mfd, void* va_base, long long offset, size_t nbytes, void** ret_mptr); 89 | __declspec_dll BOOL fdMappingSyncMemory(void* addr, size_t nbytes); 90 | __declspec_dll BOOL fdMappingUndoMemory(void* mptr, size_t nbytes); 91 | __declspec_dll BOOL fdMappingClose(FD_Mapping_t mfd); 92 | /* directory operator */ 93 | __declspec_dll BOOL dirCreate(const char* path); 94 | __declspec_dll BOOL dirCurrentPath(char* buf, size_t n); 95 | __declspec_dll BOOL dirSheftPath(const char* path); 96 | __declspec_dll Dir_t dirOpen(const char* path); 97 | __declspec_dll BOOL dirClose(Dir_t dir); 98 | __declspec_dll BOOL dirRead(Dir_t dir, DirItem_t* item); 99 | __declspec_dll char* dirFileName(DirItem_t* item); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /inc/sysapi/io_overlapped.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_IO_OVERLAPPED_H 6 | #define UTIL_C_SYSLIB_IO_OVERLAPPED_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | typedef WSABUF Iobuf_t; 13 | #define iobufStaticInit(p, n) { (ULONG)(n), (char*)(p) } 14 | #define iobufPtr(iobuf) ((iobuf)->buf) 15 | #define iobufLen(iobuf) ((iobuf)->len) 16 | #else 17 | #include 18 | typedef struct iovec Iobuf_t; 19 | #define iobufStaticInit(p, n) { (void*)(p), n } 20 | #define iobufPtr(iobuf) ((iobuf)->iov_base) 21 | #define iobufLen(iobuf) ((iobuf)->iov_len) 22 | #endif 23 | 24 | enum { 25 | IO_OVERLAPPED_OP_INTERNAL_FD_CLOSE = -1, 26 | /* public */ 27 | IO_OVERLAPPED_OP_READ = 1, 28 | IO_OVERLAPPED_OP_WRITE = 2, 29 | IO_OVERLAPPED_OP_ACCEPT = 3, 30 | IO_OVERLAPPED_OP_CONNECT = 4, 31 | }; 32 | 33 | enum { 34 | IO_OVERLAPPED_FLAG_BIT_WRITE_ZC = 0x1, /* linux io_uring maybe support... */ 35 | }; 36 | 37 | typedef struct IoOverlapped_t { 38 | #if defined(_WIN32) || defined(_WIN64) 39 | OVERLAPPED ol; /* private */ 40 | DWORD transfer_bytes; 41 | #else 42 | #ifdef __linux__ 43 | int __wait_cqe_notify; /* private */ 44 | #endif 45 | union { 46 | int __fd; /* private */ 47 | int retval; 48 | unsigned int transfer_bytes; 49 | }; 50 | void* __completion_key; /* private */ 51 | #endif 52 | void(*on_destroy)(struct IoOverlapped_t*); 53 | void* udata; 54 | Iobuf_t iobuf; 55 | int error; 56 | unsigned char commit; 57 | unsigned char free_flag; 58 | short opcode; 59 | int flag_bits; 60 | unsigned int bytes_off; 61 | struct IoOverlapped_t* __prev; /* private */ 62 | struct IoOverlapped_t* __next; /* private */ 63 | } IoOverlapped_t; 64 | 65 | /* note: internal define, not direct use */ 66 | 67 | #if defined(_WIN32) || defined(_WIN64) 68 | typedef struct { 69 | IoOverlapped_t base; 70 | struct sockaddr_storage saddr; 71 | int saddrlen; 72 | DWORD dwFlags; 73 | WSABUF wsabuf; 74 | unsigned int appendsize; 75 | unsigned char append_data[1]; /* convienent for text data */ 76 | } IocpReadOverlapped_t, IocpWriteOverlapped_t, IocpConnectExOverlapped_t; 77 | 78 | typedef struct IocpAcceptExOverlapped_t { 79 | IoOverlapped_t base; 80 | SOCKET acceptsocket; 81 | SOCKET listensocket; 82 | union { 83 | struct { 84 | struct sockaddr_storage peer_saddr; 85 | int peer_saddrlen; 86 | }; 87 | unsigned char saddr_bytes[sizeof(struct sockaddr_storage) + 16 + sizeof(struct sockaddr_storage) + 16]; 88 | }; 89 | } IocpAcceptExOverlapped_t; 90 | #else 91 | typedef struct { 92 | IoOverlapped_t base; 93 | struct msghdr msghdr; 94 | struct sockaddr_storage saddr; 95 | off_t fd_offset; 96 | struct iovec iov; 97 | unsigned int appendsize; 98 | unsigned char append_data[1]; /* convienent for text data */ 99 | } UnixReadOverlapped_t, UnixWriteOverlapped_t; 100 | 101 | typedef struct { 102 | IoOverlapped_t base; 103 | struct sockaddr_storage saddr; 104 | socklen_t saddrlen; 105 | } UnixConnectOverlapped_t, UnixAcceptOverlapped_t; 106 | #endif 107 | 108 | #ifdef __cplusplus 109 | extern "C" { 110 | #endif 111 | 112 | __declspec_dll void iobufSkip(const Iobuf_t* iov, size_t iovcnt, size_t* iov_i, size_t* iov_off, size_t n); 113 | __declspec_dll size_t iobufShardCopy(const Iobuf_t* iov, size_t iovcnt, size_t* iov_i, size_t* iov_off, void* buf, size_t n); 114 | 115 | __declspec_dll IoOverlapped_t* IoOverlapped_alloc(int opcode, unsigned int appendsize); 116 | __declspec_dll Iobuf_t* IoOverlapped_get_append_iobuf(const IoOverlapped_t* ol, Iobuf_t* iobuf); 117 | __declspec_dll struct sockaddr* IoOverlapped_get_peer_sockaddr(const IoOverlapped_t* ol, struct sockaddr* saddr, socklen_t* plen); 118 | __declspec_dll void IoOverlapped_set_peer_sockaddr(IoOverlapped_t* ol, const struct sockaddr* saddr, socklen_t saddrlen); 119 | __declspec_dll long long IoOverlapped_get_file_offset(const IoOverlapped_t* ol); 120 | __declspec_dll IoOverlapped_t* IoOverlapped_set_file_offest(IoOverlapped_t* ol, long long offset); 121 | __declspec_dll FD_t IoOverlapped_pop_acceptfd(IoOverlapped_t* ol, struct sockaddr* p_peer_saddr, socklen_t* plen); 122 | __declspec_dll void IoOverlapped_free(IoOverlapped_t* ol); 123 | __declspec_dll int IoOverlapped_check_reuse_able(const IoOverlapped_t* ol); 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /inc/sysapi/ipc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_IPC_H 6 | #define UTIL_C_SYSLIB_IPC_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | typedef CRITICAL_SECTION CriticalSection_t; 13 | typedef CONDITION_VARIABLE ConditionVariable_t; 14 | typedef HANDLE Mutex_t; 15 | typedef HANDLE Semaphore_t; 16 | typedef struct RWLock_t { 17 | volatile BOOL __exclusive_lock; 18 | volatile LONG __read_cnt; 19 | HANDLE __read_ev, __write_ev, __wait_ev; 20 | } RWLock_t; 21 | typedef INIT_ONCE InitOnce_t; 22 | #define SEM_FAILED NULL 23 | #else 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | typedef pthread_mutex_t CriticalSection_t; 31 | typedef pthread_cond_t ConditionVariable_t; 32 | typedef pthread_mutex_t Mutex_t; 33 | typedef sem_t* Semaphore_t; 34 | typedef pthread_rwlock_t RWLock_t; 35 | typedef pthread_once_t InitOnce_t; 36 | #define INIT_ONCE_STATIC_INIT PTHREAD_ONCE_INIT 37 | #endif 38 | #include 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /* signal */ 45 | __declspec_dll void signalReg(int signo); 46 | __declspec_dll BOOL signalThreadMaskNotify(void); 47 | __declspec_dll int signalWait(void); 48 | __declspec_dll void signalIdleHandler(int signo); 49 | /* pipe */ 50 | __declspec_dll BOOL pipeCreate(FD_t* r, FD_t* w); 51 | __declspec_dll BOOL pipeNonBlock(FD_t pipefd, BOOL bool_val); 52 | __declspec_dll int pipeReadableBytes(FD_t r); 53 | /* critical section */ 54 | __declspec_dll CriticalSection_t* criticalsectionCreate(CriticalSection_t* cs); 55 | __declspec_dll BOOL criticalsectionTryEnter(CriticalSection_t* cs); 56 | __declspec_dll void criticalsectionEnter(CriticalSection_t* cs); 57 | __declspec_dll void criticalsectionLeave(CriticalSection_t* cs); 58 | __declspec_dll void criticalsectionClose(CriticalSection_t* cs); 59 | /* condition */ 60 | __declspec_dll ConditionVariable_t* conditionvariableCreate(ConditionVariable_t* condition); 61 | __declspec_dll BOOL conditionvariableWait(ConditionVariable_t* condition, CriticalSection_t* cs, int msec); 62 | __declspec_dll void conditionvariableSignal(ConditionVariable_t* condition); 63 | __declspec_dll void conditionvariableBroadcast(ConditionVariable_t* condition); 64 | __declspec_dll void conditionvariableClose(ConditionVariable_t* condition); 65 | /* mutex */ 66 | __declspec_dll Mutex_t* mutexCreate(Mutex_t* mutex); 67 | __declspec_dll BOOL mutexTryLock(Mutex_t* mutex); 68 | __declspec_dll void mutexLock(Mutex_t* mutex); 69 | __declspec_dll void mutexUnlock(Mutex_t* mutex); 70 | __declspec_dll void mutexClose(Mutex_t* mutex); 71 | /* read/write lock */ 72 | __declspec_dll RWLock_t* rwlockCreate(RWLock_t* rwlock); 73 | __declspec_dll void rwlockLockRead(RWLock_t* rwlock); 74 | __declspec_dll void rwlockLockWrite(RWLock_t* rwlock); 75 | __declspec_dll void rwlockUnlock(RWLock_t* rwlock); 76 | __declspec_dll void rwlockClose(RWLock_t* rwlock); 77 | /* semaphore */ 78 | __declspec_dll Semaphore_t* semaphoreCreate(Semaphore_t* sem, const char* name, unsigned short val); 79 | __declspec_dll Semaphore_t* semaphoreOpen(Semaphore_t* sem, const char* name); 80 | __declspec_dll BOOL semaphoreTryWait(Semaphore_t* sem); 81 | __declspec_dll void semaphoreWait(Semaphore_t* sem); 82 | __declspec_dll void semaphorePost(Semaphore_t* sem); 83 | __declspec_dll void semaphoreClose(Semaphore_t* sem); 84 | __declspec_dll BOOL semaphoreUnlink(const char* name); 85 | /* once call */ 86 | __declspec_dll InitOnce_t* initonceCall(InitOnce_t* once, void(*callback)(void)); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /inc/sysapi/misc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_MISC_H 6 | #define UTIL_C_SYSLIB_MISC_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #ifndef alloca 13 | #define alloca _alloca 14 | #endif 15 | #else 16 | #if __linux__ 17 | #include 18 | #include 19 | #endif 20 | #endif 21 | #include 22 | 23 | #define alignedAlloca(nbytes, alignment)\ 24 | ((void*)(((size_t)alloca(nbytes + alignment)) + (alignment - 1) & ~(((size_t)alignment) - 1))) 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | __declspec_dll void* alignMalloc(size_t nbytes, size_t alignment); 31 | __declspec_dll void alignFree(const void* p); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /inc/sysapi/mmap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_MMAP_H 6 | #define UTIL_C_SYSLIB_MMAP_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | typedef HANDLE ShareMemMap_t; 12 | #else 13 | typedef int ShareMemMap_t; 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | __declspec_dll BOOL memoryCreateMapping(ShareMemMap_t* mm, const char* name, size_t nbytes); 21 | __declspec_dll BOOL memoryOpenMapping(ShareMemMap_t* mm, const char* name); 22 | __declspec_dll BOOL memoryCloseMapping(ShareMemMap_t mm); 23 | __declspec_dll BOOL memoryDoMapping(ShareMemMap_t mm, void* va_base, size_t nbytes, void** ret_mptr); 24 | __declspec_dll BOOL memoryUndoMapping(void* mptr); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /inc/sysapi/module.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_MODULE_H 6 | #define UTIL_C_SYSLIB_MODULE_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #else 13 | #if __linux__ 14 | #include 15 | #endif 16 | #include 17 | #endif 18 | 19 | #if defined(_WIN32) || defined(_WIN64) 20 | #define moduleLoad(path) ((void*)LoadLibraryA(path)) 21 | #define moduleSymbolAddress(md, symbol_name) ((void*)GetProcAddress((HMODULE)md, symbol_name)) 22 | #define moduleUnload(md) (md ? FreeLibrary((HMODULE)md) : TRUE) 23 | #else 24 | #define moduleLoad(path) dlopen(path, RTLD_NOW) 25 | #define moduleSymbolAddress(md, symbol_name) dlsym(md, symbol_name) 26 | #define moduleUnload(md) (md ? (dlclose(md) == 0) : 1) 27 | #endif 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | __declspec_dll void* moduleAddress(const void* symbol_addr); 34 | __declspec_dll size_t modulePathLength(void* md); 35 | __declspec_dll size_t moduleFillPath(void* md, char* buf, size_t n); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /inc/sysapi/nio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_NIO_H 6 | #define UTIL_C_SYSLIB_NIO_H 7 | 8 | #include "atomic.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include "io_overlapped.h" 12 | #include 13 | typedef OVERLAPPED_ENTRY NioEv_t; 14 | #pragma comment(lib, "wsock32.lib") 15 | #pragma comment(lib, "ws2_32.lib") 16 | #elif defined(__FreeBSD__) || defined(__APPLE__) 17 | #include 18 | #include 19 | typedef struct kevent NioEv_t; 20 | #elif __linux__ 21 | #include 22 | typedef struct epoll_event NioEv_t; 23 | #endif 24 | struct sockaddr; 25 | struct sockaddr_storage; 26 | 27 | /* not support disk file io */ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* nio */ 34 | enum { 35 | NIO_OP_READ = 1, 36 | NIO_OP_WRITE = 2, 37 | NIO_OP_ACCEPT = 4, 38 | NIO_OP_CONNECT = 8 39 | }; 40 | 41 | typedef struct NioFD_t { 42 | FD_t fd; 43 | struct NioFD_t* __lprev; 44 | struct NioFD_t* __lnext; 45 | short __delete_flag; 46 | short __reg; 47 | #if defined(_WIN32) || defined(_WIN64) 48 | int __domain; 49 | IoOverlapped_t* __read_ol; 50 | IoOverlapped_t* __write_ol; 51 | #else 52 | unsigned int __event_mask; 53 | #endif 54 | } NioFD_t; 55 | 56 | typedef struct Nio_t { 57 | FD_t __hNio; 58 | #if defined(_WIN32) || defined(_WIN64) 59 | IoOverlapped_t* __ol_list_head; 60 | #else 61 | FD_t __socketpair[2]; 62 | #endif 63 | Atom16_t __wakeup; 64 | NioFD_t* __alive_list_head; 65 | NioFD_t* __free_list_head; 66 | void(*__fn_free_niofd)(NioFD_t*); 67 | } Nio_t; 68 | 69 | __declspec_dll BOOL nioCreate(Nio_t* nio, void(*fn_free_niofd)(NioFD_t*)); 70 | __declspec_dll void niofdInit(NioFD_t* niofd, FD_t fd, int domain); 71 | __declspec_dll void niofdDelete(Nio_t* nio, NioFD_t* niofd); 72 | __declspec_dll BOOL nioCommit(Nio_t* nio, NioFD_t* niofd, int opcode, const struct sockaddr* saddr, socklen_t addrlen); 73 | __declspec_dll int nioWait(Nio_t* nio, NioEv_t* e, unsigned int count, int msec); 74 | __declspec_dll void nioWakeup(Nio_t* nio); 75 | __declspec_dll NioFD_t* nioEventCheck(Nio_t* nio, const NioEv_t* e, int* ev_mask); 76 | __declspec_dll int nioConnectUpdate(NioFD_t* niofd); 77 | __declspec_dll FD_t nioAccept(NioFD_t* niofd, struct sockaddr* peer_saddr, socklen_t* p_slen); 78 | __declspec_dll BOOL nioClose(Nio_t* nio); 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /inc/sysapi/process.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_PROCESS_H 6 | #define UTIL_C_SYSLIB_PROCESS_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #ifndef FIBER_FLAG_FLOAT_SWITCH 13 | #error "No such macro FIBER_FLAG_FLOAT_SWITCH" 14 | #endif 15 | /* 16 | #ifdef _MSC_VER 17 | #pragma warning(disable:4091)// avoid bug(dbghelp.h warning C4091: "typedef ") 18 | #endif 19 | #include 20 | #ifdef _MSC_VER 21 | #pragma warning(default:4091) 22 | #endif 23 | */ 24 | typedef struct { 25 | HANDLE handle; 26 | DWORD id; 27 | } Process_t; 28 | typedef struct { 29 | HANDLE handle; 30 | unsigned int id; 31 | } Thread_t; 32 | typedef DWORD Tls_t; 33 | #define __declspec_tls __declspec(thread) 34 | #pragma comment(lib, "Dbghelp.lib") 35 | #else 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #if __linux__ 42 | #include 43 | #endif 44 | /* 45 | #include 46 | */ 47 | typedef struct { 48 | pid_t id; 49 | } Process_t; 50 | typedef struct { 51 | pthread_t id; 52 | } Thread_t; 53 | typedef pthread_key_t Tls_t; 54 | #define __declspec_tls __thread 55 | #endif 56 | struct Fiber_t; 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | /* process operator */ 63 | __declspec_dll BOOL processCreate(Process_t* p_process, const char* path, const char* cmdarg); 64 | __declspec_dll BOOL processCancel(Process_t* process); 65 | __declspec_dll size_t processId(void); 66 | __declspec_dll BOOL processWait(Process_t process, unsigned char* retcode); 67 | __declspec_dll BOOL processTryWait(Process_t process, unsigned char* retcode); 68 | /* thread operator */ 69 | __declspec_dll BOOL threadCreate(Thread_t* p_thread, unsigned int stack_size, unsigned int(*entry)(void*), void* arg); 70 | __declspec_dll BOOL threadDetach(Thread_t thread); 71 | __declspec_dll BOOL threadJoin(Thread_t thread, unsigned int* retcode); 72 | __declspec_dll void threadExit(unsigned int retcode); 73 | __declspec_dll BOOL threadEqual(Thread_t t1, Thread_t t2); 74 | __declspec_dll Thread_t threadSelf(void); 75 | __declspec_dll void threadPause(void); 76 | __declspec_dll void threadSleepMillsecond(unsigned int msec); 77 | __declspec_dll void threadYield(void); 78 | __declspec_dll BOOL threadSetAffinity(Thread_t thread, unsigned int processor_index); 79 | /* thread local operator */ 80 | __declspec_dll BOOL threadAllocLocalKey(Tls_t* key); 81 | __declspec_dll BOOL threadSetLocalValue(Tls_t key, void* value); 82 | __declspec_dll void* threadGetLocalValue(Tls_t key); 83 | __declspec_dll BOOL threadFreeLocalKey(Tls_t key); 84 | /* fiber operator */ 85 | __declspec_dll struct Fiber_t* fiberFromThread(void); 86 | __declspec_dll struct Fiber_t* fiberCreate(struct Fiber_t* cur_fiber, size_t stack_size, void (*entry)(struct Fiber_t*, void*), void* arg); 87 | __declspec_dll void fiberSwitch(struct Fiber_t* cur, struct Fiber_t* to, int cur_dead); 88 | __declspec_dll int fiberIsDead(struct Fiber_t* fiber); 89 | __declspec_dll void fiberFree(struct Fiber_t* fiber); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /inc/sysapi/statistics.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_STATISTICS_H 6 | #define UTIL_C_SYSLIB_STATISTICS_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | //typedef char HOST_NAME[MAX_COMPUTERNAME_LENGTH + 1]; 12 | #else 13 | #include 14 | #include 15 | #include 16 | #ifdef __linux__ 17 | #include 18 | #include 19 | #include 20 | //typedef char HOST_NAME[HOST_NAME_MAX + 1]; 21 | #elif defined(__FreeBSD__) || defined(__APPLE__) 22 | #include 23 | //typedef char HOST_NAME[_POSIX_HOST_NAME_MAX + 1]; 24 | #endif 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | __declspec_dll long memoryPageSize(void); 32 | __declspec_dll unsigned long long memorySize(void); 33 | __declspec_dll size_t processorCount(void); 34 | __declspec_dll char* systemCurrentLoginUsername(char* buffer, size_t nbytes); 35 | __declspec_dll char* systemHostname(char* buf, size_t len); 36 | __declspec_dll BOOL diskPartitionSize(const char* dev_path, unsigned long long* total_bytes, unsigned long long* free_bytes, unsigned long long* availabel_bytes, unsigned long long* block_bytes); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /inc/sysapi/terminal.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_TERMINAL_H 6 | #define UTIL_C_SYSLIB_TERMINAL_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | __declspec_dll char* terminalName(char* buf, size_t buflen); 21 | __declspec_dll char* terminalOriginalName(char* buf, size_t buflen); 22 | __declspec_dll FD_t terminalStdin(void); 23 | __declspec_dll FD_t terminalStdout(void); 24 | __declspec_dll FD_t terminalStderr(void); 25 | __declspec_dll BOOL terminalFlushInput(FD_t fd); 26 | __declspec_dll BOOL terminalEnableEcho(FD_t fd, BOOL bval); 27 | __declspec_dll BOOL terminalEnableLineInput(FD_t fd, BOOL bval); 28 | __declspec_dll BOOL terminalEnableSignal(FD_t fd, BOOL bval); 29 | __declspec_dll BOOL terminalGetPageSize(FD_t fd, int* x_col, int* y_row); 30 | __declspec_dll BOOL terminalSetCursorPos(FD_t fd, int x_col, int y_row); 31 | __declspec_dll BOOL terminalShowCursor(FD_t fd, BOOL bval); 32 | __declspec_dll BOOL terminalClrscr(FD_t fd); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif // !UTIL_C_SYSLIB_TERMINAL_H 39 | -------------------------------------------------------------------------------- /inc/sysapi/time.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifndef UTIL_C_SYSLIB_TIME_H 6 | #define UTIL_C_SYSLIB_TIME_H 7 | 8 | #include "../platform_define.h" 9 | 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #else 13 | #include 14 | #endif 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | extern int TIMESTAMP_OFFSET_SECOND; 22 | 23 | /* time trasform */ 24 | __declspec_dll int gmtimeTimezoneOffsetSecond(void); 25 | __declspec_dll time_t gmtimeSecond(void); 26 | __declspec_dll time_t localWeekBeginGmtSecond(time_t gmt_sec, int tz_off); 27 | __declspec_dll time_t localtimeSecond(void); 28 | __declspec_dll long long gmtimeMillisecond(void); 29 | __declspec_dll struct tm* gmtimeTM(time_t value, struct tm* datetime); 30 | __declspec_dll struct tm* gmtimeLocalTM(time_t value, struct tm* datetime); 31 | __declspec_dll char* structtmText(struct tm* datetime, char* buf, size_t len); 32 | __declspec_dll struct tm* structtmNormal(struct tm* datetime); 33 | __declspec_dll struct tm* structtmUnnormal(struct tm* datetime); 34 | __declspec_dll int structtmCmp(const struct tm* t1, const struct tm* t2); 35 | __declspec_dll long long clockNanosecond(void); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /lib_compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | OBJECT_FILE=`find . -name "*.o"` 3 | SOURCE_C_FILE=`find . -name "*.c"` 4 | SOURCE_CPP_FILE=`find . -name "*.cpp"` 5 | MACRO="-D_REENTRANT" 6 | COMPILE_OPTION="-Wno-deprecated -Wno-parentheses -Wno-unused-result -Wreturn-type -fwrapv -fno-strict-aliasing -pthread" 7 | 8 | COMPILER="gcc" 9 | if [ $COMPILER == "gcc" ];then 10 | SOURCE_CPP_FILE="" 11 | fi 12 | if [ ! -n "$1" ];then 13 | echo "no spec build mode" 14 | exit 15 | elif [ $1 == "debug" ];then 16 | MACRO="-D_DEBUG $MACRO" 17 | COMPILE_OPTION="-g $COMPILE_OPTION" 18 | TARGET="libUtilStaticDebug.a" 19 | elif [ $1 == "asan" ];then 20 | MACRO="-D_DEBUG $MACRO" 21 | COMPILE_OPTION="-g -fsanitize=address $COMPILE_OPTION" 22 | TARGET="libUtilStaticAsan.a" 23 | elif [ $1 == "release" ];then 24 | MACRO="-DNDEBUG $MACRO" 25 | COMPILE_OPTION="-O2 $COMPILE_OPTION" 26 | TARGET="libUtilStatic.a" 27 | else 28 | echo "no spec build mode" 29 | exit 30 | fi 31 | 32 | rm $OBJECT_FILE 2>/dev/null 33 | rm $TARGET 2>/dev/null 34 | #find ./ -type f -exec touch {} \; 35 | echo "$COMPILER -c $MACRO $COMPILE_OPTION" $SOURCE_C_FILE $SOURCE_CPP_FILE 36 | $COMPILER -c $MACRO $COMPILE_OPTION $SOURCE_C_FILE $SOURCE_CPP_FILE 37 | if [ "$?" != 0 ];then 38 | OBJECT_FILE=`find . -name "*.o"` 39 | rm $OBJECT_FILE 2>/dev/null 40 | exit 41 | fi 42 | OBJECT_FILE=`find . -name "*.o"` 43 | echo "ar rcs $TARGET" $OBJECT_FILE 44 | ar rcs $TARGET $OBJECT_FILE 45 | rm $OBJECT_FILE 2>/dev/null 46 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | SOURCE_C_FILE += $(shell find . -name "*.c") 2 | SOURCE_CPP_FILE += $(shell find . -name "*.cpp") 3 | 4 | TARGET_PATH += . 5 | COMPILE_OPTION := -fPIC -shared -fvisibility=hidden -Wno-deprecated -Wno-parentheses -Wno-unused-result -Wreturn-type -flto -fwrapv -fno-strict-aliasing 6 | MACRO := -D_REENTRANT -DDECLSPEC_DLL_EXPORT 7 | 8 | DEFAULT_LINK := -pthread -lm -ldl 9 | ifeq ($(shell uname), Linux) 10 | DEFAULT_LINK += -lrt 11 | endif 12 | 13 | COMPILER := gcc 14 | ifeq ($(COMPILER), gcc) 15 | SOURCE_CPP_FILE := 16 | endif 17 | 18 | DEBUG_TARGET := $(TARGET_PATH)/libUtilDynamicDebug.so 19 | ASAN_TARGET := $(TARGET_PATH)/libUtilDynamicAsan.so 20 | RELEASE_TARGET := $(TARGET_PATH)/libUtilDynamic.so 21 | 22 | all: 23 | 24 | debug: 25 | $(COMPILER) $(MACRO) -D_DEBUG -g $(COMPILE_OPTION) $(SOURCE_C_FILE) $(SOURCE_CPP_FILE) -o $(DEBUG_TARGET) $(DEFAULT_LINK) 26 | 27 | asan: 28 | $(COMPILER) $(MACRO) -D_DEBUG -g -fsanitize=address $(COMPILE_OPTION) $(SOURCE_C_FILE) $(SOURCE_CPP_FILE) -o $(ASAN_TARGET) $(DEFAULT_LINK) 29 | 30 | release: 31 | $(COMPILER) $(MACRO) -DNDEBUG -O2 $(COMPILE_OPTION) $(SOURCE_C_FILE) $(SOURCE_CPP_FILE) -o $(RELEASE_TARGET) $(DEFAULT_LINK) 32 | -------------------------------------------------------------------------------- /src/component/dataqueue.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/assert.h" 6 | #include "../../inc/sysapi/error.h" 7 | #include "../../inc/component/dataqueue.h" 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | DataQueue_t* dataqueueInit(DataQueue_t* dq) { 14 | dq->m_initok = 0; 15 | if (!criticalsectionCreate(&dq->m_cslock)) { 16 | return NULL; 17 | } 18 | if (!conditionvariableCreate(&dq->m_condition)) { 19 | criticalsectionClose(&dq->m_cslock); 20 | return NULL; 21 | } 22 | listInit(&dq->m_datalist); 23 | dq->m_wakeup = 0; 24 | dq->m_initok = 1; 25 | return dq; 26 | } 27 | 28 | void dataqueuePush(DataQueue_t* dq, ListNode_t* data) { 29 | int is_empty; 30 | if (!data) { 31 | return; 32 | } 33 | 34 | criticalsectionEnter(&dq->m_cslock); 35 | 36 | is_empty = !dq->m_datalist.head; 37 | listInsertNodeBack(&dq->m_datalist, dq->m_datalist.tail, data); 38 | if (is_empty) { 39 | conditionvariableSignal(&dq->m_condition); 40 | } 41 | 42 | criticalsectionLeave(&dq->m_cslock); 43 | } 44 | 45 | void dataqueuePushList(DataQueue_t* dq, List_t* list) { 46 | int is_empty; 47 | if (!list->head || !list->tail) { 48 | return; 49 | } 50 | 51 | criticalsectionEnter(&dq->m_cslock); 52 | 53 | is_empty = !dq->m_datalist.head; 54 | listAppend(&dq->m_datalist, list); 55 | if (is_empty) { 56 | conditionvariableSignal(&dq->m_condition); 57 | } 58 | 59 | criticalsectionLeave(&dq->m_cslock); 60 | } 61 | 62 | ListNode_t* dataqueuePopWait(DataQueue_t* dq, int msec, size_t expect_cnt) { 63 | ListNode_t* res; 64 | if (0 == expect_cnt) { 65 | return NULL; 66 | } 67 | 68 | criticalsectionEnter(&dq->m_cslock); 69 | 70 | while (!dq->m_datalist.head && !_xchg8(&dq->m_wakeup, 0)) { 71 | if (conditionvariableWait(&dq->m_condition, &dq->m_cslock, msec)) { 72 | continue; 73 | } 74 | assertTRUE(errnoGet() == ETIMEDOUT); 75 | break; 76 | } 77 | 78 | res = dq->m_datalist.head; 79 | if (~0 == expect_cnt) { 80 | listInit(&dq->m_datalist); 81 | } 82 | else { 83 | ListNode_t *cur; 84 | for (cur = dq->m_datalist.head; cur && --expect_cnt; cur = cur->next); 85 | if (cur) 86 | res = listSplitByTail(&dq->m_datalist, cur).head; 87 | else 88 | listInit(&dq->m_datalist); 89 | } 90 | 91 | criticalsectionLeave(&dq->m_cslock); 92 | 93 | return res; 94 | } 95 | 96 | void dataqueueWake(DataQueue_t* dq) { 97 | if (_xchg8(&dq->m_wakeup, 1)) 98 | return; 99 | criticalsectionEnter(&dq->m_cslock); 100 | conditionvariableSignal(&dq->m_condition); 101 | criticalsectionLeave(&dq->m_cslock); 102 | } 103 | 104 | ListNode_t* dataqueueClean(DataQueue_t* dq) { 105 | ListNode_t* head; 106 | 107 | criticalsectionEnter(&dq->m_cslock); 108 | 109 | head = dq->m_datalist.head; 110 | listInit(&dq->m_datalist); 111 | 112 | criticalsectionLeave(&dq->m_cslock); 113 | 114 | return head; 115 | } 116 | 117 | ListNode_t* dataqueueDestroy(DataQueue_t* dq) { 118 | if (dq && dq->m_initok) { 119 | ListNode_t* head = dataqueueClean(dq); 120 | criticalsectionClose(&dq->m_cslock); 121 | conditionvariableClose(&dq->m_condition); 122 | return head; 123 | } 124 | return NULL; 125 | } 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | -------------------------------------------------------------------------------- /src/component/memheap_mt.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/component/memheap_mt.h" 6 | #include "../../inc/datastruct/memheap.h" 7 | #include 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | MemHeapMt_t* memheapmtCreate(MemHeapMt_t* memheap, size_t len, const char* name) { 15 | int ok; 16 | size_t namelen = strlen(name); 17 | char* name_ext = (char*)malloc(namelen + 5); 18 | memheap->initok = 0; 19 | if (!name_ext) 20 | return NULL; 21 | strcpy(name_ext, name); 22 | strcat(name_ext, "init"); 23 | if (!semaphoreCreate(&memheap->seminit, name_ext, 1)) { 24 | free(name_ext); 25 | return NULL; 26 | } 27 | semaphoreWait(&memheap->seminit); 28 | do { 29 | void* addr; 30 | ok = 0; 31 | name_ext[namelen] = 0; 32 | if (!semaphoreCreate(&memheap->semlock, strcat(name_ext, "lock"), 1)) 33 | break; 34 | ok = 1; 35 | name_ext[namelen] = 0; 36 | if (!memoryCreateMapping(&memheap->mm, strcat(name_ext, "mem"), len)) 37 | break; 38 | ok = 2; 39 | if (!memoryDoMapping(memheap->mm, NULL, len, &addr)) 40 | break; 41 | memheap->ptr = (struct MemHeap_t*)addr; 42 | if (!memheap->ptr) 43 | break; 44 | memheapSetup(memheap->ptr, len); 45 | ok = 3; 46 | } while (0); 47 | semaphorePost(&memheap->seminit); 48 | if (ok < 3) { 49 | semaphoreClose(&memheap->seminit); 50 | semaphoreUnlink(strcat(strcpy(name_ext, name), "init")); 51 | if (ok > 0) { 52 | semaphoreClose(&memheap->semlock); 53 | semaphoreUnlink(strcat(strcpy(name_ext, name), "lock")); 54 | } 55 | if (ok > 1) { 56 | memoryCloseMapping(memheap->mm); 57 | } 58 | free(name_ext); 59 | return NULL; 60 | } 61 | memheap->len = len; 62 | memheap->name_ext = name_ext; 63 | memheap->namelen = namelen; 64 | memheap->initok = 1; 65 | memheap->is_open = 0; 66 | return memheap; 67 | } 68 | 69 | MemHeapMt_t* memheapmtOpen(MemHeapMt_t* memheap, size_t len, const char* name) { 70 | int ok; 71 | size_t namelen = strlen(name); 72 | char* name_ext = (char*)malloc(namelen + 5); 73 | memheap->initok = 0; 74 | if (!name_ext) 75 | return NULL; 76 | strcpy(name_ext, name); 77 | strcat(name_ext, "init"); 78 | if (!semaphoreOpen(&memheap->seminit, name_ext)) { 79 | free(name_ext); 80 | return NULL; 81 | } 82 | semaphoreWait(&memheap->seminit); 83 | do { 84 | void* addr; 85 | ok = 0; 86 | name_ext[namelen] = 0; 87 | if (!semaphoreOpen(&memheap->semlock, strcat(name_ext, "lock"))) 88 | break; 89 | ok = 1; 90 | name_ext[namelen] = 0; 91 | if (!memoryOpenMapping(&memheap->mm, strcat(name_ext, "mem"))) 92 | break; 93 | ok = 2; 94 | if (!memoryDoMapping(memheap->mm, NULL, len, &addr)) 95 | break; 96 | memheap->ptr = (struct MemHeap_t*)addr; 97 | if (!memheap->ptr) 98 | break; 99 | ok = 3; 100 | } while (0); 101 | semaphorePost(&memheap->seminit); 102 | semaphoreClose(&memheap->seminit); 103 | if (ok < 3) { 104 | free(name_ext); 105 | if (ok > 0) 106 | semaphoreClose(&memheap->semlock); 107 | if (ok > 1) 108 | memoryCloseMapping(memheap->mm); 109 | return NULL; 110 | } 111 | memheap->len = len; 112 | memheap->name_ext = name_ext; 113 | memheap->namelen = namelen; 114 | memheap->initok = 1; 115 | memheap->is_open = 1; 116 | return memheap; 117 | } 118 | 119 | void* memheapmtAlloc(MemHeapMt_t* memheap, size_t nbytes) { 120 | void* addr; 121 | semaphoreWait(&memheap->semlock); 122 | addr = memheapAlloc(memheap->ptr, nbytes); 123 | semaphorePost(&memheap->semlock); 124 | return addr; 125 | } 126 | 127 | void memheapmtFree(MemHeapMt_t* memheap, void* addr) { 128 | if (addr) { 129 | semaphoreWait(&memheap->semlock); 130 | memheapFree(memheap->ptr, addr); 131 | semaphorePost(&memheap->semlock); 132 | } 133 | } 134 | 135 | void memheapmtClose(MemHeapMt_t* memheap) { 136 | if (memheap->initok) { 137 | memheap->initok = 0; 138 | memoryUndoMapping(memheap->ptr); 139 | memoryCloseMapping(memheap->mm); 140 | semaphoreClose(&memheap->semlock); 141 | if (!memheap->is_open) { 142 | semaphoreClose(&memheap->seminit); 143 | 144 | memheap->name_ext[memheap->namelen] = 0; 145 | semaphoreUnlink(strcat(memheap->name_ext, "init")); 146 | memheap->name_ext[memheap->namelen] = 0; 147 | semaphoreUnlink(strcat(memheap->name_ext, "lock")); 148 | } 149 | free(memheap->name_ext); 150 | } 151 | } 152 | 153 | #ifdef __cplusplus 154 | } 155 | #endif 156 | -------------------------------------------------------------------------------- /src/component/memref.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/component/memref.h" 6 | #include "../../inc/sysapi/atomic.h" 7 | #include 8 | 9 | typedef struct MemRef_t { 10 | void* p; 11 | void(*fn_free)(void*); 12 | Atom32_t sp_cnt; 13 | Atom32_t wp_cnt; 14 | } MemRef_t; 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | MemRef_t* memrefCreate(void* p, void(*fn_free)(void*)) { 21 | if (p) { 22 | MemRef_t* ref = (MemRef_t*)malloc(sizeof(MemRef_t)); 23 | if (!ref) { 24 | return NULL; 25 | } 26 | ref->p = p; 27 | ref->fn_free = fn_free; 28 | ref->sp_cnt = 1; 29 | ref->wp_cnt = 1; 30 | return ref; 31 | } 32 | return NULL; 33 | } 34 | 35 | void* memrefGetPtr(MemRef_t* ref) { return ref ? ref->p : NULL; } 36 | 37 | MemRef_t* memrefIncr(MemRef_t* ref) { 38 | if (ref) { 39 | _xadd32(&ref->sp_cnt, 1); 40 | } 41 | return ref; 42 | } 43 | 44 | void memrefDecr(MemRef_t** p_ref) { 45 | Atom32_t sp_cnt; 46 | MemRef_t* ref = *p_ref; 47 | if (!ref) { 48 | return; 49 | } 50 | *p_ref = NULL; 51 | 52 | sp_cnt = _xadd32(&ref->sp_cnt, -1); 53 | if (sp_cnt > 1) { 54 | return; 55 | } 56 | if (ref->fn_free) { 57 | ref->fn_free(ref->p); 58 | } 59 | ref->p = NULL; 60 | if (_xadd32(&ref->wp_cnt, -1) > 1) { 61 | return; 62 | } 63 | free(ref); 64 | } 65 | 66 | MemRef_t* memrefLockWeak(MemRef_t* ref) { 67 | if (!ref || !ref->p) { 68 | return NULL; 69 | } 70 | while (1) { 71 | Atom32_t tmp = _xadd32(&ref->sp_cnt, 0); 72 | if (tmp < 1) { 73 | return NULL; 74 | } 75 | if (_cmpxchg32(&ref->sp_cnt, tmp + 1, tmp) == tmp) { 76 | return ref; 77 | } 78 | } 79 | } 80 | 81 | MemRef_t* memrefIncrWeak(MemRef_t* ref) { 82 | if (ref) { 83 | _xadd32(&ref->wp_cnt, 1); 84 | } 85 | return ref; 86 | } 87 | 88 | void memrefDecrWeak(MemRef_t** p_ref) { 89 | MemRef_t* ref = *p_ref; 90 | if (!ref) { 91 | return; 92 | } 93 | *p_ref = NULL; 94 | 95 | if (_xadd32(&ref->wp_cnt, -1) > 1) { 96 | return; 97 | } 98 | free(ref); 99 | } 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | -------------------------------------------------------------------------------- /src/component/rbtimer.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-24. 3 | // 4 | 5 | #include "../../inc/component/rbtimer.h" 6 | #include 7 | 8 | typedef struct RBTimerEvList { 9 | RBTreeNode_t m_rbtreenode; 10 | List_t m_list; 11 | } RBTimerEvList; 12 | 13 | static void rbtimer_remove_evlist(RBTimer_t* timer, RBTimerEvList* evlist) { 14 | if (timer->m_first_evlist == evlist) { 15 | RBTreeNode_t* rb_next = rbtreeNextNode(&evlist->m_rbtreenode); 16 | if (rb_next) { 17 | RBTimerEvList* evlist_next = pod_container_of(rb_next, RBTimerEvList, m_rbtreenode); 18 | timer->m_first_evlist = evlist_next; 19 | } 20 | else { 21 | timer->m_first_evlist = NULL; 22 | } 23 | } 24 | rbtreeRemoveNode(&timer->m_rbtree, &evlist->m_rbtreenode); 25 | } 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | RBTimer_t* rbtimerInit(RBTimer_t* timer) { 32 | rbtreeInit(&timer->m_rbtree, rbtreeDefaultKeyCmpI64); 33 | timer->m_first_evlist = NULL; 34 | return timer; 35 | } 36 | 37 | long long rbtimerMiniumTimestamp(RBTimer_t* timer) { 38 | RBTimerEvList* first_evlist = (RBTimerEvList*)timer->m_first_evlist; 39 | return first_evlist ? first_evlist->m_rbtreenode.key.i64 : -1; 40 | } 41 | 42 | RBTimerEvent_t* rbtimerSetEvent(RBTimer_t* timer, RBTimerEvent_t* e, long long timestamp) { 43 | RBTimerEvList* evlist, *detach_old_evlist; 44 | RBTreeNode_t* exist_node; 45 | RBTreeNodeKey_t key; 46 | 47 | if (timestamp < 0) { 48 | return NULL; 49 | } 50 | detach_old_evlist = NULL; 51 | evlist = (RBTimerEvList*)e->m_internal_evlist; 52 | if (evlist) { 53 | if (e->m_timer != timer) { 54 | return NULL; 55 | } 56 | if (timestamp == evlist->m_rbtreenode.key.i64) { 57 | return e; 58 | } 59 | detach_old_evlist = evlist; 60 | } 61 | key.i64 = timestamp; 62 | exist_node = rbtreeSearchKey(&timer->m_rbtree, key); 63 | if (exist_node) { 64 | if (detach_old_evlist) { 65 | listRemoveNode(&detach_old_evlist->m_list, &e->m_listnode); 66 | if (listIsEmpty(&detach_old_evlist->m_list)) { 67 | rbtimer_remove_evlist(timer, detach_old_evlist); 68 | free(detach_old_evlist); 69 | } 70 | } 71 | evlist = pod_container_of(exist_node, RBTimerEvList, m_rbtreenode); 72 | listInsertNodeBack(&evlist->m_list, evlist->m_list.tail, &e->m_listnode); 73 | } 74 | else { 75 | if (!detach_old_evlist) { 76 | evlist = (RBTimerEvList*)malloc(sizeof(RBTimerEvList)); 77 | if (!evlist) { 78 | return NULL; 79 | } 80 | listInit(&evlist->m_list); 81 | listInsertNodeBack(&evlist->m_list, evlist->m_list.tail, &e->m_listnode); 82 | } 83 | else if (&e->m_listnode == detach_old_evlist->m_list.head && 84 | &e->m_listnode == detach_old_evlist->m_list.tail) 85 | { 86 | rbtimer_remove_evlist(timer, detach_old_evlist); 87 | evlist = detach_old_evlist; 88 | } 89 | else { 90 | evlist = (RBTimerEvList*)malloc(sizeof(RBTimerEvList)); 91 | if (!evlist) { 92 | return NULL; 93 | } 94 | listInit(&evlist->m_list); 95 | listRemoveNode(&detach_old_evlist->m_list, &e->m_listnode); 96 | listInsertNodeBack(&evlist->m_list, evlist->m_list.tail, &e->m_listnode); 97 | } 98 | evlist->m_rbtreenode.key.i64 = timestamp; 99 | rbtreeInsertNode(&timer->m_rbtree, &evlist->m_rbtreenode); 100 | if (!timer->m_first_evlist || ((RBTimerEvList*)timer->m_first_evlist)->m_rbtreenode.key.i64 > timestamp) { 101 | timer->m_first_evlist = evlist; 102 | } 103 | } 104 | e->timestamp = timestamp; 105 | e->m_timer = timer; 106 | e->m_internal_evlist = evlist; 107 | return e; 108 | } 109 | 110 | BOOL rbtimerCheckEventScheduled(RBTimerEvent_t* e) { return e->m_internal_evlist != NULL; } 111 | 112 | void rbtimerDetachEvent(RBTimerEvent_t* e) { 113 | RBTimerEvList* evlist; 114 | RBTimer_t* timer; 115 | 116 | timer = e->m_timer; 117 | if (!timer) { 118 | return; 119 | } 120 | e->m_timer = NULL; 121 | evlist = (RBTimerEvList*)e->m_internal_evlist; 122 | if (!evlist) { 123 | return; 124 | } 125 | e->m_internal_evlist = NULL; 126 | listRemoveNode(&evlist->m_list, &e->m_listnode); 127 | if (!listIsEmpty(&evlist->m_list)) { 128 | return; 129 | } 130 | rbtimer_remove_evlist(timer, evlist); 131 | free(evlist); 132 | } 133 | 134 | RBTimerEvent_t* rbtimerTimeoutPopup(RBTimer_t* timer, long long timestamp) { 135 | ListNode_t* lnode; 136 | RBTimerEvList* evlist; 137 | RBTimerEvent_t* e; 138 | 139 | evlist = (RBTimerEvList*)timer->m_first_evlist; 140 | if (!evlist || evlist->m_rbtreenode.key.i64 > timestamp) { 141 | return NULL; 142 | } 143 | lnode = listPopNodeFront(&evlist->m_list); 144 | if (listIsEmpty(&evlist->m_list)) { 145 | rbtimer_remove_evlist(timer, evlist); 146 | free(evlist); 147 | } 148 | if (!lnode) { 149 | return NULL; 150 | } 151 | e = pod_container_of(lnode, RBTimerEvent_t, m_listnode); 152 | e->m_timer = NULL; 153 | e->m_internal_evlist = NULL; 154 | return e; 155 | } 156 | 157 | void rbtimerDestroy(RBTimer_t* timer) { 158 | RBTreeNode_t *rbcur, *rbnext; 159 | for (rbcur = rbtreeFirstNode(&timer->m_rbtree); rbcur; rbcur = rbnext) { 160 | ListNode_t* lcur, *lnext; 161 | RBTimerEvList* evlist = pod_container_of(rbcur, RBTimerEvList, m_rbtreenode); 162 | rbnext = rbtreeNextNode(rbcur); 163 | rbtreeRemoveNode(&timer->m_rbtree, rbcur); 164 | for (lcur = evlist->m_list.head; lcur; lcur = lnext) { 165 | RBTimerEvent_t* e = pod_container_of(lcur, RBTimerEvent_t, m_listnode); 166 | lnext = lcur->next; 167 | e->m_timer = NULL; 168 | e->m_internal_evlist = NULL; 169 | } 170 | free(evlist); 171 | } 172 | timer->m_first_evlist = NULL; 173 | } 174 | 175 | #ifdef __cplusplus 176 | } 177 | #endif 178 | -------------------------------------------------------------------------------- /src/crt/dynarr.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/crt/dynarr.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | void* dynarrReserve_raw(DynArrRaw_t* dynarr, size_t capacity, size_t ele_size) { 13 | if (dynarr->capacity < capacity) { 14 | void* p = realloc(dynarr->buf, ele_size * capacity); 15 | if (!p) { 16 | return NULL; 17 | } 18 | dynarr->buf = p; 19 | dynarr->capacity = capacity; 20 | } 21 | return dynarr->buf; 22 | } 23 | 24 | void* dynarrResize_raw(DynArrRaw_t* dynarr, size_t len, size_t ele_size) { 25 | if (!dynarrReserve_raw(dynarr, len, ele_size)) { 26 | return NULL; 27 | } 28 | dynarr->len = len; 29 | return dynarr; 30 | } 31 | 32 | void dynarrSwap_raw(DynArrRaw_t* a1, DynArrRaw_t* a2) { 33 | if (a1 != a2) { 34 | DynArrRaw_t temp = *a1; 35 | *a1 = *a2; 36 | *a2 = temp; 37 | } 38 | } 39 | 40 | void dynarrInitZero_raw(DynArrRaw_t* dynarr) { 41 | dynarr->buf = NULL; 42 | dynarr->len = 0; 43 | dynarr->capacity = 0; 44 | } 45 | 46 | void dynarrFreeMemory_raw(DynArrRaw_t* dynarr) { 47 | free(dynarr->buf); 48 | dynarrInitZero_raw(dynarr); 49 | } 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /src/crt/protocol/websocketframe.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-17. 3 | // 4 | 5 | #include "../../../inc/datastruct/base64.h" 6 | #include "../../../inc/datastruct/sha1.h" 7 | #include "../../../inc/datastruct/memfunc.h" 8 | #include "../../../inc/crt/protocol/websocketframe.h" 9 | #include 10 | #include 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | char* websocketframeComputeSecAccept(const char* sec_key, unsigned int sec_keylen, char sec_accept[60]) { 17 | static const char WEB_SOCKET_MAGIC_KEY[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 18 | SHA1_CTX sha1_ctx; 19 | unsigned char sha1_key[20]; 20 | unsigned char* pk = (unsigned char*)malloc(sec_keylen + sizeof(WEB_SOCKET_MAGIC_KEY) - 1); 21 | if (!pk) { 22 | return NULL; 23 | } 24 | memmove(pk, sec_key, sec_keylen); 25 | memmove(pk + sec_keylen, WEB_SOCKET_MAGIC_KEY, sizeof(WEB_SOCKET_MAGIC_KEY) - 1); 26 | SHA1Init(&sha1_ctx); 27 | SHA1Update(&sha1_ctx, (unsigned char*)pk, sec_keylen + sizeof(WEB_SOCKET_MAGIC_KEY) - 1); 28 | SHA1Final(sha1_key, &sha1_ctx); 29 | free(pk); 30 | base64Encode(sha1_key, sizeof(sha1_key), sec_accept); 31 | return sec_accept; 32 | } 33 | 34 | int websocketframeDecodeHandshakeRequest(const char* data, unsigned int datalen, const char** sec_key, unsigned int* sec_keylen, const char** sec_protocol, unsigned int* sec_protocol_len) { 35 | const char *ks, *ke; 36 | const char* e = strStr(data, datalen, "\r\n\r\n", 4); 37 | if (!e) { 38 | return 0; 39 | } 40 | ks = strStr(data, e - data, "Sec-WebSocket-Key:", 18); 41 | if (!ks) { 42 | return -1; 43 | } 44 | for (ks += 18; ks < e && *ks <= 32; ++ks); 45 | if (ks >= e) { 46 | return -1; 47 | } 48 | ke = strChr(ks, e - ks + 1, '\r'); 49 | if (!ke) { 50 | return -1; 51 | } 52 | *sec_key = ks; 53 | *sec_keylen = ke - ks; 54 | *sec_protocol = NULL; 55 | *sec_protocol_len = 0; 56 | do { 57 | ks = strStr(data, e - data, "Sec-WebSocket-Protocol:", 23); 58 | if (!ks) { 59 | break; 60 | } 61 | for (ks += 23; ks < e && *ks <= 32; ++ks); 62 | if (ks >= e) { 63 | break; 64 | } 65 | ke = strChr(ks, e - ks + 1, '\r'); 66 | if (!ke) { 67 | break; 68 | } 69 | *sec_protocol = ks; 70 | *sec_protocol_len = ke - ks; 71 | } while (0); 72 | return e - data + 4; 73 | } 74 | 75 | char* websocketframeEncodeHandshakeResponse(const char* sec_accept, unsigned int sec_accept_len, char buf[162]) { 76 | buf[0] = 0; 77 | strcat(buf, "HTTP/1.1 101 Switching Protocols\r\n" 78 | "Upgrade: websocket\r\n" 79 | "Connection: Upgrade\r\n" 80 | "Sec-WebSocket-Accept: "); 81 | strncat(buf, sec_accept, sec_accept_len); 82 | strcat(buf, "\r\n\r\n"); 83 | return buf; 84 | } 85 | 86 | char* websocketframeEncodeHandshakeResponseWithProtocol(const char* sec_accept, unsigned int sec_accept_len, const char* sec_protocol, unsigned int sec_protocol_len) { 87 | char* buf; 88 | size_t buflen = 162; 89 | if (sec_protocol && sec_protocol_len > 0) { 90 | buflen += (24 + sec_protocol_len + 2); /* Sec-WebSocket-Protocol: %s\r\n */ 91 | } 92 | buf = (char*)malloc(buflen); 93 | if (!buf) { 94 | return NULL; 95 | } 96 | buf[0] = 0; 97 | strcat(buf, "HTTP/1.1 101 Switching Protocols\r\n" 98 | "Upgrade: websocket\r\n" 99 | "Connection: Upgrade\r\n" 100 | "Sec-WebSocket-Accept: "); 101 | strncat(buf, sec_accept, sec_accept_len); 102 | if (sec_protocol && sec_protocol_len > 0) { 103 | strcat(buf, "\r\nSec-WebSocket-Protocol: "); 104 | strncat(buf, sec_protocol, sec_protocol_len); 105 | } 106 | strcat(buf, "\r\n\r\n"); 107 | return buf; 108 | } 109 | 110 | void websocketframeFreeString(char* s) { free(s); } 111 | 112 | int websocketframeDecode(unsigned char* buf, unsigned long long len, 113 | unsigned char** data, unsigned long long* datalen, int* is_fin, int* type) 114 | { 115 | unsigned char frame_is_fin, frame_type; 116 | unsigned int mask_len = 0, ext_payload_filed_len = 0; 117 | unsigned char* payload_data = NULL; 118 | unsigned long long payload_len; 119 | const unsigned int header_size = 2; 120 | 121 | if (len < header_size) 122 | return 0; 123 | 124 | frame_is_fin = buf[0] >> 7; 125 | frame_type = buf[0] & 0x0f; 126 | if (buf[1] >> 7) 127 | mask_len = 4; 128 | 129 | payload_len = buf[1] & 0x7f; 130 | if (payload_len < 126) { 131 | if (len < header_size + ext_payload_filed_len + mask_len) 132 | return 0; 133 | } 134 | else if (payload_len == 126) { 135 | ext_payload_filed_len = 2; 136 | if (len < header_size + ext_payload_filed_len + mask_len) 137 | return 0; 138 | payload_len = memFromBE16(*(unsigned short*)&buf[header_size]); 139 | } 140 | else if (payload_len == 127) { 141 | ext_payload_filed_len = 8; 142 | if (len < header_size + ext_payload_filed_len + mask_len) 143 | return 0; 144 | payload_len = memFromBE64(*(unsigned long long*)&data[header_size]); 145 | } 146 | else 147 | return -1; 148 | 149 | if (len < header_size + ext_payload_filed_len + mask_len + payload_len) 150 | return 0; 151 | 152 | payload_data = &buf[header_size + ext_payload_filed_len + mask_len]; 153 | if (mask_len) { 154 | unsigned long long i; 155 | unsigned char* mask = &buf[header_size + ext_payload_filed_len]; 156 | for (i = 0; i < payload_len; ++i) 157 | payload_data[i] ^= mask[i % 4]; 158 | } 159 | 160 | *is_fin = frame_is_fin; 161 | *type = frame_type; 162 | *datalen = payload_len; 163 | *data = payload_len ? payload_data : NULL; 164 | return header_size + ext_payload_filed_len + mask_len + payload_len; 165 | } 166 | 167 | unsigned int websocketframeEncodeHeadLength(unsigned long long datalen) { 168 | if (datalen < 126) 169 | return 2; 170 | else if (datalen <= 0xffff) 171 | return 4; 172 | else 173 | return 10; 174 | } 175 | 176 | void websocketframeEncode(void* headbuf, int is_fin, int prev_is_fin, int type, unsigned long long datalen) { 177 | unsigned char* phead = (unsigned char*)headbuf; 178 | if (prev_is_fin && is_fin) { 179 | phead[0] = type | 0x80; 180 | } 181 | else if (prev_is_fin) { 182 | phead[0] = type; 183 | } 184 | else if (is_fin) { 185 | phead[0] = WEBSOCKET_CONTINUE_FRAME | 0x80; 186 | } 187 | else { 188 | phead[0] = WEBSOCKET_CONTINUE_FRAME; 189 | } 190 | 191 | if (datalen < 126) { 192 | phead[1] = datalen; 193 | } 194 | else if (datalen <= 0xffff) { 195 | phead[1] = 126; 196 | *(unsigned short*)&phead[2] = memToBE16(datalen); 197 | } 198 | else { 199 | phead[1] = 127; 200 | *(unsigned long long*)&phead[2] = memToBE64(datalen); 201 | } 202 | } 203 | 204 | #ifdef __cplusplus 205 | } 206 | #endif 207 | -------------------------------------------------------------------------------- /src/crt/string.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 22-10-14 3 | // 4 | 5 | #include "../../inc/crt/string.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | int strFormatLen(const char* format, ...) { 15 | char test_buf; 16 | int len; 17 | va_list varg; 18 | va_start(varg, format); 19 | len = vsnprintf(&test_buf, 0, format, varg); 20 | va_end(varg); 21 | return len; 22 | } 23 | 24 | char* strFormat(int* out_len, const char* format, ...) { 25 | char test_buf; 26 | char* buf; 27 | int len; 28 | va_list varg; 29 | va_start(varg, format); 30 | len = vsnprintf(&test_buf, 0, format, varg); 31 | va_end(varg); 32 | if (len < 0) { 33 | return NULL; 34 | } 35 | buf = (char*)malloc(len + 1); 36 | if (!buf) { 37 | return NULL; 38 | } 39 | va_start(varg, format); 40 | len = vsnprintf(buf, len + 1, format, varg); 41 | va_end(varg); 42 | if (len < 0) { 43 | free(buf); 44 | return NULL; 45 | } 46 | if (out_len) { 47 | *out_len = len; 48 | } 49 | buf[len] = 0; 50 | return buf; 51 | } 52 | 53 | void strFreeMemory(char* s) { free(s); } 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif -------------------------------------------------------------------------------- /src/datastruct/base64.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/base64.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | static const unsigned char base64map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 12 | 13 | UnsignedPtr_t base64Encode(const unsigned char* src, UnsignedPtr_t srclen, char* dst) { 14 | UnsignedPtr_t i, dstLen; 15 | UnsignedPtr_t leven = 3 * (srclen / 3); 16 | for (dstLen = 0, i = 0; i < leven; i += 3) { 17 | if (dst) { 18 | dst[dstLen] = base64map[src[0] >> 2]; 19 | dst[dstLen + 1] = base64map[((src[0] & 3) << 4) + (src[1] >> 4)]; 20 | dst[dstLen + 2] = base64map[((src[1] & 0xf) << 2) + (src[2] >> 6)]; 21 | dst[dstLen + 3] = base64map[src[2] & 0x3f]; 22 | } 23 | dstLen += 4; 24 | src += 3; 25 | } 26 | if (i < srclen) { 27 | unsigned char a = src[0]; 28 | unsigned char b = (unsigned char)((i + 1 < srclen) ? src[1] : 0); 29 | unsigned c = 0; 30 | 31 | if (dst) { 32 | dst[dstLen] = base64map[a >> 2]; 33 | dst[dstLen + 1] = base64map[((a & 3) << 4) + (b >> 4)]; 34 | dst[dstLen + 2] = (char)((i + 1 < srclen) ? base64map[((b & 0xf) << 2) + (c >> 6)] : '='); 35 | dst[dstLen + 3] = '='; 36 | } 37 | dstLen += 4; 38 | } 39 | if (dst) { 40 | dst[dstLen] = 0; 41 | } 42 | return dstLen; 43 | } 44 | 45 | static unsigned char base64byte(char c) { 46 | if (c >= '0' && c <= '9') 47 | return (unsigned char)(c - '0' + 52); 48 | if (c >= 'A' && c <= 'Z') 49 | return (unsigned char)(c - 'A'); 50 | if (c >= 'a' && c <= 'z') 51 | return (unsigned char)(c - 'a' + 26); 52 | if ('+' == c) 53 | return 62; 54 | if ('/' == c) 55 | return 63; 56 | else 57 | return 64; 58 | } 59 | 60 | UnsignedPtr_t base64Decode(const char* src, UnsignedPtr_t srclen, unsigned char* dst) { 61 | unsigned char input[4]; 62 | UnsignedPtr_t i, dstLen; 63 | for (dstLen = 0, i = 0; i < srclen; i += 4) { 64 | if (dst) { 65 | input[0] = base64byte(src[i]); 66 | input[1] = base64byte(src[i + 1]); 67 | dst[dstLen] = (input[0] << 2) + (input[1] >> 4); 68 | } 69 | ++dstLen; 70 | if (src[i + 2] != '=') { 71 | if (dst) { 72 | input[2] = base64byte(src[i + 2]); 73 | dst[dstLen] = (input[1] << 4) + (input[2] >> 2); 74 | } 75 | ++dstLen; 76 | } 77 | if (src[i + 3] != '=') { 78 | if (dst) { 79 | input[3] = base64byte(src[i + 3]); 80 | dst[dstLen] = (input[2] << 6) + input[3]; 81 | } 82 | ++dstLen; 83 | } 84 | } 85 | return dstLen; 86 | } 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif -------------------------------------------------------------------------------- /src/datastruct/graph.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/graph.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | Graph_t* graphInit(Graph_t* g) { 12 | listInit(&g->vnodelist); 13 | g->dfs_visit = 0; 14 | return g; 15 | } 16 | 17 | Graph_t* graphAddNode(Graph_t* g, GraphNode_t* v) { 18 | int i; 19 | for (i = 0; i < 2; ++i) { 20 | listInit(&v->edgelist[i]); 21 | v->degree[i] = 0; 22 | } 23 | v->dfs_visit = 0; 24 | v->graph = g; 25 | listPushNodeBack(&g->vnodelist, &v->node); 26 | return g; 27 | } 28 | 29 | void graphRemoveNode(Graph_t* g, GraphNode_t* v, List_t* unlink_edgelist) { 30 | graphUnlinkNode(v, unlink_edgelist); 31 | listRemoveNode(&g->vnodelist, &v->node); 32 | } 33 | 34 | GraphEdge_t* graphLinkEdge(GraphEdge_t* e) { 35 | if (e->v[0] && e->v[1]) { 36 | int i; 37 | for (i = 0; i < 2; ++i) { 38 | GraphNode_t* v = e->v[i]; 39 | listInsertNodeBack(&v->edgelist[i], v->edgelist[i].tail, &e->edgelistnode[i]); 40 | v->degree[i]++; 41 | } 42 | } 43 | return e; 44 | } 45 | 46 | void graphUnlinkEdge(GraphEdge_t* e) { 47 | if (e->v[0] && e->v[1]) { 48 | int i; 49 | for (i = 0; i < 2; ++i) { 50 | GraphNode_t* v = e->v[i]; 51 | listRemoveNode(&v->edgelist[i], &e->edgelistnode[i]); 52 | v->degree[i]--; 53 | e->v[i] = (GraphNode_t*)0; 54 | } 55 | } 56 | } 57 | 58 | void graphUnlinkNode(GraphNode_t* v, List_t* unlink_edgelist) { 59 | int i; 60 | for (i = 0; i < 2; ++i) { 61 | List_t* edgelist = &v->edgelist[i]; 62 | ListNode_t* cur, *next; 63 | for (cur = edgelist->head; cur; cur = next) { 64 | GraphEdge_t* edge = pod_container_of(cur, GraphEdge_t, edgelistnode[i]); 65 | next = cur->next; 66 | graphUnlinkEdge(edge); 67 | listPushNodeBack(unlink_edgelist, &edge->viewnode); 68 | } 69 | v->degree[i] = 0; 70 | } 71 | } 72 | 73 | GraphNode_t* graphDFSFirst(Graph_t* g, GraphNode_t* v) { 74 | if (0 == ++g->dfs_visit) { 75 | ListNode_t* cur; 76 | for (cur = g->vnodelist.head; cur; cur = cur->next) { 77 | GraphNode_t* vnode = pod_container_of(cur, GraphNode_t, node); 78 | vnode->dfs_visit = 0; 79 | } 80 | ++g->dfs_visit; 81 | } 82 | v->dfs_visit = g->dfs_visit; 83 | v->visit_from_edgenode = (GraphEdge_t*)0; 84 | return v; 85 | } 86 | 87 | GraphNode_t* graphDFSNext(GraphNode_t* v) { 88 | ListNode_t* cur = v->edgelist[0].head; 89 | int dfs_visit = v->graph->dfs_visit; 90 | while (1) { 91 | GraphEdge_t* edge; 92 | for (; cur; cur = cur->next) { 93 | GraphNode_t* next_v; 94 | edge = pod_container_of(cur, GraphEdge_t, edgelistnode[0]); 95 | next_v = edge->v[1]; 96 | if (next_v->dfs_visit == dfs_visit) 97 | continue; 98 | next_v->dfs_visit = dfs_visit; 99 | next_v->visit_from_edgenode = edge; 100 | return next_v; 101 | } 102 | if (!v->visit_from_edgenode) 103 | return (GraphNode_t*)0; 104 | cur = v->visit_from_edgenode->edgelistnode[0].next; 105 | edge = v->visit_from_edgenode; 106 | v = edge->v[0]; 107 | } 108 | } 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | -------------------------------------------------------------------------------- /src/datastruct/hash.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/hash.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | unsigned int hashBKDR(const char *str) { 12 | /* seed is 131 */ 13 | unsigned int hash = 0; 14 | while (*str) 15 | hash = hash * 131U + (*str++); 16 | return hash & 0x7fffffff; 17 | } 18 | 19 | unsigned int hashDJB(const char *str) { 20 | unsigned int hash = 5381; 21 | while (*str) 22 | hash = ((hash << 5) + hash) + (*str++); 23 | return hash & 0x7fffffff; 24 | } 25 | 26 | unsigned int hashJenkins(const char *key, UnsignedPtr_t keylen) { 27 | const char *p; 28 | unsigned int hash = 0; 29 | for (p = key; keylen; --keylen, ++p) { 30 | hash += *p; 31 | hash += hash << 10; 32 | hash ^= hash >> 6; 33 | } 34 | hash += hash << 3; 35 | hash ^= hash >> 11; 36 | hash += hash << 15; 37 | return hash; 38 | } 39 | 40 | unsigned int hashMurmur2(const char *key, UnsignedPtr_t keylen) { 41 | unsigned int h, k; 42 | h = 0 ^ keylen; 43 | 44 | while (keylen >= 4) { 45 | k = key[0]; 46 | k |= key[1] << 8; 47 | k |= key[2] << 16; 48 | k |= key[3] << 24; 49 | 50 | k *= 0x5bd1e995; 51 | k ^= k >> 24; 52 | k *= 0x5bd1e995; 53 | 54 | h *= 0x5bd1e995; 55 | h ^= k; 56 | 57 | key += 4; 58 | keylen -= 4; 59 | } 60 | 61 | switch (keylen) { 62 | case 3: 63 | h ^= key[2] << 16; 64 | /* no break */ 65 | case 2: 66 | h ^= key[1] << 8; 67 | /* no break */ 68 | case 1: 69 | h ^= key[0]; 70 | h *= 0x5bd1e995; 71 | } 72 | 73 | h ^= h >> 13; 74 | h *= 0x5bd1e995; 75 | h ^= h >> 15; 76 | 77 | return h; 78 | } 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | -------------------------------------------------------------------------------- /src/datastruct/lengthfieldframe.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe on 18-8-17. 3 | // 4 | 5 | #include "../../inc/datastruct/lengthfieldframe.h" 6 | #include "../../inc/datastruct/memfunc.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int lengthfieldframeDecode(unsigned short lengthfieldsize, 13 | const unsigned char* buf, unsigned int len, unsigned char** data, unsigned int* datalen) 14 | { 15 | if (lengthfieldsize > len) 16 | return 0; 17 | 18 | switch (lengthfieldsize) { 19 | case 2: 20 | *datalen = memFromBE16(*(unsigned short*)buf); 21 | break; 22 | 23 | case 4: 24 | *datalen = memFromBE32(*(unsigned int*)buf); 25 | break; 26 | 27 | default: 28 | return -1; 29 | } 30 | if (*datalen > len - lengthfieldsize) 31 | return 0; 32 | 33 | if (*datalen) 34 | *data = (unsigned char*)buf + lengthfieldsize; 35 | else 36 | *data = (unsigned char*)0; 37 | return lengthfieldsize + *datalen; 38 | } 39 | 40 | int lengthfieldframeEncode(void* lengthfieldbuf, unsigned short lengthfieldsize, unsigned int datalen) { 41 | switch (lengthfieldsize) { 42 | case 2: 43 | if (datalen > 0xffff) 44 | return 0; 45 | *(unsigned short*)lengthfieldbuf = memToBE16(datalen); 46 | return 1; 47 | 48 | case 4: 49 | *(unsigned int*)lengthfieldbuf = memToBE32(datalen); 50 | return 1; 51 | 52 | default: 53 | return 0; 54 | } 55 | } 56 | 57 | int lengthfieldframeDecode2(unsigned short lengthfieldsize, unsigned char* buf, unsigned int len) { 58 | int decodelen; 59 | if (len < lengthfieldsize) 60 | return 0; 61 | 62 | switch (lengthfieldsize) { 63 | case 2: 64 | decodelen = memFromBE16(*(unsigned short*)buf); 65 | break; 66 | 67 | case 4: 68 | decodelen = memFromBE32(*(unsigned int*)buf); 69 | break; 70 | 71 | default: 72 | return -1; 73 | } 74 | if (decodelen < lengthfieldsize) { 75 | return -1; 76 | } 77 | return decodelen <= len ? decodelen : 0; 78 | } 79 | 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | -------------------------------------------------------------------------------- /src/datastruct/md5.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/md5.h" 6 | 7 | #define F(x,y,z) ((x & y) | (~x & z)) 8 | #define G(x,y,z) ((x & z) | (y & ~z)) 9 | #define H(x,y,z) (x^y^z) 10 | #define I(x,y,z) (y ^ (x | ~z)) 11 | #define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) 12 | #define FF(a,b,c,d,x,s,ac) \ 13 | { \ 14 | a += F(b,c,d) + x + ac; \ 15 | a = ROTATE_LEFT(a,s); \ 16 | a += b; \ 17 | } 18 | #define GG(a,b,c,d,x,s,ac) \ 19 | { \ 20 | a += G(b,c,d) + x + ac; \ 21 | a = ROTATE_LEFT(a,s); \ 22 | a += b; \ 23 | } 24 | #define HH(a,b,c,d,x,s,ac) \ 25 | { \ 26 | a += H(b,c,d) + x + ac; \ 27 | a = ROTATE_LEFT(a,s); \ 28 | a += b; \ 29 | } 30 | #define II(a,b,c,d,x,s,ac) \ 31 | { \ 32 | a += I(b,c,d) + x + ac; \ 33 | a = ROTATE_LEFT(a,s); \ 34 | a += b; \ 35 | } 36 | 37 | static unsigned char PADDING[] = { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 38 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 39 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 40 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 41 | 42 | static void* _memcopy_(void* dst, const void* src, unsigned int n) 43 | { 44 | for (; n; --n) 45 | ((unsigned char*)dst)[n - 1] = ((unsigned char*)src)[n - 1]; 46 | return dst; 47 | } 48 | 49 | static void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len) 50 | { 51 | unsigned int i = 0, j = 0; 52 | while (j < len) 53 | { 54 | output[j] = input[i] & 0xFF; 55 | output[j + 1] = (input[i] >> 8) & 0xFF; 56 | output[j + 2] = (input[i] >> 16) & 0xFF; 57 | output[j + 3] = (input[i] >> 24) & 0xFF; 58 | i++; 59 | j += 4; 60 | } 61 | } 62 | 63 | static void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len) 64 | { 65 | unsigned int i = 0, j = 0; 66 | while (j < len) 67 | { 68 | output[i] = (input[j]) | 69 | (input[j + 1] << 8) | 70 | (input[j + 2] << 16) | 71 | (input[j + 3] << 24); 72 | i++; 73 | j += 4; 74 | } 75 | } 76 | 77 | #ifdef __cplusplus 78 | extern "C" { 79 | #endif 80 | 81 | void MD5Transform(unsigned int state[4], unsigned char block[64]) 82 | { 83 | unsigned int a = state[0]; 84 | unsigned int b = state[1]; 85 | unsigned int c = state[2]; 86 | unsigned int d = state[3]; 87 | unsigned int x[64]; 88 | MD5Decode(x, block, 64); 89 | FF(a, b, c, d, x[0], 7, 0xd76aa478); /* 1 */ 90 | FF(d, a, b, c, x[1], 12, 0xe8c7b756); /* 2 */ 91 | FF(c, d, a, b, x[2], 17, 0x242070db); /* 3 */ 92 | FF(b, c, d, a, x[3], 22, 0xc1bdceee); /* 4 */ 93 | FF(a, b, c, d, x[4], 7, 0xf57c0faf); /* 5 */ 94 | FF(d, a, b, c, x[5], 12, 0x4787c62a); /* 6 */ 95 | FF(c, d, a, b, x[6], 17, 0xa8304613); /* 7 */ 96 | FF(b, c, d, a, x[7], 22, 0xfd469501); /* 8 */ 97 | FF(a, b, c, d, x[8], 7, 0x698098d8); /* 9 */ 98 | FF(d, a, b, c, x[9], 12, 0x8b44f7af); /* 10 */ 99 | FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */ 100 | FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */ 101 | FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */ 102 | FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */ 103 | FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */ 104 | FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */ 105 | 106 | /* Round 2 */ 107 | GG(a, b, c, d, x[1], 5, 0xf61e2562); /* 17 */ 108 | GG(d, a, b, c, x[6], 9, 0xc040b340); /* 18 */ 109 | GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */ 110 | GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); /* 20 */ 111 | GG(a, b, c, d, x[5], 5, 0xd62f105d); /* 21 */ 112 | GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */ 113 | GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */ 114 | GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); /* 24 */ 115 | GG(a, b, c, d, x[9], 5, 0x21e1cde6); /* 25 */ 116 | GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */ 117 | GG(c, d, a, b, x[3], 14, 0xf4d50d87); /* 27 */ 118 | GG(b, c, d, a, x[8], 20, 0x455a14ed); /* 28 */ 119 | GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */ 120 | GG(d, a, b, c, x[2], 9, 0xfcefa3f8); /* 30 */ 121 | GG(c, d, a, b, x[7], 14, 0x676f02d9); /* 31 */ 122 | GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */ 123 | 124 | /* Round 3 */ 125 | HH(a, b, c, d, x[5], 4, 0xfffa3942); /* 33 */ 126 | HH(d, a, b, c, x[8], 11, 0x8771f681); /* 34 */ 127 | HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */ 128 | HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */ 129 | HH(a, b, c, d, x[1], 4, 0xa4beea44); /* 37 */ 130 | HH(d, a, b, c, x[4], 11, 0x4bdecfa9); /* 38 */ 131 | HH(c, d, a, b, x[7], 16, 0xf6bb4b60); /* 39 */ 132 | HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */ 133 | HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */ 134 | HH(d, a, b, c, x[0], 11, 0xeaa127fa); /* 42 */ 135 | HH(c, d, a, b, x[3], 16, 0xd4ef3085); /* 43 */ 136 | HH(b, c, d, a, x[6], 23, 0x4881d05); /* 44 */ 137 | HH(a, b, c, d, x[9], 4, 0xd9d4d039); /* 45 */ 138 | HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */ 139 | HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */ 140 | HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 48 */ 141 | 142 | /* Round 4 */ 143 | II(a, b, c, d, x[0], 6, 0xf4292244); /* 49 */ 144 | II(d, a, b, c, x[7], 10, 0x432aff97); /* 50 */ 145 | II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */ 146 | II(b, c, d, a, x[5], 21, 0xfc93a039); /* 52 */ 147 | II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */ 148 | II(d, a, b, c, x[3], 10, 0x8f0ccc92); /* 54 */ 149 | II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */ 150 | II(b, c, d, a, x[1], 21, 0x85845dd1); /* 56 */ 151 | II(a, b, c, d, x[8], 6, 0x6fa87e4f); /* 57 */ 152 | II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */ 153 | II(c, d, a, b, x[6], 15, 0xa3014314); /* 59 */ 154 | II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */ 155 | II(a, b, c, d, x[4], 6, 0xf7537e82); /* 61 */ 156 | II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */ 157 | II(c, d, a, b, x[2], 15, 0x2ad7d2bb); /* 63 */ 158 | II(b, c, d, a, x[9], 21, 0xeb86d391); /* 64 */ 159 | state[0] += a; 160 | state[1] += b; 161 | state[2] += c; 162 | state[3] += d; 163 | } 164 | 165 | void MD5Init(MD5_CTX *context) 166 | { 167 | context->count[0] = 0; 168 | context->count[1] = 0; 169 | context->state[0] = 0x67452301; 170 | context->state[1] = 0xEFCDAB89; 171 | context->state[2] = 0x98BADCFE; 172 | context->state[3] = 0x10325476; 173 | } 174 | 175 | void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen) 176 | { 177 | unsigned int i = 0, index = 0, partlen = 0; 178 | index = (context->count[0] >> 3) & 0x3F; 179 | partlen = 64 - index; 180 | context->count[0] += inputlen << 3; 181 | if (context->count[0] < (inputlen << 3)) 182 | context->count[1]++; 183 | context->count[1] += inputlen >> 29; 184 | 185 | if (inputlen >= partlen) 186 | { 187 | _memcopy_(&context->buffer[index], input, partlen); 188 | MD5Transform(context->state, context->buffer); 189 | for (i = partlen; i + 64 <= inputlen; i += 64) 190 | MD5Transform(context->state, &input[i]); 191 | index = 0; 192 | } 193 | else 194 | { 195 | i = 0; 196 | } 197 | _memcopy_(&context->buffer[index], &input[i], inputlen - i); 198 | } 199 | 200 | void MD5Final(MD5_CTX *context, unsigned char digest[16]) 201 | { 202 | unsigned int index = 0, padlen = 0; 203 | unsigned char bits[8]; 204 | index = (context->count[0] >> 3) & 0x3F; 205 | padlen = (index < 56) ? (56 - index) : (120 - index); 206 | MD5Encode(bits, context->count, 8); 207 | MD5Update(context, PADDING, padlen); 208 | MD5Update(context, bits, 8); 209 | MD5Encode(digest, context->state, 16); 210 | } 211 | 212 | #ifdef __cplusplus 213 | } 214 | #endif -------------------------------------------------------------------------------- /src/datastruct/memheap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/memheap.h" 6 | 7 | typedef struct MemHeapBlock_t { 8 | UnsignedPtr_t prevoff; 9 | UnsignedPtr_t nextoff; 10 | UnsignedPtr_t uselen; 11 | } MemHeapBlock_t; 12 | 13 | #define memheapblock_ptr(block) ((unsigned char*)((block) + 1)) 14 | #define ptr_memheapblock(ptr) ((MemHeapBlock_t*)(((unsigned char*)(ptr)) - sizeof(MemHeapBlock_t))) 15 | #define PTR_VALUE_MAX ((UnsignedPtr_t)(~0)) 16 | 17 | typedef struct MemHeap_t { 18 | UnsignedPtr_t len; 19 | UnsignedPtr_t tailoff; 20 | MemHeapBlock_t guard_block; 21 | } MemHeap_t; 22 | 23 | static UnsignedPtr_t __heapblock_leftlen(MemHeap_t* memheap, MemHeapBlock_t* block) { 24 | if (block->nextoff) { 25 | return (UnsignedPtr_t)memheap + block->nextoff - (UnsignedPtr_t)block - sizeof(*block) - block->uselen; 26 | } 27 | else { 28 | return memheap->len - memheap->tailoff - sizeof(*block) - block->uselen; 29 | } 30 | } 31 | 32 | static void __insertback(MemHeap_t* memheap, MemHeapBlock_t* node, MemHeapBlock_t* new_node) { 33 | UnsignedPtr_t base = (UnsignedPtr_t)memheap; 34 | new_node->prevoff = (UnsignedPtr_t)node - base; 35 | new_node->nextoff = node->nextoff; 36 | if (node->nextoff) { 37 | ((MemHeapBlock_t*)(base + node->nextoff))->prevoff = (UnsignedPtr_t)new_node - base; 38 | } 39 | node->nextoff = (UnsignedPtr_t)new_node - base; 40 | if (memheap->tailoff == new_node->prevoff) { 41 | memheap->tailoff = (UnsignedPtr_t)new_node - base; 42 | } 43 | } 44 | 45 | static void __remove(MemHeap_t* memheap, MemHeapBlock_t* node) { 46 | UnsignedPtr_t base = (UnsignedPtr_t)memheap; 47 | if (node->prevoff) { 48 | ((MemHeapBlock_t*)(base + node->prevoff))->nextoff = node->nextoff; 49 | } 50 | if (node->nextoff) { 51 | ((MemHeapBlock_t*)(base + node->nextoff))->prevoff = node->prevoff; 52 | } 53 | if (memheap->tailoff + base == (UnsignedPtr_t)node) { 54 | memheap->tailoff = node->prevoff; 55 | } 56 | } 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | UnsignedPtr_t memheapLength(MemHeap_t* memheap) { return memheap->len; } 63 | void* memheapStartAddr(MemHeap_t* memheap) { return (void*)(memheap + 1); } 64 | 65 | MemHeap_t* memheapSetup(void* addr, UnsignedPtr_t len) { 66 | MemHeap_t* memheap; 67 | if (len < sizeof(MemHeap_t)) { 68 | return (MemHeap_t*)0; 69 | } 70 | memheap = (MemHeap_t*)addr; 71 | memheap->len = len; 72 | memheap->tailoff = (UnsignedPtr_t)&memheap->guard_block - (UnsignedPtr_t)memheap; 73 | memheap->guard_block.prevoff = 0; 74 | memheap->guard_block.nextoff = 0; 75 | memheap->guard_block.uselen = 0; 76 | return memheap; 77 | } 78 | 79 | void* memheapAlloc(MemHeap_t* memheap, UnsignedPtr_t nbytes) { 80 | if (sizeof(void*) > 4) { 81 | return memheapAlignAlloc(memheap, nbytes, 16); 82 | } 83 | else { 84 | return memheapAlignAlloc(memheap, nbytes, 8); 85 | } 86 | } 87 | 88 | void* memheapAlignAlloc(struct MemHeap_t* memheap, UnsignedPtr_t nbytes, UnsignedPtr_t alignment) { 89 | UnsignedPtr_t realbytes, curoff, prevoff, mask; 90 | if (PTR_VALUE_MAX - sizeof(MemHeapBlock_t) < nbytes) { 91 | return (void*)0; 92 | } 93 | mask = alignment - 1; 94 | realbytes = nbytes + sizeof(MemHeapBlock_t); 95 | for (curoff = memheap->tailoff; curoff; curoff = prevoff) { 96 | MemHeapBlock_t* block = (MemHeapBlock_t*)(curoff + (UnsignedPtr_t)memheap); 97 | UnsignedPtr_t leftlen = __heapblock_leftlen(memheap, block); 98 | prevoff = block->prevoff; 99 | if (leftlen >= realbytes) { 100 | UnsignedPtr_t newoff = curoff + sizeof(MemHeapBlock_t) + block->uselen; 101 | UnsignedPtr_t ptr = newoff + (UnsignedPtr_t)memheap + sizeof(MemHeapBlock_t); 102 | UnsignedPtr_t newptr = (ptr + mask) & (~mask); 103 | realbytes += newptr - ptr; 104 | if (leftlen < realbytes) { 105 | continue; 106 | } 107 | MemHeapBlock_t* newblock = ptr_memheapblock(newptr); 108 | newblock->uselen = nbytes; 109 | __insertback(memheap, block, newblock); 110 | return (void*)newptr; 111 | } 112 | } 113 | return (void*)0; 114 | } 115 | 116 | void* memheapRealloc(MemHeap_t* memheap, void* addr, UnsignedPtr_t nbytes) { 117 | if (!addr) { 118 | return memheapAlloc(memheap, nbytes); 119 | } 120 | else if (!nbytes) { 121 | memheapFree(memheap, addr); 122 | return (void*)0; 123 | } 124 | else { 125 | char* new_p, *old_p; 126 | void* new_addr; 127 | MemHeapBlock_t* block = ptr_memheapblock(addr); 128 | if (block->uselen >= nbytes) { 129 | block->uselen = nbytes; 130 | return addr; 131 | } 132 | if (__heapblock_leftlen(memheap, block) + block->uselen >= nbytes) { 133 | block->uselen = nbytes; 134 | return addr; 135 | } 136 | new_addr = memheapAlloc(memheap, nbytes); 137 | if (!new_addr) { 138 | return (void*)0; 139 | } 140 | new_p = (char*)new_addr; 141 | old_p = (char*)addr; 142 | nbytes = block->uselen; 143 | while (nbytes--) { 144 | *new_p = *old_p; 145 | ++new_p; 146 | ++old_p; 147 | } 148 | memheapFree(memheap, addr); 149 | return new_addr; 150 | } 151 | } 152 | 153 | void memheapFree(MemHeap_t* memheap, void* addr) { 154 | if (addr) { 155 | MemHeapBlock_t* block = ptr_memheapblock(addr); 156 | __remove(memheap, block); 157 | } 158 | } 159 | 160 | void memheapFreeAll(MemHeap_t* memheap) { 161 | memheap->tailoff = (UnsignedPtr_t)&memheap->guard_block - (UnsignedPtr_t)memheap; 162 | memheap->guard_block.nextoff = 0; 163 | } 164 | 165 | #ifdef __cplusplus 166 | } 167 | #endif 168 | -------------------------------------------------------------------------------- /src/datastruct/random.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/random.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | /* linear congruential */ 12 | #define N 16 13 | #define MASK ((1 << (N - 1)) + (1 << (N - 1)) - 1) 14 | #define LOW(x) ((unsigned int)(x) & MASK) 15 | #define HIGH(x) LOW((x) >> N) 16 | #define MUL(x, y, z) { int l = (long long)(x) * (long long)(y); (z)[0] = LOW(l); (z)[1] = HIGH(l); } 17 | #define CARRY(x, y) ((int)(x) + (long long)(y) > MASK) 18 | #define ADDEQU(x, y, z) (z = CARRY(x, (y)), x = LOW(x + (y))) 19 | #define X0 0x330E 20 | #define X1 0xABCD 21 | #define X2 0x1234 22 | #define A0 0xE66D 23 | #define A1 0xDEEC 24 | #define A2 0x5 25 | #define C 0xB 26 | #define SET3(x, x0, x1, x2) ((x)[0] = (x0), (x)[1] = (x1), (x)[2] = (x2)) 27 | void rand48Seed(Rand48_t* ctx, int seedval) { 28 | ctx->x[0] = X0; 29 | ctx->x[1] = LOW(seedval); 30 | ctx->x[2] = HIGH(seedval); 31 | 32 | ctx->a[0] = A0; 33 | ctx->a[1] = A1; 34 | ctx->a[2] = A2; 35 | 36 | ctx->c = C; 37 | } 38 | int rand48_l(Rand48_t* ctx) { 39 | unsigned int p[2], q[2], r[2], carry0, carry1; 40 | 41 | MUL(ctx->a[0], ctx->x[0], p); 42 | ADDEQU(p[0], ctx->c, carry0); 43 | ADDEQU(p[1], carry0, carry1); 44 | MUL(ctx->a[0], ctx->x[1], q); 45 | ADDEQU(p[1], q[0], carry0); 46 | MUL(ctx->a[1], ctx->x[0], r); 47 | ctx->x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] + 48 | ctx->a[0] * ctx->x[2] + ctx->a[1] * ctx->x[1] + ctx->a[2] * ctx->x[0]); 49 | ctx->x[1] = LOW(p[1] + r[0]); 50 | ctx->x[0] = LOW(p[0]); 51 | return (((int)(ctx->x[2]) << (N - 1)) + (ctx->x[1] >> 1)); 52 | } 53 | int rand48Range(Rand48_t* ctx, int start, int end) { 54 | /* [start, end) */ 55 | if (start >= end) 56 | return start; 57 | return rand48_ul(ctx) % (end - start) + start; 58 | } 59 | 60 | /* mt19937 */ 61 | void mt19937Seed(RandMT19937_t* ctx, int seedval) { 62 | int i; 63 | unsigned long long* x = ctx->x; 64 | x[0] = seedval; 65 | for (i = 1; i < sizeof(ctx->x) / sizeof(ctx->x[0]); i++) 66 | x[i] = 6364136223846793005ULL * (x[i - 1] ^ (x[i - 1] >> (64 - 2))) + i; 67 | ctx->k = 0; 68 | } 69 | unsigned long long mt19937_ull(RandMT19937_t* ctx) { 70 | int k = ctx->k; 71 | unsigned long long* x = ctx->x; 72 | unsigned long long y, z; 73 | 74 | /* z = (x^u_k | x^l_(k+1))*/ 75 | z = (x[k] & 0xffffffff80000000ULL) | (x[(k + 1) % 312] & 0x7fffffffULL); 76 | /* x_(k+n) = x_(k+m) |+| z*A */ 77 | x[k] = x[(k + 156) % 312] ^ (z >> 1) ^ (!(z & 1ULL) ? 0ULL : 0xb5026f5aa96619e9ULL); 78 | /* Tempering */ 79 | y = x[k]; 80 | y ^= (y >> 29) & 0x5555555555555555ULL; 81 | y ^= (y << 17) & 0x71d67fffeda60000ULL; 82 | y ^= (y << 37) & 0xfff7eee000000000ULL; 83 | y ^= y >> 43; 84 | 85 | ctx->k = (k + 1) % 312; 86 | return y; 87 | } 88 | long long mt19937Range(RandMT19937_t* ctx, long long start, long long end) { 89 | /* [start, end) */ 90 | if (start >= end) 91 | return start; 92 | return mt19937_ull(ctx) % (end - start) + start; 93 | } 94 | 95 | /* random string */ 96 | char* randAlphabetNumber(int seedval, char* s, UnsignedPtr_t length) { 97 | static char table[] = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ"; 98 | UnsignedPtr_t i; 99 | RandMT19937_t ctx; 100 | mt19937Seed(&ctx, seedval); 101 | for (i = 0; i < length; ++i) { 102 | long long index = mt19937Range(&ctx, 0, sizeof(table) - 1); 103 | s[i] = table[index]; 104 | } 105 | return s; 106 | } 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | -------------------------------------------------------------------------------- /src/datastruct/sha1.c: -------------------------------------------------------------------------------- 1 | 2 | /* from valgrind tests */ 3 | 4 | /* ================ sha1.c ================ */ 5 | /* 6 | SHA-1 in C 7 | By Steve Reid 8 | 100% Public Domain 9 | 10 | Test Vectors (from FIPS PUB 180-1) 11 | "abc" 12 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 13 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 14 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 15 | A million repetitions of "a" 16 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 17 | */ 18 | 19 | /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ 20 | /* #define SHA1HANDSOFF * Copies data before messing with it. */ 21 | 22 | #include "../../inc/datastruct/sha1.h" 23 | 24 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 25 | 26 | /* blk0() and blk() perform the initial expand. */ 27 | /* I got the idea of expanding during the round function from SSLeay */ 28 | #define blk0(i) (*((const unsigned char*)&BYTE_ORDER) ? (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 29 | |(rol(block->l[i],8)&0x00FF00FF)) : block->l[i]) 30 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 31 | ^block->l[(i+2)&15]^block->l[i&15],1)) 32 | 33 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 34 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 35 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 36 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 37 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 38 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | static const unsigned short BYTE_ORDER = 0x0001; 45 | 46 | static void* __byte_copy(void* dst, const void* src, unsigned int sz) { 47 | unsigned char* pdst = (unsigned char*)dst; 48 | unsigned char* psrc = (unsigned char*)src; 49 | while (sz--) { 50 | *pdst = *psrc; 51 | ++pdst; 52 | ++psrc; 53 | } 54 | return dst; 55 | } 56 | 57 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 58 | 59 | void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]) 60 | { 61 | unsigned int a, b, c, d, e; 62 | typedef union { 63 | unsigned char c[64]; 64 | unsigned int l[16]; 65 | } CHAR64LONG16; 66 | 67 | CHAR64LONG16 block[1]; /* use array to appear as a pointer */ 68 | __byte_copy(block, buffer, 64); 69 | 70 | /* Copy context->state[] to working vars */ 71 | a = state[0]; 72 | b = state[1]; 73 | c = state[2]; 74 | d = state[3]; 75 | e = state[4]; 76 | /* 4 rounds of 20 operations each. Loop unrolled. */ 77 | R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1); R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3); 78 | R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5); R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7); 79 | R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9); R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11); 80 | R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13); R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15); 81 | R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17); R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19); 82 | R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21); R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23); 83 | R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25); R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27); 84 | R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29); R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31); 85 | R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33); R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35); 86 | R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37); R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39); 87 | R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41); R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43); 88 | R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45); R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47); 89 | R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49); R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51); 90 | R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53); R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55); 91 | R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57); R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59); 92 | R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61); R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63); 93 | R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65); R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67); 94 | R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69); R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71); 95 | R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73); R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75); 96 | R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77); R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79); 97 | /* Add the working vars back into context.state[] */ 98 | state[0] += a; 99 | state[1] += b; 100 | state[2] += c; 101 | state[3] += d; 102 | state[4] += e; 103 | /* Wipe variables */ 104 | /* 105 | a = b = c = d = e = 0; 106 | memset(block, '\0', sizeof(block)); 107 | */ 108 | } 109 | 110 | 111 | /* SHA1Init - Initialize new context */ 112 | 113 | void SHA1Init(SHA1_CTX* context) 114 | { 115 | /* SHA1 initialization constants */ 116 | context->state[0] = 0x67452301; 117 | context->state[1] = 0xEFCDAB89; 118 | context->state[2] = 0x98BADCFE; 119 | context->state[3] = 0x10325476; 120 | context->state[4] = 0xC3D2E1F0; 121 | context->count[0] = context->count[1] = 0; 122 | } 123 | 124 | 125 | /* Run your data through this. */ 126 | 127 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len) 128 | { 129 | unsigned int i; 130 | unsigned int j; 131 | 132 | j = context->count[0]; 133 | if ((context->count[0] += len << 3) < j) 134 | context->count[1]++; 135 | context->count[1] += (len >> 29); 136 | j = (j >> 3) & 63; 137 | if ((j + len) > 63) { 138 | __byte_copy(&context->buffer[j], data, (i = 64 - j)); 139 | SHA1Transform(context->state, context->buffer); 140 | for (; i + 63 < len; i += 64) { 141 | SHA1Transform(context->state, &data[i]); 142 | } 143 | j = 0; 144 | } 145 | else i = 0; 146 | __byte_copy(&context->buffer[j], &data[i], len - i); 147 | } 148 | 149 | 150 | /* Add padding and return the message digest. */ 151 | 152 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context) 153 | { 154 | unsigned i; 155 | unsigned char finalcount[8]; 156 | unsigned char c; 157 | 158 | for (i = 0; i < 8; i++) { 159 | finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 160 | >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ 161 | } 162 | 163 | c = 0200; 164 | SHA1Update(context, &c, 1); 165 | while ((context->count[0] & 504) != 448) { 166 | c = 0000; 167 | SHA1Update(context, &c, 1); 168 | } 169 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 170 | for (i = 0; i < 20; i++) { 171 | digest[i] = (unsigned char) 172 | ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); 173 | } 174 | /* Wipe variables */ 175 | /* 176 | memset(context, '\0', sizeof(*context)); 177 | memset(&finalcount, '\0', sizeof(finalcount)); 178 | */ 179 | } 180 | 181 | #ifdef __cplusplus 182 | } 183 | #endif 184 | /* ================ end of sha1.c ================ */ 185 | -------------------------------------------------------------------------------- /src/datastruct/tree.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/datastruct/tree.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void treeInit(struct Tree_t* node) { 12 | node->parent = node->child = node->left = node->right = (struct Tree_t*)0; 13 | } 14 | 15 | struct Tree_t* treeRoot(const struct Tree_t* node) { 16 | for (; node && node->parent; node = node->parent); 17 | return (struct Tree_t*)node; 18 | } 19 | 20 | void treeInsertChild(struct Tree_t* parent_node, struct Tree_t* new_node) { 21 | if (new_node->parent) { 22 | return; 23 | } 24 | if (parent_node->child) { 25 | new_node->right = parent_node->child; 26 | parent_node->child->left = new_node; 27 | } 28 | parent_node->child = new_node; 29 | new_node->parent = parent_node; 30 | } 31 | 32 | void treeInsertRight(struct Tree_t* node, struct Tree_t* new_node) { 33 | new_node->left = node; 34 | new_node->right = node->right; 35 | new_node->parent = node->parent; 36 | if (node->right) { 37 | node->right->left = new_node; 38 | } 39 | node->right = new_node; 40 | } 41 | 42 | void treeInsertLeft(struct Tree_t* node, struct Tree_t* new_node) { 43 | new_node->left = node->left; 44 | new_node->right = node; 45 | new_node->parent = node->parent; 46 | if (node->left) { 47 | node->left->right = new_node; 48 | } 49 | node->left = new_node; 50 | } 51 | 52 | void treeRemove(struct Tree_t* node) { 53 | if (node->left) { 54 | node->left->right = node->right; 55 | } 56 | if (node->right) { 57 | node->right->left = node->left; 58 | } 59 | if (node->parent && node->parent->child == node) { 60 | node->parent->child = node->right; 61 | } 62 | node->left = node->right = node->parent = (struct Tree_t*)0; 63 | } 64 | 65 | struct Tree_t* treeBegin(struct Tree_t* node) { 66 | for (; node && node->child; node = node->child); 67 | return node; 68 | } 69 | 70 | struct Tree_t* treeNext(struct Tree_t* node) { 71 | if (node->right) { 72 | node = node->right; 73 | for (; node && node->child; node = node->child); 74 | return node; 75 | } 76 | return node->parent; 77 | } 78 | 79 | struct Tree_t* treeLevelBegin(struct Tree_t* node) { 80 | struct Tree_t* up_node = node->parent; 81 | if (up_node) { 82 | struct Tree_t* dst_node = (struct Tree_t*)0; 83 | do { 84 | if (up_node->child) { 85 | dst_node = up_node->child; 86 | } 87 | up_node = up_node->left; 88 | } while (up_node); 89 | return dst_node; 90 | } 91 | else { 92 | while (node->left) { 93 | node = node->left; 94 | } 95 | return node; 96 | } 97 | } 98 | 99 | struct Tree_t* treeLevelNext(struct Tree_t* node) { 100 | if (node->right) { 101 | return node->right; 102 | } 103 | node = node->parent; 104 | if (!node) { 105 | return (struct Tree_t*)0; 106 | } 107 | while (node->right) { 108 | node = node->right; 109 | if (node->child) { 110 | return node->child; 111 | } 112 | } 113 | return (struct Tree_t*)0; 114 | } 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | -------------------------------------------------------------------------------- /src/sysapi/error.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/error.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int errnoGet(void) { 13 | #if defined(_WIN32) || defined(_WIN64) 14 | DWORD err = GetLastError(); 15 | switch (err) { 16 | case ERROR_TOO_MANY_OPEN_FILES: 17 | errno = ENFILE; 18 | break; 19 | case ERROR_PATH_NOT_FOUND: 20 | case ERROR_FILE_NOT_FOUND: 21 | errno = ENOENT; 22 | break; 23 | case ERROR_DEV_NOT_EXIST: 24 | errno = ENODEV; 25 | break; 26 | case ERROR_FILE_EXISTS: 27 | case ERROR_ALREADY_EXISTS: 28 | errno = EEXIST; 29 | break; 30 | case WSAEBADF: 31 | case ERROR_INVALID_ACCEL_HANDLE: 32 | case ERROR_INVALID_HANDLE: 33 | case ERROR_BAD_PIPE: 34 | case ERROR_FILE_INVALID: 35 | errno = EBADF; 36 | break; 37 | case WSAEACCES: 38 | case ERROR_ACCESS_DENIED: 39 | case ERROR_INVALID_ACCESS: 40 | case ERROR_FILE_READ_ONLY: 41 | errno = EACCES; 42 | break; 43 | case WSAENOBUFS: 44 | case ERROR_NOT_ENOUGH_MEMORY: 45 | errno = ENOMEM; 46 | break; 47 | case ERROR_BUSY: 48 | case ERROR_DS_BUSY: 49 | case ERROR_PIPE_BUSY: 50 | case ERROR_BUSY_DRIVE: 51 | errno = EBUSY; 52 | break; 53 | case WSAETIMEDOUT: 54 | case ERROR_TIMEOUT: 55 | errno = ETIMEDOUT; 56 | break; 57 | case WSAEINVAL: 58 | case ERROR_INVALID_FLAGS: 59 | case ERROR_INVALID_PARAMETER: 60 | errno = EINVAL; 61 | break; 62 | case ERROR_BROKEN_PIPE: 63 | errno = EPIPE; 64 | break; 65 | /**/ 66 | case WSAEINTR: 67 | errno = EINTR; 68 | break; 69 | case WSAESOCKTNOSUPPORT: 70 | case WSAEPFNOSUPPORT: 71 | errno = ENOTSUP; 72 | break; 73 | case WSAEPROTOTYPE: 74 | errno = EPROTOTYPE; 75 | break; 76 | case WSAENOPROTOOPT: 77 | errno = ENOPROTOOPT; 78 | break; 79 | case WSAEPROTONOSUPPORT: 80 | errno = EPROTONOSUPPORT; 81 | break; 82 | case WSAEMSGSIZE: 83 | errno = EMSGSIZE; 84 | break; 85 | case WSAEDESTADDRREQ: 86 | errno = EDESTADDRREQ; 87 | break; 88 | case WSAEFAULT: 89 | case ERROR_INVALID_ADDRESS: 90 | errno = EADDRNOTAVAIL; 91 | break; 92 | case WSAENOTSOCK: 93 | errno = ENOTSOCK; 94 | break; 95 | case WSAEMFILE: 96 | errno = EMFILE; 97 | break; 98 | case WSAEAFNOSUPPORT: 99 | errno = EAFNOSUPPORT; 100 | break; 101 | case WSAEINPROGRESS: 102 | errno = EINPROGRESS; 103 | break; 104 | case WSAEALREADY: 105 | errno = EALREADY; 106 | break; 107 | case WSAEADDRINUSE: 108 | errno = EADDRINUSE; 109 | break; 110 | case WSAENETUNREACH: 111 | errno = ENETUNREACH; 112 | break; 113 | case WSAEISCONN: 114 | errno = EISCONN; 115 | break; 116 | case WSAENOTCONN: 117 | errno = ENOTCONN; 118 | break; 119 | case WSAECONNABORTED: 120 | errno = ECONNABORTED; 121 | break; 122 | case WSAECONNREFUSED: 123 | errno = ECONNREFUSED; 124 | break; 125 | case WSAEHOSTDOWN: 126 | case WSAECONNRESET: 127 | errno = ECONNRESET; 128 | break; 129 | case WSATRY_AGAIN: 130 | case WSAEWOULDBLOCK: 131 | errno = EWOULDBLOCK; 132 | break; 133 | case WSAENOTEMPTY: 134 | errno = ENOTEMPTY; 135 | break; 136 | case WSAELOOP: 137 | errno = ELOOP; 138 | break; 139 | case WSAEOPNOTSUPP: 140 | errno = EOPNOTSUPP; 141 | break; 142 | case WSAENAMETOOLONG: 143 | errno = ENAMETOOLONG; 144 | break; 145 | case WSAEHOSTUNREACH: 146 | errno = EHOSTUNREACH; 147 | break; 148 | default: 149 | errno = err; 150 | } 151 | #else 152 | #if EAGAIN != EWOULDBLOCK 153 | if (EAGAIN == errno) 154 | errno = EWOULDBLOCK; 155 | #endif 156 | #endif 157 | return errno; 158 | } 159 | 160 | void errnoSet(int errnum) { 161 | #if defined(_WIN32) || defined(_WIN64) 162 | SetLastError(errnum); 163 | #endif 164 | errno = errnum; 165 | } 166 | 167 | char* errnoText(int errnum, char* buf, size_t bufsize) { 168 | #if defined(_WIN32) || defined(_WIN64) 169 | return strerror_s(buf, bufsize, errnum) ? NULL : buf; 170 | #else 171 | #if defined(_GNU_SOURCE) 172 | return strerror_r(errnum, buf, bufsize); 173 | #elif defined(_XOPEN_SOURCE) 174 | return strerror_r(errnum, buf, bufsize) ? NULL : buf; 175 | #else 176 | strerror_r(errnum, buf, bufsize); 177 | return buf; 178 | #endif 179 | #endif 180 | } 181 | 182 | #ifdef __cplusplus 183 | } 184 | #endif 185 | -------------------------------------------------------------------------------- /src/sysapi/misc.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/misc.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | void* alignMalloc(size_t nbytes, size_t alignment) { 13 | #if defined(_WIN32) || defined(_WIN64) 14 | return alignment ? _aligned_malloc(nbytes, alignment) : NULL; 15 | #elif defined(__linux__) 16 | return alignment ? memalign(alignment, nbytes) : NULL; 17 | #else 18 | if (alignment <= 0) { 19 | return NULL; 20 | } 21 | size_t padsize = alignment > sizeof(size_t) ? alignment : sizeof(size_t); 22 | size_t ptr = (size_t)malloc(nbytes + padsize); 23 | if (NULL == (void*)ptr) { 24 | return NULL; 25 | } 26 | size_t new_ptr = (ptr + sizeof(size_t) + alignment - 1) & ~(alignment - 1); 27 | *(((size_t*)new_ptr) - 1) = new_ptr - ptr; 28 | return (void*)new_ptr; 29 | #endif 30 | } 31 | 32 | void alignFree(const void* ptr) { 33 | #if defined(_WIN32) || defined(_WIN64) 34 | _aligned_free((void*)ptr); 35 | #elif defined(__linux__) 36 | free((void*)ptr); 37 | #else 38 | if (ptr) { 39 | size_t off = *(((size_t*)ptr) - 1); 40 | free((char*)ptr - off); 41 | } 42 | #endif 43 | } 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /src/sysapi/mmap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/mmap.h" 6 | #if !defined(_WIN32) && !defined(_WIN64) 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | /*#include */ 13 | #endif 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | BOOL memoryCreateMapping(ShareMemMap_t* mm, const char* name, size_t nbytes) { 20 | /* note: if already exist, size is lesser or equal than the size of that segment */ 21 | #if defined(_WIN32) || defined(_WIN64) 22 | HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, ((long long)nbytes) >> 32, nbytes, name); 23 | if (!handle) { 24 | return FALSE; 25 | } 26 | /* 27 | if (GetLastError() == ERROR_ALREADY_EXISTS) { 28 | CloseHandle(handle); 29 | return FALSE; 30 | } 31 | */ 32 | *mm = handle; 33 | return TRUE; 34 | #else 35 | key_t k = ftok(name, 0); 36 | if ((key_t)-1 == k) { 37 | return FALSE; 38 | } 39 | *mm = shmget(k, nbytes, 0666 | IPC_CREAT); 40 | return (*mm) != -1; 41 | #endif 42 | } 43 | 44 | BOOL memoryOpenMapping(ShareMemMap_t* mm, const char* name) { 45 | #if defined(_WIN32) || defined(_WIN64) 46 | *mm = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, name); 47 | return (*mm) != NULL; 48 | #else 49 | key_t k = ftok(name, 0); 50 | if ((key_t)-1 == k) { 51 | return FALSE; 52 | } 53 | *mm = shmget(k, 0, 0666); 54 | return (*mm) != -1; 55 | #endif 56 | } 57 | 58 | BOOL memoryCloseMapping(ShareMemMap_t mm) { 59 | #if defined(_WIN32) || defined(_WIN64) 60 | return CloseHandle(mm); 61 | #else 62 | return shmctl(mm, IPC_RMID, NULL) == 0; 63 | #endif 64 | } 65 | 66 | BOOL memoryDoMapping(ShareMemMap_t mm, void* va_base, size_t nbytes, void** ret_mptr) { 67 | #if defined(_WIN32) || defined(_WIN64) 68 | void* addr = MapViewOfFileEx(mm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, nbytes, va_base); 69 | if (!addr) { 70 | return FALSE; 71 | } 72 | *ret_mptr = addr; 73 | return TRUE; 74 | #else 75 | void* addr = shmat(mm, va_base, 0); 76 | if ((void*)-1 == addr) { 77 | return FALSE; 78 | } 79 | *ret_mptr = addr; 80 | return TRUE; 81 | #endif 82 | } 83 | 84 | BOOL memoryUndoMapping(void* mptr) { 85 | #if defined(_WIN32) || defined(_WIN64) 86 | return UnmapViewOfFile(mptr); 87 | #else 88 | return shmdt(mptr) == 0; 89 | #endif 90 | } 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | -------------------------------------------------------------------------------- /src/sysapi/module.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/module.h" 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | static void module_empty_probe() {} 14 | 15 | void* moduleAddress(const void* symbol_addr) { 16 | #if defined(_WIN32) || defined(_WIN64) 17 | HMODULE m; 18 | if (!symbol_addr) { 19 | symbol_addr = (const void*)module_empty_probe; 20 | } 21 | if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PTCHAR)symbol_addr, &m)) { 22 | return (void*)m; 23 | } 24 | return NULL; 25 | #else 26 | Dl_info dl_info; 27 | if (!symbol_addr) { 28 | symbol_addr = (const void*)module_empty_probe; 29 | } 30 | if (dladdr((void*)symbol_addr, &dl_info)) { 31 | return dlopen(dl_info.dli_fname, RTLD_NOW); 32 | } 33 | return NULL; 34 | #endif 35 | } 36 | 37 | size_t modulePathLength(void* md) { 38 | #if defined(_WIN32) || defined(_WIN64) 39 | size_t n = MAX_PATH; 40 | char* buf = NULL; 41 | do { 42 | DWORD ret; 43 | char* newbuf = (char*)realloc(buf, n); 44 | if (!newbuf) { 45 | break; 46 | } 47 | buf = newbuf; 48 | ret = GetModuleFileNameA((HMODULE)md, buf, n); 49 | if (!ret) { 50 | break; 51 | } 52 | if (ret < n) { 53 | free(buf); 54 | return ret; 55 | } 56 | n += MAX_PATH; 57 | } while (1); 58 | free(buf); 59 | return 0; 60 | #elif __linux__ 61 | struct link_map *lm; 62 | if (dlinfo(md, RTLD_DI_LINKMAP, &lm)) { 63 | return 0; 64 | } 65 | return strlen(lm->l_name); 66 | #else 67 | return 0; 68 | #endif 69 | } 70 | 71 | size_t moduleFillPath(void* md, char* buf, size_t n) { 72 | #if defined(_WIN32) || defined(_WIN64) 73 | DWORD ret = GetModuleFileNameA((HMODULE)md, buf, n); 74 | if (!ret) { 75 | return 0; 76 | } 77 | if (n > ret) { 78 | buf[ret] = 0; 79 | return ret; 80 | } 81 | else { 82 | buf[n - 1] = 0; 83 | return n - 1; 84 | } 85 | #elif __linux__ 86 | struct link_map *lm; 87 | if (dlinfo(md, RTLD_DI_LINKMAP, &lm)) { 88 | return 0; 89 | } 90 | strncpy(buf, lm->l_name, n); 91 | buf[n - 1] = 0; 92 | return n - 1; 93 | #else 94 | return 0; 95 | #endif 96 | } 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | -------------------------------------------------------------------------------- /src/sysapi/statistics.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/statistics.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | long memoryPageSize(void) { 13 | #if defined(_WIN32) || defined(_WIN64) 14 | SYSTEM_INFO si; 15 | GetSystemInfo(&si); 16 | return si.dwPageSize; 17 | #else 18 | return sysconf(_SC_PAGESIZE); 19 | #endif 20 | } 21 | 22 | unsigned long long memorySize(void) { 23 | #if defined(_WIN32) || defined(_WIN64) 24 | MEMORYSTATUSEX statex = { 0 }; 25 | statex.dwLength = sizeof(statex); 26 | if (GlobalMemoryStatusEx(&statex)) { 27 | return statex.ullTotalPhys; 28 | //*avail = statex.ullAvailPhys; 29 | //return TRUE; 30 | } 31 | return 0; 32 | //return FALSE; 33 | #elif __linux__ 34 | unsigned long page_size, total_page; 35 | if ((page_size = sysconf(_SC_PAGESIZE)) == -1) 36 | return 0; 37 | if ((total_page = sysconf(_SC_PHYS_PAGES)) == -1) 38 | return 0; 39 | //if((free_page = sysconf(_SC_AVPHYS_PAGES)) == -1) 40 | //return FALSE; 41 | return (unsigned long long)total_page * (unsigned long long)page_size; 42 | //*avail = (unsigned long long)free_page * (unsigned long long)page_size; 43 | //return TRUE; 44 | #elif __APPLE__ 45 | int64_t value; 46 | size_t len = sizeof(value); 47 | return sysctlbyname("hw.memsize", &value, &len, NULL, 0) != -1 ? value : 0; 48 | //*avail = 0;// sorry... 49 | //return TRUE; 50 | #endif 51 | } 52 | 53 | size_t processorCount(void) { 54 | #if defined(_WIN32) || defined(_WIN64) 55 | SYSTEM_INFO si; 56 | GetSystemInfo(&si); 57 | return si.dwNumberOfProcessors ? si.dwNumberOfProcessors : 1; 58 | #else 59 | /*long count = sysconf(_SC_NPROCESSORS_CONF);*/ 60 | long count = sysconf(_SC_NPROCESSORS_ONLN); 61 | if (count <= 0) { 62 | return 1; 63 | } 64 | return count; 65 | #endif 66 | } 67 | 68 | char* systemCurrentLoginUsername(char* buffer, size_t nbytes) { 69 | #if defined(_WIN32) || defined(_WIN64) 70 | DWORD len = nbytes; 71 | return GetUserNameA(buffer, &len) ? buffer : NULL; 72 | #else 73 | struct passwd pwd, *res = NULL; 74 | int r = getpwuid_r(getuid(), &pwd, buffer, nbytes, &res); 75 | if (!res && r) { 76 | errno = r; 77 | return NULL; 78 | } 79 | return buffer; 80 | #endif 81 | } 82 | 83 | char* systemHostname(char* buf, size_t len) { 84 | #if defined(_WIN32) || defined(_WIN64) 85 | DWORD dwLen = len; 86 | return GetComputerNameA(buf, &dwLen) ? buf : NULL; 87 | #else 88 | return gethostname(buf, len) == 0 ? buf : NULL; 89 | #endif 90 | } 91 | 92 | BOOL diskPartitionSize(const char* dev_path, unsigned long long* total_bytes, unsigned long long* free_bytes, unsigned long long* availabel_bytes, unsigned long long* block_bytes) { 93 | #if defined(_WIN32) || defined(_WIN64) 94 | ULARGE_INTEGER t, f, a; 95 | if (!GetDiskFreeSpaceExA(dev_path, &a, &t, &f)) { 96 | return FALSE; 97 | } 98 | if (block_bytes) { 99 | DWORD spc, bps, nfc, tnc; 100 | if (!GetDiskFreeSpaceA(dev_path, &spc, &bps, &nfc, &tnc)) 101 | return FALSE; 102 | *block_bytes = spc * bps; 103 | } 104 | if (total_bytes) 105 | *total_bytes = t.QuadPart; 106 | if (free_bytes) 107 | *free_bytes = f.QuadPart; 108 | if (availabel_bytes) 109 | *availabel_bytes = a.QuadPart; 110 | return TRUE; 111 | #else 112 | struct statvfs disk_info = { 0 }; 113 | if (!statvfs(dev_path, &disk_info)) { 114 | unsigned long f_bsize = disk_info.f_bsize; 115 | if (total_bytes) { 116 | *total_bytes = disk_info.f_blocks; 117 | *total_bytes *= f_bsize; 118 | } 119 | if (free_bytes) { 120 | *free_bytes = disk_info.f_bfree; 121 | *free_bytes *= f_bsize; 122 | } 123 | if (availabel_bytes) { 124 | *availabel_bytes = disk_info.f_bavail; 125 | *availabel_bytes *= f_bsize; 126 | } 127 | if (block_bytes) 128 | *block_bytes = f_bsize; 129 | return TRUE; 130 | } 131 | return FALSE; 132 | #endif 133 | } 134 | 135 | /* 136 | #if defined(_WIN32) || defined(_WIN64) 137 | #pragma comment(lib, "Advapi32.lib") 138 | #pragma comment(lib, "Crypt32.lib") 139 | #endif 140 | #if defined(_WIN32) || defined(_WIN64) 141 | typedef struct __WIN32_CRYPT_CTX { 142 | HCRYPTPROV hProv; 143 | HCRYPTHASH hHash; 144 | DWORD dwLen; 145 | } __WIN32_CRYPT_CTX; 146 | 147 | static BOOL __win32_crypt_init(struct __WIN32_CRYPT_CTX* ctx) { 148 | ctx->hProv = ctx->hHash = 0; 149 | return CryptAcquireContext(&ctx->hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 150 | } 151 | static BOOL __win32_crypt_hash_create(struct __WIN32_CRYPT_CTX* ctx, DWORD Algid) { 152 | DWORD dwDataLen = sizeof(ctx->dwLen); 153 | if (!CryptCreateHash(ctx->hProv, Algid, 0, 0, &ctx->hHash)) { 154 | return FALSE; 155 | } 156 | return CryptGetHashParam(ctx->hHash, HP_HASHSIZE, (BYTE*)(&ctx->dwLen), &dwDataLen, 0); 157 | } 158 | static BOOL __win32_crypt_update(struct __WIN32_CRYPT_CTX* ctx, const BYTE* data, DWORD len) { 159 | return CryptHashData(ctx->hHash, (const BYTE*)data, len, 0); 160 | } 161 | static BOOL __win32_crypt_final(unsigned char* data, struct __WIN32_CRYPT_CTX* ctx) { 162 | return CryptGetHashParam(ctx->hHash, HP_HASHVAL, data, &ctx->dwLen, 0); 163 | } 164 | static BOOL __win32_crypt_clean(struct __WIN32_CRYPT_CTX* ctx) { 165 | if (ctx->hHash && !CryptDestroyHash(ctx->hHash)) { 166 | return FALSE; 167 | } 168 | return CryptReleaseContext(ctx->hProv, 0); 169 | } 170 | #endif 171 | */ 172 | 173 | #ifdef __cplusplus 174 | } 175 | #endif 176 | -------------------------------------------------------------------------------- /src/sysapi/time.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #include "../../inc/sysapi/time.h" 6 | #include 7 | #include 8 | #include 9 | #if defined(__APPLE__) || defined(__MACH__) 10 | #include 11 | #include 12 | #include 13 | #endif 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | int TIMESTAMP_OFFSET_SECOND = 0; 20 | 21 | /* time trasform */ 22 | int gmtimeTimezoneOffsetSecond(void) { 23 | static int tm_gmtoff; 24 | if (0 == tm_gmtoff) { 25 | #if defined(WIN32) || defined(_WIN64) 26 | TIME_ZONE_INFORMATION tz; 27 | if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_INVALID) 28 | return -1; 29 | tm_gmtoff = tz.Bias * 60; 30 | #else 31 | time_t v = time(NULL); 32 | struct tm tm; 33 | if (!localtime_r(&v, &tm)) { 34 | return -1; 35 | } 36 | tm_gmtoff = -tm.tm_gmtoff; 37 | /* 38 | struct timeval tv; 39 | struct timezone tz; 40 | if (gettimeofday(&tv, &tz)) 41 | return -1; 42 | tm_gmtoff = tz.tz_minuteswest * 60; 43 | */ 44 | #endif 45 | } 46 | return tm_gmtoff; 47 | } 48 | 49 | time_t gmtimeSecond(void) { 50 | time_t v; 51 | return time(&v); 52 | } 53 | 54 | time_t localWeekBeginGmtSecond(time_t gmt_sec, int tz_off) { 55 | /* since from 1970-1-1 0:0:0 */ 56 | return (gmt_sec - tz_off - 345600) / 604800 * 604800 + 345600 + tz_off; 57 | } 58 | 59 | time_t localtimeSecond(void) { 60 | return gmtimeSecond() - gmtimeTimezoneOffsetSecond(); 61 | } 62 | 63 | long long gmtimeMillisecond(void) { 64 | #if defined(WIN32) || defined(_WIN64) 65 | long long intervals; 66 | FILETIME ft; 67 | GetSystemTimeAsFileTime(&ft); 68 | intervals = ((long long)ft.dwHighDateTime << 32) | ft.dwLowDateTime; 69 | intervals -= 116444736000000000; 70 | return intervals / 10000; 71 | #else 72 | struct timeval tval; 73 | if (0 == gettimeofday(&tval, NULL)) { 74 | long long sec = tval.tv_sec;/* avoid overflow */ 75 | return sec * 1000 + tval.tv_usec / 1000; 76 | } 77 | return 0; 78 | #endif 79 | } 80 | 81 | struct tm* gmtimeTM(time_t value, struct tm* datetime) { 82 | #if defined(WIN32) || defined(_WIN64) 83 | int res = gmtime_s(datetime, &value); 84 | if (res) { 85 | errno = res; 86 | return NULL; 87 | } 88 | #else 89 | if (gmtime_r(&value, datetime) == NULL) 90 | return NULL; 91 | #endif 92 | return datetime; 93 | } 94 | 95 | struct tm* gmtimeLocalTM(time_t value, struct tm* datetime) { 96 | #if defined(WIN32) || defined(_WIN64) 97 | int res = localtime_s(datetime, &value); 98 | if (res) { 99 | errno = res; 100 | return NULL; 101 | } 102 | #else 103 | if (localtime_r(&value, datetime) == NULL) 104 | return NULL; 105 | #endif 106 | return datetime; 107 | } 108 | 109 | char* structtmText(struct tm* datetime, char* buf, size_t len) { 110 | char* c; 111 | #if defined(WIN32) || defined(_WIN64) 112 | int res = asctime_s(buf, len, datetime); 113 | if (res) { 114 | errno = res; 115 | return NULL; 116 | } 117 | #else 118 | if (asctime_r(datetime, buf) == NULL) 119 | return NULL; 120 | #endif 121 | if ((c = strchr(buf, '\n'))) { 122 | *c = 0; 123 | } 124 | return buf; 125 | } 126 | 127 | struct tm* structtmNormal(struct tm* datetime) { 128 | if (datetime) { 129 | datetime->tm_year += 1900; 130 | datetime->tm_mon += 1; 131 | if (0 == datetime->tm_wday) 132 | datetime->tm_wday = 7; 133 | } 134 | return datetime; 135 | } 136 | 137 | struct tm* structtmUnnormal(struct tm* datetime) { 138 | if (datetime) { 139 | datetime->tm_year -= 1900; 140 | datetime->tm_mon -= 1; 141 | if (7 == datetime->tm_wday) 142 | datetime->tm_wday = 0; 143 | } 144 | return datetime; 145 | } 146 | 147 | int structtmCmp(const struct tm* t1, const struct tm* t2) { 148 | if (t1->tm_yday > t2->tm_yday) { 149 | return 1; 150 | } 151 | if (t1->tm_yday < t2->tm_yday) { 152 | return -1; 153 | } 154 | if (t1->tm_hour > t2->tm_hour) { 155 | return 1; 156 | } 157 | if (t1->tm_hour < t2->tm_hour) { 158 | return -1; 159 | } 160 | if (t1->tm_min > t2->tm_min) { 161 | return 1; 162 | } 163 | if (t1->tm_min < t2->tm_min) { 164 | return -1; 165 | } 166 | if (t1->tm_sec > t2->tm_sec) { 167 | return 1; 168 | } 169 | if (t1->tm_sec < t2->tm_sec) { 170 | return -1; 171 | } 172 | return 0; 173 | } 174 | 175 | long long clockNanosecond(void) { 176 | #if defined(WIN32) || defined(_WIN64) 177 | static LARGE_INTEGER s_frep; 178 | LARGE_INTEGER counter; 179 | if (0 == s_frep.QuadPart) { 180 | if (!QueryPerformanceFrequency(&s_frep) || 0 == s_frep.QuadPart) { 181 | return -1; 182 | } 183 | } 184 | if (!QueryPerformanceCounter(&counter)) 185 | return -1; 186 | return (double)counter.QuadPart / s_frep.QuadPart * 1000000000; 187 | #elif __linux__ 188 | struct timespec ts; 189 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) 190 | return -1; 191 | return ts.tv_sec * 1000000000LL + ts.tv_nsec; 192 | #elif __FreeBSD__ 193 | struct timespec ts; 194 | if (clock_gettime(CLOCK_UPTIME, &ts) < 0) 195 | return -1; 196 | return ts.tv_sec * 1000000000LL + ts.tv_nsec; 197 | #elif defined(__APPLE__) || defined(__MACH__) 198 | static mach_timebase_info_data_t s_timebase_info; 199 | if (0 == s_timebase_info.denom) { 200 | mach_timebase_info(&s_timebase_info); 201 | if (0 == s_timebase_info.denom) 202 | return -1; 203 | } 204 | return mach_absolute_time() * s_timebase_info.numer / s_timebase_info.denom; 205 | #else 206 | return -1; 207 | #endif 208 | } 209 | 210 | #ifdef __cplusplus 211 | } 212 | #endif 213 | -------------------------------------------------------------------------------- /src/sysapi/win32_misc.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by hujianzhe 3 | // 4 | 5 | #ifdef _WIN32 6 | #include "../../inc/platform_define.h" 7 | #include 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | char* win32_Path_Win32Style(const char* path) { 15 | char* p = strdup(path); 16 | if (p) { 17 | char* pa; 18 | for (pa = p; *pa; ++pa) { 19 | if ('/' == *pa) 20 | *pa = '\\'; 21 | } 22 | } 23 | return p; 24 | } 25 | 26 | BOOL win32_Iocp_PrepareRegUdp(SOCKET fd, int domain) { 27 | struct sockaddr_storage local_saddr; 28 | socklen_t slen; 29 | DWORD dwBytesReturned = 0; 30 | BOOL bNewBehavior = FALSE; 31 | /* winsock2 BUG, udp recvfrom WSAECONNRESET(10054) error and post Overlapped IO error */ 32 | if (WSAIoctl(fd, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL)) { 33 | return FALSE; 34 | } 35 | /* note: UDP socket need bind a address before call WSA function, otherwise WSAGetLastError return WSAINVALID */ 36 | slen = sizeof(local_saddr); 37 | if (!getsockname(fd, (struct sockaddr*)&local_saddr, &slen)) { 38 | return TRUE; 39 | } 40 | if (WSAEINVAL != WSAGetLastError()) { 41 | return FALSE; 42 | } 43 | if (AF_INET == domain) { 44 | struct sockaddr_in* addr_in = (struct sockaddr_in*)&local_saddr; 45 | slen = sizeof(*addr_in); 46 | memset(addr_in, 0, sizeof(*addr_in)); 47 | addr_in->sin_family = AF_INET; 48 | addr_in->sin_port = 0; 49 | addr_in->sin_addr.s_addr = htonl(INADDR_ANY); 50 | } 51 | else if (AF_INET6 == domain) { 52 | struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*)&local_saddr; 53 | slen = sizeof(*addr_in6); 54 | memset(addr_in6, 0, sizeof(*addr_in6)); 55 | addr_in6->sin6_family = AF_INET6; 56 | addr_in6->sin6_port = 0; 57 | addr_in6->sin6_addr = in6addr_any; 58 | } 59 | else { 60 | WSASetLastError(WSAEAFNOSUPPORT); 61 | return FALSE; 62 | } 63 | if (bind(fd, (struct sockaddr*)&local_saddr, slen)) { 64 | return FALSE; 65 | } 66 | return TRUE; 67 | } 68 | 69 | int win32_OverlappedConnectUpdate(SOCKET fd) { 70 | int sec = ~0, err; 71 | int len = sizeof(sec); 72 | if (getsockopt(fd, SOL_SOCKET, SO_CONNECT_TIME, (char*)&sec, &len)) { 73 | return WSAGetLastError(); 74 | } 75 | if (~0 == sec) { 76 | return WSAETIMEDOUT; 77 | } 78 | if (setsockopt(fd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) { 79 | return WSAGetLastError(); 80 | } 81 | err = 0; 82 | len = sizeof(err); 83 | if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&err, &len)) { 84 | return WSAGetLastError(); 85 | } 86 | return 0; 87 | } 88 | 89 | #ifdef __cplusplus 90 | } 91 | #endif 92 | 93 | #endif // _WIN32 --------------------------------------------------------------------------------