hewei.it 5 роки тому
батько
коміт
efc75784c8
59 змінених файлів з 1149 додано та 976 видалено
  1. 1 0
      CMake/vars.cmake
  2. 2 0
      Makefile
  3. 3 3
      Makefile.in
  4. 1 0
      Makefile.vars
  5. 70 8
      base/hbase.c
  6. 13 4
      base/hbase.h
  7. 2 0
      base/hbuf.h
  8. 151 175
      base/hdef.h
  9. 1 1
      base/herr.h
  10. 4 0
      base/hlog.c
  11. 4 0
      base/hlog.h
  12. 54 0
      base/hmap.h
  13. 45 47
      base/hobj.h
  14. 62 14
      base/hplatform.h
  15. 2 2
      base/hstring.cpp
  16. 3 45
      base/hstring.h
  17. 2 2
      base/hsysinfo.h
  18. 57 41
      base/hthread.h
  19. 68 82
      base/htime.c
  20. 37 30
      base/htime.h
  21. 12 13
      base/hvar.h
  22. 1 1
      base/hversion.h
  23. 3 0
      base/list.h
  24. 2 1
      configure
  25. 295 290
      docs/apis.md
  26. 4 4
      event/hloop.c
  27. 5 5
      event/nmap.cpp
  28. 3 3
      event/nmap.h
  29. 1 1
      examples/consul_cli.cpp
  30. 1 1
      examples/hmain_test.cpp
  31. 1 1
      examples/httpd/httpd.cpp
  32. 1 1
      examples/nc.c
  33. 9 9
      examples/nmap.cpp
  34. 1 1
      examples/tcp.c
  35. 1 1
      examples/udp.c
  36. 4 4
      hconfig.h
  37. 36 36
      http/Http1Parser.cpp
  38. 7 7
      http/Http1Parser.h
  39. 31 31
      http/Http2Parser.cpp
  40. 7 7
      http/Http2Parser.h
  41. 1 1
      http/HttpMessage.h
  42. 25 0
      http/HttpParser.cpp
  43. 14 14
      http/HttpParser.h
  44. 0 25
      http/HttpSession.cpp
  45. 13 13
      http/client/http_client.cpp
  46. 1 1
      http/http_content.h
  47. 3 3
      http/server/HttpHandler.h
  48. 24 24
      http/server/HttpServer.cpp
  49. 11 10
      hv.h
  50. 8 0
      unittest/CMakeLists.txt
  51. 15 0
      unittest/date_test.c
  52. 1 1
      unittest/hstring_test.cpp
  53. 10 0
      unittest/mkdir_test.c
  54. 1 1
      unittest/nslookup_test.c
  55. 2 2
      unittest/sendmail_test.c
  56. 4 2
      utils/hendian.h
  57. 6 5
      utils/hmain.cpp
  58. 1 1
      utils/hmain.h
  59. 2 2
      utils/singleton.h

+ 1 - 0
CMake/vars.cmake

@@ -18,6 +18,7 @@ set(BASE_HEADERS
     base/hurl.h
     base/hgui.h
     base/ssl_ctx.h
+    base/hmap.h
     base/hstring.h
     base/hvar.h
     base/hobj.h

+ 2 - 0
Makefile

@@ -91,6 +91,8 @@ consul_cli: prepare
 	$(MAKEF) TARGET=$@ SRCDIRS=". base utils http http/client consul" SRCS="examples/consul_cli.cpp" DEFINES="PRINT_DEBUG"
 
 unittest: prepare
+	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/mkdir_p           unittest/mkdir_test.c         base/hbase.c
+	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/date              unittest/date_test.c          base/htime.c
 	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/hmutex_test       unittest/hmutex_test.c        base/htime.c -pthread
 	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/connect_test      unittest/connect_test.c       base/hsocket.c base/htime.c
 	$(CC)  -g -Wall -std=c99   -I. -Ibase            -o bin/socketpair_test   unittest/socketpair_test.c    base/hsocket.c

+ 3 - 3
Makefile.in

@@ -54,8 +54,8 @@ endif
 ifneq ($(findstring android, $(TARGET_PLATFORM)), )
 	OS=Android
 endif
-ifneq ($(findstring apple, $(TARGET_PLATFORM)), )
-	OS=Apple
+ifneq ($(findstring darwin, $(TARGET_PLATFORM)), )
+	OS=Darwin
 endif
 ifndef OS
 	OS=Linux
@@ -238,7 +238,7 @@ ifneq ($(findstring SHARED, $(TARGET_TYPE)), )
 ifeq ($(OS), Windows)
 	$(CC) -shared $^ -o $(LIBDIR)/$@.dll $(LDFLAGS) -Wl,--output-def,$(LIBDIR)/$(@).def
 else
-ifeq ($(OS), Apple)
+ifeq ($(OS), Darwin)
 	$(CC) -dynamiclib -install_name @rpath/$@.dylib $^ -o $(LIBDIR)/$@.dylib $(LDFLAGS)
 else
 	$(CC) -shared $^ -o $(LIBDIR)/$@.so $(LDFLAGS)

+ 1 - 0
Makefile.vars

@@ -24,6 +24,7 @@ BASE_HEADERS =  base/hplatform.h\
 				base/hgui.h\
 				base/ssl_ctx.h\
 				\
+				base/hmap.h\
 				base/hstring.h\
 				base/hvar.h\
 				base/hobj.h\

+ 70 - 8
base/hbase.c

@@ -151,18 +151,80 @@ bool strcontains(const char* str, const char* sub) {
 }
 
 char* strrchr_dir(const char* filepath) {
-    char* b = (char*)filepath;
-    char* e = b;
-    while (*e) ++e;
-    while (--e >= b) {
+    char* p = (char*)filepath;
+    while (*p) ++p;
+    while (--p >= filepath) {
 #ifdef OS_WIN
-        if (*e == '/' || *e == '\\')
+        if (*p == '/' || *p == '\\')
 #else
-        if (*e == '/')
+        if (*p == '/')
 #endif
-            return e;
+            return p;
     }
-    return b;
+    return NULL;
+}
+
+const char* hv_basename(const char* filepath) {
+    const char* pos = strrchr_dir(filepath);
+    return pos ? pos+1 : filepath;
+}
+
+const char* hv_suffixname(const char* filename) {
+    const char* pos = strrchr_dot(filename);
+    return pos ? pos+1 : "";
+}
+
+int hv_mkdir_p(const char* dir) {
+    if (access(dir, 0) == 0) {
+        return EEXIST;
+    }
+    char tmp[MAX_PATH];
+    safe_strncpy(tmp, dir, sizeof(tmp));
+    char* p = tmp;
+    char delim = '/';
+    while (*p) {
+#ifdef OS_WIN
+        if (*p == '/' || *p == '\\') {
+            delim = *p;
+#else
+        if (*p == '/') {
+#endif
+            *p = '\0';
+            hv_mkdir(tmp);
+            *p = delim;
+        }
+        ++p;
+    }
+    if (hv_mkdir(tmp) != 0) {
+        return EPERM;
+    }
+    return 0;
+}
+
+int hv_rmdir_p(const char* dir) {
+    if (access(dir, 0) != 0) {
+        return ENOENT;
+    }
+    if (rmdir(dir) != 0) {
+        return EPERM;
+    }
+    char tmp[MAX_PATH];
+    safe_strncpy(tmp, dir, sizeof(tmp));
+    char* p = tmp;
+    while (*p) ++p;
+    while (--p >= tmp) {
+#ifdef OS_WIN
+        if (*p == '/' || *p == '\\') {
+#else
+        if (*p == '/') {
+#endif
+            *p = '\0';
+            if (rmdir(tmp) != 0) {
+                return 0;
+            }
+        }
+    }
+    return 0;
 }
 
 bool getboolean(const char* str) {

+ 13 - 4
base/hbase.h

@@ -5,7 +5,7 @@
 
 BEGIN_EXTERN_C
 
-//---------------------safe alloc/free---------------------------
+//--------------------safe alloc/free---------------------------
 extern unsigned int g_alloc_cnt;
 extern unsigned int g_free_cnt;
 
@@ -39,7 +39,7 @@ static inline void hv_memcheck() {
 
 #define HV_MEMCHECK    atexit(hv_memcheck);
 
-//-----------------------------safe string-----------------------
+//--------------------safe string-------------------------------
 char* strupper(char* str);
 char* strlower(char* str);
 char* strreverse(char* str);
@@ -47,8 +47,6 @@ char* strreverse(char* str);
 bool strstartswith(const char* str, const char* start);
 bool strendswith(const char* str, const char* end);
 bool strcontains(const char* str, const char* sub);
-#define strrchr_dot(str) strrchr(str, '.')
-char* strrchr_dir(const char* filepath);
 
 // strncpy n = sizeof(dest_buf)-1
 // safe_strncpy n = sizeof(dest_buf)
@@ -66,6 +64,17 @@ char* safe_strncat(char* dest, const char* src, size_t n);
 #define strlcat safe_strncat
 #endif
 
+#define strrchr_dot(str) strrchr(str, '.')
+char* strrchr_dir(const char* filepath);
+
+// basename
+const char* hv_basename(const char* filepath);
+const char* hv_suffixname(const char* filename);
+// mkdir -p
+int hv_mkdir_p(const char* dir);
+// rmdir -p
+int hv_rmdir_p(const char* dir);
+
 // 1 y on yes true enable
 bool getboolean(const char* str);
 

+ 2 - 0
base/hbuf.h

@@ -229,6 +229,8 @@ public:
         }
     }
 
+    void clear() {_head = _tail = _size = 0;}
+
     size_t size() {return _size;}
 
 private:

+ 151 - 175
base/hdef.h

@@ -3,97 +3,6 @@
 
 #include "hplatform.h"
 
-typedef float               float32;
-typedef double              float64;
-typedef void*               handle;
-
-typedef union {
-    bool        b;
-    char        ch;
-    char*       str;
-    long long   num;
-    float       f;
-    double      lf;
-    void*       ptr;
-} var;
-
-typedef int (*method_t)(void* userdata);
-typedef void (*procedure_t)(void* userdata);
-
-#ifdef _MSC_VER
-    typedef int pid_t;
-    typedef int gid_t;
-    typedef int uid_t;
-    #define strcasecmp  stricmp
-    #define strncasecmp strnicmp
-#else
-    #include <strings.h>
-    #define stricmp     strcasecmp
-    #define strnicmp    strncasecmp
-#endif
-
-#ifdef PRINT_DEBUG
-#define printd printf
-#else
-#define printd(...)
-#endif
-
-#ifndef MAX_PATH
-#define MAX_PATH          260
-#endif
-
-#ifndef NULL
-#define NULL        0
-#endif
-
-#ifndef TRUE
-#define TRUE        1
-#endif
-
-#ifndef FALSE
-#define FALSE       0
-#endif
-
-#ifndef INFINITE
-#define INFINITE    (uint32_t)-1
-#endif
-
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
-
-#ifndef OPTIONAL
-#define OPTIONAL
-#endif
-
-#ifndef REQUIRED
-#define REQUIRED
-#endif
-
-#ifndef REPEATED
-#define REPEATED
-#endif
-
-#ifndef LD
-#define LD(v)   ((long)(v))
-#endif
-
-#ifndef LU
-#define LU(v)   ((unsigned long)(v))
-#endif
-
-#ifndef LLD
-#define LLD(v)   ((long long)(v))
-#endif
-
-#ifndef LLU
-#define LLU(v)   ((unsigned long long)(v))
-#endif
-
 #ifndef ABS
 #define ABS(n)  ((n) > 0 ? (n) : -(n))
 #endif
@@ -102,16 +11,8 @@ typedef void (*procedure_t)(void* userdata);
 #define NABS(n) ((n) < 0 ? (n) : -(n))
 #endif
 
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifndef MIN
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-#ifndef LIMIT
-#define LIMIT(lower, v, upper) ((v) < (lower) ? (lower) : (v) > (upper) ? (upper) : (v))
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
 #endif
 
 #ifndef BITSET
@@ -126,19 +27,6 @@ typedef void (*procedure_t)(void* userdata);
 #define BITGET(i, n) ((i) & (1u << (n)))
 #endif
 
-// ASCII:
-// [0, 0x20)    control-charaters
-// [0x20, 0x7F) printable-charaters
-//
-// 0x0A => LF
-// 0x0D => CR
-// 0x20 => SPACE
-// 0x7F => DEL
-//
-// [0x09, 0x0D] => \t\n\v\f\r
-// [0x30, 0x39] => 0~9
-// [0x41, 0x5A] => A~Z
-// [0x61, 0x7A] => a~z
 #ifndef CR
 #define CR      '\r'
 #endif
@@ -151,36 +39,52 @@ typedef void (*procedure_t)(void* userdata);
 #define CRLF    "\r\n"
 #endif
 
-#ifndef LOWER
-#define LOWER(c)    ((c) | 0x20)
-#endif
+#define FLOAT_PRECISION     1e-6
+#define FLOAT_EQUAL_ZERO(f) (ABS(f) < FLOAT_PRECISION)
 
-#ifndef UPPER
-#define UPPER(c)    ((c) & ~0x20)
+// @param[IN|OUT|INOUT]
+#ifndef IN
+#define IN
 #endif
 
-#ifndef IS_NUM
-#define IS_NUM(c)   ((c) >= '0' && (c) <= '9')
+#ifndef OUT
+#define OUT
 #endif
 
-#ifndef IS_UPPER
-#define IS_UPPER(c) (((c) >= 'A' && (c) <= 'Z'))
+#ifndef INOUT
+#define INOUT
 #endif
 
-#ifndef IS_LOWER
-#define IS_LOWER(c) (((c) >= 'a' && (c) <= 'z'))
+#ifndef INFINITE
+#define INFINITE    (uint32_t)-1
 #endif
 
+/*
+ASCII:
+[0, 0x20)    control-charaters
+[0x20, 0x7F) printable-charaters
+
+0x0A => LF
+0x0D => CR
+0x20 => SPACE
+0x7F => DEL
+
+[0x09, 0x0D] => \t\n\v\f\r
+[0x30, 0x39] => 0~9
+[0x41, 0x5A] => A~Z
+[0x61, 0x7A] => a~z
+*/
+
 #ifndef IS_ALPHA
 #define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
 #endif
 
-#ifndef IS_ALPHANUM
-#define IS_ALPHANUM(c) (IS_NUM(c) || IS_ALPHA(c))
+#ifndef IS_NUM
+#define IS_NUM(c)   ((c) >= '0' && (c) <= '9')
 #endif
 
-#ifndef IS_HEX
-#define IS_HEX(c) (IS_NUM(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
+#ifndef IS_ALPHANUM
+#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
 #endif
 
 #ifndef IS_CNTRL
@@ -191,38 +95,46 @@ typedef void (*procedure_t)(void* userdata);
 #define IS_GRAPH(c) ((c) >= 0x20 && (c) < 0x7F)
 #endif
 
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#ifndef IS_HEX
+#define IS_HEX(c) (IS_NUM(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
 #endif
 
-#ifndef SAFE_FREE
-#define SAFE_FREE(p)    do {if (p) {free(p); (p) = NULL;}} while(0)
+#ifndef IS_LOWER
+#define IS_LOWER(c) (((c) >= 'a' && (c) <= 'z'))
 #endif
 
-#ifndef SAFE_DELETE
-#define SAFE_DELETE(p)  do {if (p) {delete (p); (p) = NULL;}} while(0)
+#ifndef IS_UPPER
+#define IS_UPPER(c) (((c) >= 'A' && (c) <= 'Z'))
 #endif
 
-#ifndef SAFE_DELETE_ARRAY
-#define SAFE_DELETE_ARRAY(p) do {if (p) {delete[] (p); (p) = NULL;}} while(0)
+#ifndef LOWER
+#define LOWER(c)    ((c) | 0x20)
 #endif
 
-#ifndef SAFE_RELEASE
-#define SAFE_RELEASE(p) do {if (p) {(p)->release(); (p) = NULL;}} while(0)
+#ifndef UPPER
+#define UPPER(c)    ((c) & ~0x20)
 #endif
 
-#ifndef MAKE_FOURCC
-#define MAKE_FOURCC(a, b, c, d) \
-( ((uint32)d) | ( ((uint32)c) << 8 ) | ( ((uint32)b) << 16 ) | ( ((uint32)a) << 24 ) )
+// LD, LU, LLD, LLU for explicit conversion of integer
+#ifndef LD
+#define LD(v)   ((long)(v))
 #endif
 
-#ifndef OS_WIN
-typedef unsigned char       BYTE;
-typedef unsigned short      WORD;
+#ifndef LU
+#define LU(v)   ((unsigned long)(v))
+#endif
 
-typedef int                 BOOL;
-typedef void*               HANDLE;
+#ifndef LLD
+#define LLD(v)  ((long long)(v))
+#endif
+
+#ifndef LLU
+#define LLU(v)  ((unsigned long long)(v))
+#endif
+
+#ifndef OS_WIN
 
+// MAKEWORD, HIBYTE, LOBYTE
 #ifndef MAKEWORD
 #define MAKEWORD(h, l)  ( (((WORD)h) << 8) | (l & 0xff) )
 #endif
@@ -235,6 +147,7 @@ typedef void*               HANDLE;
 #define LOBYTE(w) ( (BYTE)(w & 0xff) )
 #endif
 
+// MAKELONG, HIWORD, LOWORD
 #ifndef MAKELONG
 #define MAKELONG(h, l)   ( ((int32_t)h) << 16 | (l & 0xffff) )
 #endif
@@ -246,8 +159,10 @@ typedef void*               HANDLE;
 #ifndef LOWORD
 #define LOWORD(n)        ( (WORD)(n & 0xffff) )
 #endif
-#endif
 
+#endif // OS_WIN
+
+// MAKEINT64, HIINT, LOINT
 #ifndef MAKEINT64
 #define MAKEINT64(h, l)   ( ((int64_t)h) << 32 | (l & 0xffffffff) )
 #endif
@@ -260,14 +175,73 @@ typedef void*               HANDLE;
 #define LOINT(n)        ( (int32_t)(n & 0xffffffff) )
 #endif
 
-#define FLOAT_PRECISION 1e-6
-#define FLOAT_EQUAL_ZERO(f) (ABS(f) < FLOAT_PRECISION)
+#ifndef MAKE_FOURCC
+#define MAKE_FOURCC(a, b, c, d) \
+( ((uint32)d) | ( ((uint32)c) << 8 ) | ( ((uint32)b) << 16 ) | ( ((uint32)a) << 24 ) )
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef LIMIT
+#define LIMIT(lower, v, upper) ((v) < (lower) ? (lower) : (v) > (upper) ? (upper) : (v))
+#endif
+
+#ifndef MAX_PATH
+#define MAX_PATH    260
+#endif
+
+#ifndef NULL
+#define NULL        0
+#endif
+
+#ifndef TRUE
+#define TRUE        1
+#endif
+
+#ifndef FALSE
+#define FALSE       0
+#endif
+
+// @field[OPTIONAL|REQUIRED|REPEATED]
+#ifndef OPTIONAL
+#define OPTIONAL
+#endif
+
+#ifndef REQUIRED
+#define REQUIRED
+#endif
+
+#ifndef REPEATED
+#define REPEATED
+#endif
+
+#ifndef SAFE_FREE
+#define SAFE_FREE(p)    do {if (p) {free(p); (p) = NULL;}} while(0)
+#endif
+
+#ifndef SAFE_DELETE
+#define SAFE_DELETE(p)  do {if (p) {delete (p); (p) = NULL;}} while(0)
+#endif
+
+#ifndef SAFE_DELETE_ARRAY
+#define SAFE_DELETE_ARRAY(p) do {if (p) {delete[] (p); (p) = NULL;}} while(0)
+#endif
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(p) do {if (p) {(p)->release(); (p) = NULL;}} while(0)
+#endif
 
 #define STRINGIFY(x)    STRINGIFY_HELPER(x)
-#define STRINGIFY_HELPER(x)    #x
+#define STRINGIFY_HELPER(x)     #x
 
 #define STRINGCAT(x, y)  STRINGCAT_HELPER(x, y)
-#define STRINGCAT_HELPER(x, y)   x##y
+#define STRINGCAT_HELPER(x, y)  x##y
 
 #ifndef offsetof
 #define offsetof(type, member) \
@@ -292,20 +266,14 @@ typedef void*               HANDLE;
 #endif
 #endif
 
-// __cplusplus
-#ifdef __cplusplus
-
-#include <string>
-#include <map>
-typedef std::map<std::string, std::string> keyval_t;
-
-#ifndef BEGIN_NAMESPACE
-#define BEGIN_NAMESPACE(ns) namespace ns {
+#ifdef PRINT_DEBUG
+#define printd printf
+#else
+#define printd(...)
 #endif
 
-#ifndef END_NAMESPACE
-#define END_NAMESPACE(ns)   } // ns
-#endif
+// __cplusplus
+#ifdef __cplusplus
 
 #ifndef EXTERN_C
 #define EXTERN_C            extern "C"
@@ -319,27 +287,39 @@ typedef std::map<std::string, std::string> keyval_t;
 #define END_EXTERN_C        } // extern "C"
 #endif
 
-#ifndef ENUM
-#define ENUM(e)     enum e
+#ifndef BEGIN_NAMESPACE
+#define BEGIN_NAMESPACE(ns) namespace ns {
 #endif
 
-#ifndef STRUCT
-#define STRUCT(s)   struct s
+#ifndef END_NAMESPACE
+#define END_NAMESPACE(ns)   } // ns
 #endif
 
 #ifndef DEFAULT
 #define DEFAULT(x)  = x
 #endif
 
-#else
+#ifndef ENUM
+#define ENUM(e)     enum e
+#endif
 
-#define BEGIN_NAMESPACE(ns)
-#define END_NAMESPACE(ns)
+#ifndef STRUCT
+#define STRUCT(s)   struct s
+#endif
+
+#else
 
 #define EXTERN_C    extern
 #define BEGIN_EXTERN_C
 #define END_EXTERN_C
 
+#define BEGIN_NAMESPACE(ns)
+#define END_NAMESPACE(ns)
+
+#ifndef DEFAULT
+#define DEFAULT(x)
+#endif
+
 #ifndef ENUM
 #define ENUM(e)\
 typedef enum e e;\
@@ -352,10 +332,6 @@ typedef struct s s;\
 struct s
 #endif
 
-#ifndef DEFAULT
-#define DEFAULT(x)
-#endif
-
 #endif // __cplusplus
 
 #endif // HV_DEF_H_

+ 1 - 1
base/herr.h

@@ -82,7 +82,7 @@
     F(3011, DEVICE_DISABLE,         "device disable")       \
     F(3012, DEVICE_BUSY,            "device busy")          \
 
-// grpc [4000+]
+// grpc [4xxx]
 #define FOREACH_ERR_GRPC(F)     \
     F(4000, GRPC_FIRST,                     "grpc no error")                \
     F(4001, GRPC_STATUS_CANCELLED,          "grpc status: cancelled")       \

+ 4 - 0
base/hlog.c

@@ -140,6 +140,10 @@ void logger_fsync(logger_t* logger) {
     hmutex_unlock(&logger->mutex_);
 }
 
+const char* logger_get_cur_file(logger_t* logger) {
+    return logger->cur_logfile;
+}
+
 static void ts_logfile(const char* filepath, time_t ts, char* buf, int len) {
     struct tm* tm = localtime(&ts);
     snprintf(buf, len, "%s-%04d-%02d-%02d.log",

+ 4 - 0
base/hlog.h

@@ -57,6 +57,8 @@ typedef void (*logger_handler)(int loglevel, const char* buf, int len);
 void stdout_logger(int loglevel, const char* buf, int len);
 void stderr_logger(int loglevel, const char* buf, int len);
 void file_logger(int loglevel, const char* buf, int len);
+// network_logger implement see event/nlog.h
+// void network_logger(int loglevel, const char* buf, int len);
 
 typedef struct logger_s logger_t;
 logger_t* logger_create();
@@ -74,6 +76,7 @@ void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
 void logger_set_remain_days(logger_t* logger, int days);
 void logger_enable_fsync(logger_t* logger, int on);
 void logger_fsync(logger_t* logger);
+const char* logger_get_cur_file(logger_t* logger);
 
 // hlog: default logger instance
 logger_t* default_logger();
@@ -87,6 +90,7 @@ logger_t* default_logger();
 #define hlog_enable_fsync()             logger_enable_fsync(hlog, 1)
 #define hlog_disable_fsync()            logger_enable_fsync(hlog, 0)
 #define hlog_fsync()                    logger_fsync(hlog)
+#define hlog_get_cur_file()             logger_get_cur_file(hlog)
 
 #define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
 #define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO,  fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)

+ 54 - 0
base/hmap.h

@@ -0,0 +1,54 @@
+#ifndef HV_MAP_H_
+#define HV_MAP_H_
+
+#include <map>
+#include <string>
+
+// MultiMap
+namespace std {
+/*
+int main() {
+    std::MultiMap<std::string, std::string> kvs;
+    kvs["name"] = "hw";
+    kvs["filename"] = "1.jpg";
+    kvs["filename"] = "2.jpg";
+    //kvs.insert(std::pair<std::string,std::string>("name", "hw"));
+    //kvs.insert(std::pair<std::string,std::string>("filename", "1.jpg"));
+    //kvs.insert(std::pair<std::string,std::string>("filename", "2.jpg"));
+    for (auto& pair : kvs) {
+        printf("%s:%s\n", pair.first.c_str(), pair.second.c_str());
+    }
+    auto iter = kvs.find("filename");
+    if (iter != kvs.end()) {
+        for (int i = 0; i < kvs.count("filename"); ++i, ++iter) {
+            printf("%s:%s\n", iter->first.c_str(), iter->second.c_str());
+        }
+    }
+    return 0;
+}
+ */
+template<typename Key,typename Value>
+class MultiMap : public multimap<Key, Value> {
+public:
+    Value& operator[](Key key) {
+        auto iter = this->insert(std::pair<Key,Value>(key,Value()));
+        return (*iter).second;
+    }
+};
+}
+
+#ifdef USE_MULTIMAP
+#define HV_MAP      std::MultiMap
+#else
+#define HV_MAP      std::map
+#endif
+
+// KeyValue
+typedef std::map<std::string, std::string>      keyval_t;
+typedef std::MultiMap<std::string, std::string> multi_keyval_t;
+
+namespace hv {
+typedef HV_MAP<std::string, std::string> KeyValue;
+}
+
+#endif // HV_MAP_H_

+ 45 - 47
base/hobj.h

@@ -5,97 +5,95 @@
 #include <map>
 #include <list>
 
-#include "hdef.h"
 #include "hvar.h"
 
+typedef int (*HMethod)(void* userdata);
+
 class HObj {
- public:
+public:
     HObj(HObj* parent = NULL) {
-        _parent = parent;
+        this->parent = parent;
     }
 
     virtual ~HObj() {
         deleteAllChild();
     }
 
-    std::string name() {
-        return _objName;
-    }
-
-    void  setName(char* name) {
-        _objName = name;
-    }
-
-    HObj* parent() {
-        return _parent;
+    void setName(char* name) {
+        this->name = name;
     }
 
-    void  setParent(HObj* ptr) {
-        _parent = ptr;
+    void setParent(HObj* parent) {
+        this->parent = parent;
     }
 
-    void  addChild(HObj* ptr) {
-        _children.push_back(ptr);
+    bool addChild(HObj* child) {
+        children.push_back(child);
+        return true;
     }
 
-    void removeChild(HObj* ptr) {
-        auto iter = _children.begin();
-        while (iter != _children.end()) {
-            if ((*iter) == ptr) {
-                iter = _children.erase(iter);
-            } else {
-                ++iter;
+    bool removeChild(HObj* child) {
+        auto iter = children.begin();
+        while (iter != children.end()) {
+            if (*iter == child) {
+                iter = children.erase(iter);
+                return true;
             }
+            ++iter;
         }
+        return false;
     }
 
     void deleteAllChild() {
-        auto iter = _children.begin();
-        while (iter != _children.end()) {
-            SAFE_DELETE(*iter);
+        auto iter = children.begin();
+        while (iter != children.end()) {
+            if (*iter) {
+                delete (*iter);
+            }
             ++iter;
         }
-        _children.clear();
+        children.clear();
     }
 
-    HObj* findChild(std::string objName) {
-        for (auto iter = _children.begin(); iter != _children.end(); ++iter) {
-            if ((*iter)->name() == objName) {
+    HObj* findChild(std::string name) {
+        for (auto iter = children.begin(); iter != children.end(); ++iter) {
+            if ((*iter)->name == name) {
                 return *iter;
             }
         }
         return NULL;
     }
 
-    HVar  property(std::string key) {
-        auto iter = _properties.find(key);
-        if (iter != _properties.end())
+    HVar property(std::string key) {
+        auto iter = properties.find(key);
+        if (iter != properties.end()) {
             return iter->second;
+        }
         return HVar();
     }
 
-    void  setProperty(std::string key, HVar value) {
-        _properties[key] = value;
+    void setProperty(std::string key, HVar value) {
+        properties[key] = value;
     }
 
-    method_t method(std::string key) {
-        auto iter = _methods.find(key);
-        if (iter != _methods.end())
+    HMethod method(std::string key) {
+        auto iter = methods.find(key);
+        if (iter != methods.end())
             return iter->second;
         return NULL;
     }
 
-    void  setMethod(std::string key, method_t method) {
-        _methods[key] = method;
+    void setMethod(std::string key, HMethod method) {
+        methods[key] = method;
     }
 
- public:
-    std::string _objName;
-    std::map<std::string, HVar> _properties;
-    std::map<std::string, method_t> _methods;
+public:
+    HObj*               parent;
+    std::list<HObj*>    children;
 
-    HObj* _parent;
-    std::list<HObj*> _children;
+    std::string                     name;
+    std::map<std::string, HVar>     properties;
+    std::map<std::string, HMethod>  methods;
 };
 
 #endif // HV_OBJ_H_

+ 62 - 14
base/hplatform.h

@@ -21,7 +21,6 @@
     #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
         #define OS_IOS
     #endif
-    #define OS_APPLE
     #define OS_DARWIN
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     #define OS_FREEBSD
@@ -63,17 +62,17 @@
 // __clang__
 
 #ifdef HV_STATICLIB
-#define HEXPORT
+    #define HV_EXPORT
 #elif defined(OS_WIN)
-#ifdef DLL_EXPORTS
-#define HEXPORT  __declspec(dllexport)
-#else
-#define HEXPORT  __declspec(dllimport)
-#endif
+    #if defined(HV_EXPORTS) || defined(hv_EXPORTS)
+        #define HV_EXPORT  __declspec(dllexport)
+    #else
+        #define HV_EXPORT  __declspec(dllimport)
+    #endif
 #elif defined(__GNUC__)
-#define HEXPORT  __attribute__((visibility("default")))
+    #define HV_EXPORT  __attribute__((visibility("default")))
 #else
-#define HEXPORT
+    #define HV_EXPORT
 #endif
 
 // ARCH
@@ -106,7 +105,7 @@
 #endif
 #endif
 
-// header files
+// headers
 #ifdef OS_WIN
     #ifndef WIN32_LEAN_AND_MEAN
     #define WIN32_LEAN_AND_MEAN
@@ -121,7 +120,9 @@
     #include <direct.h>     // for mkdir,rmdir,chdir,getcwd
     #include <io.h>         // for open,close,read,write,lseek,tell
 
-    #define MKDIR(dir)      mkdir(dir)
+    #define hv_delay(ms)    Sleep(ms)
+    #define hv_mkdir(dir)   mkdir(dir)
+
     #ifndef S_ISREG
     #define S_ISREG(st_mode) (((st_mode) & S_IFMT) == S_IFREG)
     #endif
@@ -141,7 +142,24 @@
     #include <netinet/udp.h>
     #include <netdb.h>  // for gethostbyname
 
-    #define MKDIR(dir)      mkdir(dir, 0777)
+    #define hv_delay(ms)    usleep((ms)*1000)
+    #define hv_mkdir(dir)   mkdir(dir, 0777)
+#endif
+
+#ifdef _MSC_VER
+    typedef int pid_t;
+    typedef int gid_t;
+    typedef int uid_t;
+    #define strcasecmp  stricmp
+    #define strncasecmp strnicmp
+#else
+    typedef int                 BOOL;
+    typedef unsigned char       BYTE;
+    typedef unsigned short      WORD;
+    typedef void*               HANDLE;
+    #include <strings.h>
+    #define stricmp     strcasecmp
+    #define strnicmp    strncasecmp
 #endif
 
 // ANSI C
@@ -154,13 +172,26 @@
 #include <ctype.h>
 #include <float.h>
 #include <limits.h>
+#include <errno.h>
 #include <time.h>
 #include <math.h>
-#include <errno.h>
-#include <signal.h>
 
+#ifndef __cplusplus
 #if HAVE_STDBOOL_H
 #include <stdbool.h>
+#else
+    #ifndef bool
+    #define bool char
+    #endif
+
+    #ifndef true
+    #define ture 1
+    #endif
+
+    #ifndef false
+    #define false 0
+    #endif
+#endif
 #endif
 
 #if HAVE_STDINT_H
@@ -176,6 +207,23 @@ typedef unsigned __int32    uint32_t;
 typedef unsigned __int64    uint64_t;
 #endif
 
+typedef float               float32_t;
+typedef double              float64_t;
+
+// sizeof(var) = 8
+typedef union {
+    bool        b;
+    char        ch;
+    char*       str;
+    long long   num;
+    float       f;
+    double      lf;
+    void*       ptr;
+} var;
+
+typedef int (*method_t)(void* userdata);
+typedef void (*procedure_t)(void* userdata);
+
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif

+ 2 - 2
base/hstring.cpp

@@ -52,7 +52,7 @@ StringList split(const string& str, char delim) {
     return res;
 }
 
-KeyValue splitKV(const string& str, char kv_kv, char k_v) {
+hv::KeyValue splitKV(const string& str, char kv_kv, char k_v) {
     enum {
         s_key,
         s_value,
@@ -62,7 +62,7 @@ KeyValue splitKV(const string& str, char kv_kv, char k_v) {
     const char* value = NULL;
     int key_len = 0;
     int value_len = 0;
-    KeyValue kvs;
+    hv::KeyValue kvs;
     while (*p != '\0') {
         if (*p == kv_kv) {
             if (key_len && value_len) {

+ 3 - 45
base/hstring.h

@@ -3,61 +3,19 @@
 
 #include <string>
 #include <vector>
-#include <map>
 #include <sstream>
 
 #include "hbase.h"
+#include "hmap.h"
 
 using std::string;
 typedef std::vector<string> StringList;
 
-// MultiMap
-namespace std {
-/*
-int main() {
-    std::MultiMap<std::string, std::string> kvs;
-    kvs["name"] = "hw";
-    kvs["filename"] = "1.jpg";
-    kvs["filename"] = "2.jpg";
-    //kvs.insert(std::pair<std::string,std::string>("name", "hw"));
-    //kvs.insert(std::pair<std::string,std::string>("filename", "1.jpg"));
-    //kvs.insert(std::pair<std::string,std::string>("filename", "2.jpg"));
-    for (auto& pair : kvs) {
-        printf("%s:%s\n", pair.first.c_str(), pair.second.c_str());
-    }
-    auto iter = kvs.find("filename");
-    if (iter != kvs.end()) {
-        for (int i = 0; i < kvs.count("filename"); ++i, ++iter) {
-            printf("%s:%s\n", iter->first.c_str(), iter->second.c_str());
-        }
-    }
-    return 0;
-}
- */
-template<typename Key,typename Value>
-class MultiMap : public multimap<Key, Value> {
-public:
-    Value& operator[](Key key) {
-        auto iter = this->insert(std::pair<Key,Value>(key,Value()));
-        return (*iter).second;
-    }
-};
-}
-
-#ifdef USE_MULTIMAP
-#define HV_MAP      std::MultiMap
-#else
-#define HV_MAP      std::map
-#endif
-
-// KeyValue
-typedef HV_MAP<std::string, std::string> KeyValue;
-
 // std::map<std::string, std::string, StringCaseLess>
 class StringCaseLess : public std::less<std::string> {
 public:
     bool operator()(const std::string& lhs, const std::string& rhs) const {
-        return stricmp(lhs.c_str(), rhs.c_str()) < 0;
+        return strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
     }
 };
 
@@ -86,7 +44,7 @@ string asprintf(const char* fmt, ...);
 // x,y,z
 StringList split(const string& str, char delim = ',');
 // user=amdin&pswd=123456
-KeyValue   splitKV(const string& str, char kv_kv = '&', char k_v = '=');
+hv::KeyValue splitKV(const string& str, char kv_kv = '&', char k_v = '=');
 string trim(const string& str, const char* chars = SPACE_CHARS);
 string trimL(const string& str, const char* chars = SPACE_CHARS);
 string trimR(const string& str, const char* chars = SPACE_CHARS);

+ 2 - 2
base/hsysinfo.h

@@ -21,8 +21,8 @@ static inline int get_ncpu() {
 }
 
 typedef struct meminfo_s {
-    unsigned long total; // KB
-    unsigned long free; // KB
+    unsigned long total;    // KB
+    unsigned long free;     // KB
 } meminfo_t;
 
 static inline int get_meminfo(meminfo_t* mem) {

+ 57 - 41
base/hthread.h

@@ -16,15 +16,30 @@
 #define hv_gettid   (long)gettid
 #elif defined(OS_LINUX)
 #include <sys/syscall.h>
-static inline long hv_gettid() {
-    return syscall(SYS_gettid);
-}
+#define hv_gettid   (long)syscall(SYS_gettid)
 #elif HAVE_PTHREAD_H
 #define hv_gettid   (long)pthread_self
 #else
 #define hv_gettid   hv_getpid
 #endif
 
+/*
+#include "hthread.h"
+
+HTHREAD_ROUTINE(thread_demo) {
+    printf("thread[%ld] start\n", hv_gettid());
+    hv_delay(3000);
+    printf("thread[%ld] end\n", hv_gettid());
+    return 0;
+}
+
+int main() {
+    hthread_t th = hthread_create(thread_demo, NULL);
+    hthread_join(th);
+    return 0;
+}
+ */
+
 #ifdef OS_WIN
 typedef HANDLE      hthread_t;
 typedef DWORD (WINAPI *hthread_routine)(void*);
@@ -68,19 +83,43 @@ static inline int hthread_join(hthread_t th) {
 #include <chrono>
 
 class HThread {
- public:
+public:
+    enum Status {
+        STOP,
+        RUNNING,
+        PAUSE,
+    };
+
+    enum SleepPolicy {
+        YIELD,
+        SLEEP_FOR,
+        SLEEP_UNTIL,
+        NO_SLEEP,
+    };
+
     HThread() {
         status = STOP;
-        status_switch = false;
+        status_changed = false;
         sleep_policy = YIELD;
         sleep_ms = 0;
     }
 
     virtual ~HThread() {}
 
+    void setStatus(Status stat) {
+        status_changed = true;
+        status = stat;
+    }
+
+    void setSleepPolicy(SleepPolicy policy, uint32_t ms = 0) {
+        sleep_policy = policy;
+        sleep_ms = ms;
+        setStatus(status);
+    }
+
     virtual int start() {
         if (status == STOP) {
-            switchStatus(RUNNING);
+            setStatus(RUNNING);
             dotask_cnt = 0;
 
             thread = std::thread([this] {
@@ -94,7 +133,7 @@ class HThread {
 
     virtual int stop() {
         if (status != STOP) {
-            switchStatus(STOP);
+            setStatus(STOP);
             thread.join();  // wait thread exit
         }
         return 0;
@@ -102,14 +141,14 @@ class HThread {
 
     virtual int pause() {
         if (status == RUNNING) {
-            switchStatus(PAUSE);
+            setStatus(PAUSE);
         }
         return 0;
     }
 
     virtual int resume() {
         if (status == PAUSE) {
-            switchStatus(RUNNING);
+            setStatus(RUNNING);
         }
         return 0;
     }
@@ -121,9 +160,9 @@ class HThread {
             }
 
             doTask();
-            dotask_cnt++;
+            ++dotask_cnt;
 
-            sleep();
+            HThread::sleep();
         }
     }
 
@@ -132,33 +171,9 @@ class HThread {
     virtual bool doFinish() {return true;}
 
     std::thread thread;
-    enum Status {
-        STOP,
-        RUNNING,
-        PAUSE,
-    };
     std::atomic<Status> status;
     uint32_t dotask_cnt;
-
-    enum SleepPolicy {
-        YIELD,
-        SLEEP_FOR,
-        SLEEP_UNTIL,
-        NO_SLEEP,
-    };
-
-    void setSleepPolicy(SleepPolicy policy, uint32_t ms = 0) {
-        status_switch = true;
-        sleep_policy = policy;
-        sleep_ms = ms;
-    }
-
- protected:
-    void switchStatus(Status stat) {
-        status_switch = true;
-        status = stat;
-    }
-
+protected:
     void sleep() {
         switch (sleep_policy) {
         case YIELD:
@@ -168,8 +183,8 @@ class HThread {
             std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
             break;
         case SLEEP_UNTIL: {
-            if (status_switch) {
-                status_switch = false;
+            if (status_changed) {
+                status_changed = false;
                 base_tp = std::chrono::system_clock::now();
             }
             base_tp += std::chrono::milliseconds(sleep_ms);
@@ -181,10 +196,11 @@ class HThread {
         }
     }
 
-    std::atomic<bool> status_switch;
     SleepPolicy sleep_policy;
-    std::chrono::system_clock::time_point base_tp;   // for SLEEP_UNTIL
-    uint32_t sleep_ms;
+    uint32_t    sleep_ms;
+    // for SLEEP_UNTIL
+    std::atomic<bool> status_changed;
+    std::chrono::system_clock::time_point base_tp;
 };
 #endif
 

+ 68 - 82
base/htime.c

@@ -1,15 +1,5 @@
 #include "htime.h"
 
-#include <string.h>
-#ifdef _MSC_VER
-    #define strcasecmp stricmp
-    #define strncasecmp strnicmp
-#else
-    #include <strings.h>
-    #define stricmp     strcasecmp
-    #define strnicmp    strncasecmp
-#endif
-
 static const char* s_weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
 
 static const char* s_months[] = {"January", "February", "March", "April", "May", "June",
@@ -19,14 +9,6 @@ static const uint8_t s_days[] = \
 //   1       3       5       7   8       10      12
     {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-void msleep(unsigned int ms) {
-#ifdef OS_WIN
-    Sleep(ms);
-#else
-    usleep(ms*1000);
-#endif
-}
-
 unsigned int gettick() {
 #ifdef OS_WIN
     return GetTickCount();
@@ -100,6 +82,10 @@ datetime_t datetime_now() {
 
 time_t datetime_mktime(datetime_t* dt) {
     struct tm tm;
+    time_t ts;
+    time(&ts);
+    struct tm* ptm = localtime(&ts);
+    memcpy(&tm, ptm, sizeof(struct tm));
     tm.tm_yday  = dt->year   - 1900;
     tm.tm_mon   = dt->month  - 1;
     tm.tm_mday  = dt->day;
@@ -109,33 +95,6 @@ time_t datetime_mktime(datetime_t* dt) {
     return mktime(&tm);
 }
 
-char* duration_fmt(int sec, char* buf) {
-    int h, m, s;
-    m = sec / 60;
-    s = sec % 60;
-    h = m / 60;
-    m = m % 60;
-    sprintf(buf, TIME_FMT, h, m, s);
-    return buf;
-}
-
-char* datetime_fmt(datetime_t* dt, char* buf) {
-    sprintf(buf, DATETIME_FMT,
-        dt->year, dt->month, dt->day,
-        dt->hour, dt->min, dt->sec, dt->ms);
-    return buf;
-}
-
-char* gmtime_fmt(time_t time, char* buf) {
-    struct tm* tm = gmtime(&time);
-    //strftime(buf, GMTIME_FMT_BUFLEN, "%a, %d %b %Y %H:%M:%S GMT", tm);
-    sprintf(buf, GMTIME_FMT,
-        s_weekdays[tm->tm_wday],
-        tm->tm_mday, s_months[tm->tm_mon], tm->tm_year + 1900,
-        tm->tm_hour, tm->tm_min, tm->tm_sec);
-    return buf;
-}
-
 int days_of_month(int month, int year) {
     if (month < 1 || month > 12) {
         return 0;
@@ -182,7 +141,70 @@ datetime_t* datetime_future(datetime_t* dt, int days) {
     return dt;
 }
 
-time_t calc_next_timeout(int minute, int hour, int day, int week, int month) {
+char* duration_fmt(int sec, char* buf) {
+    int h, m, s;
+    m = sec / 60;
+    s = sec % 60;
+    h = m / 60;
+    m = m % 60;
+    sprintf(buf, TIME_FMT, h, m, s);
+    return buf;
+}
+
+char* datetime_fmt(datetime_t* dt, char* buf) {
+    sprintf(buf, DATETIME_FMT,
+        dt->year, dt->month, dt->day,
+        dt->hour, dt->min, dt->sec, dt->ms);
+    return buf;
+}
+
+char* gmtime_fmt(time_t time, char* buf) {
+    struct tm* tm = gmtime(&time);
+    //strftime(buf, GMTIME_FMT_BUFLEN, "%a, %d %b %Y %H:%M:%S GMT", tm);
+    sprintf(buf, GMTIME_FMT,
+        s_weekdays[tm->tm_wday],
+        tm->tm_mday, s_months[tm->tm_mon], tm->tm_year + 1900,
+        tm->tm_hour, tm->tm_min, tm->tm_sec);
+    return buf;
+}
+
+int month_atoi(const char* month) {
+    for (size_t i = 0; i < 12; ++i) {
+        if (strnicmp(month, s_months[i], strlen(month)) == 0)
+            return i+1;
+    }
+    return 0;
+}
+
+const char* month_itoa(int month) {
+    assert(month >= 1 && month <= 12);
+    return s_months[month-1];
+}
+
+int weekday_atoi(const char* weekday) {
+    for (size_t i = 0; i < 7; ++i) {
+        if (strnicmp(weekday, s_weekdays[i], strlen(weekday)) == 0)
+            return i;
+    }
+    return 0;
+}
+
+const char* weekday_itoa(int weekday) {
+    assert(weekday >= 0 && weekday <= 7);
+    if (weekday == 7) weekday = 0;
+    return s_weekdays[weekday];
+}
+
+datetime_t hv_compile_datetime() {
+    datetime_t dt;
+    char month[32];
+    sscanf(__DATE__, "%s %d %d", month, &dt.day, &dt.year);
+    sscanf(__TIME__, "%d %d %d", &dt.hour, &dt.min, &dt.sec);
+    dt.month = month_atoi(month);
+    return dt;
+}
+
+time_t cron_next_timeout(int minute, int hour, int day, int week, int month) {
     enum {
         UNKOWN,
         HOURLY,
@@ -255,39 +277,3 @@ time_t calc_next_timeout(int minute, int hour, int day, int week, int month) {
 
     return mktime(&tm);
 }
-
-int month_atoi(const char* month) {
-    for (size_t i = 0; i < 12; ++i) {
-        if (strnicmp(month, s_months[i], strlen(month)) == 0)
-            return i+1;
-    }
-    return 0;
-}
-
-const char* month_itoa(int month) {
-    assert(month >= 1 && month <= 12);
-    return s_months[month-1];
-}
-
-int weekday_atoi(const char* weekday) {
-    for (size_t i = 0; i < 7; ++i) {
-        if (strnicmp(weekday, s_weekdays[i], strlen(weekday)) == 0)
-            return i;
-    }
-    return 0;
-}
-
-const char* weekday_itoa(int weekday) {
-    assert(weekday >= 0 && weekday <= 7);
-    if (weekday == 7) weekday = 0;
-    return s_weekdays[weekday];
-}
-
-datetime_t hv_compile_datetime() {
-    static datetime_t dt;
-    char month[32];
-    sscanf(__DATE__, "%s %d %d", month, &dt.day, &dt.year);
-    sscanf(__TIME__, "%d %d %d", &dt.hour, &dt.min, &dt.sec);
-    dt.month = month_atoi(month);
-    return dt;
-}

+ 37 - 30
base/htime.h

@@ -10,8 +10,7 @@ BEGIN_EXTERN_C
 #define SECONDS_PER_DAY     86400   // 24*3600
 #define SECONDS_PER_WEEK    604800  // 7*24*3600
 
-#define IS_LEAP_YEAR(year) (((year)%4 == 0 && (year)%100 != 0) ||\
-                            (year)%100 == 0)
+#define IS_LEAP_YEAR(year) (((year)%4 == 0 && (year)%100 != 0) || (year)%100 == 0)
 
 typedef struct datetime_s {
     int year;
@@ -23,15 +22,6 @@ typedef struct datetime_s {
     int ms;
 } datetime_t;
 
-#ifdef OS_WIN
-static inline void sleep(unsigned int s) {
-    Sleep(s*1000);
-}
-
-static inline void usleep(unsigned int us) {
-    Sleep(us/1000);
-}
-
 #ifdef _MSC_VER
 /* @see winsock2.h
 // Structure used in select() call, taken from the BSD file sys/time.h
@@ -61,24 +51,44 @@ static inline int gettimeofday(struct timeval *tv, struct timezone *tz) {
     return 0;
 }
 #endif
+
+// sleep(s), msleep(ms), usleep(us)
+#ifdef OS_WIN
+static inline void sleep(unsigned int s) {
+    Sleep(s * 1000);
+}
+
+static inline void msleep(unsigned int ms) {
+    Sleep(ms);
+}
+
+static inline void usleep(unsigned int us) {
+    Sleep(us / 1000);
+}
+#else
+static inline void msleep(unsigned int ms) {
+    usleep(ms * 1000);
+}
 #endif
 
-static inline unsigned long long timestamp_ms() {
+// ms
+unsigned int gettick();
+
+static inline unsigned long long gettimeofday_ms() {
     struct timeval tv;
     gettimeofday(&tv, NULL);
     return tv.tv_sec * (unsigned long long)1000 + tv.tv_usec/1000;
 }
 
-void msleep(unsigned int ms);
-// ms
-unsigned int gettick();
-
 // us
 unsigned long long gethrtime_us();
 
 datetime_t datetime_now();
 time_t     datetime_mktime(datetime_t* dt);
 
+datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1));
+datetime_t* datetime_future(datetime_t* dt, int days DEFAULT(1));
+
 #define TIME_FMT            "%02d:%02d:%02d"
 #define TIME_FMT_BUFLEN     12
 char* duration_fmt(int sec, char* buf);
@@ -91,20 +101,6 @@ char* datetime_fmt(datetime_t* dt, char* buf);
 #define GMTIME_FMT_BUFLEN   30
 char* gmtime_fmt(time_t time, char* buf);
 
-datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1));
-datetime_t* datetime_future(datetime_t* dt, int days DEFAULT(1));
-
-/*
- * minute   hour    day     week    month       action
- * 0~59     0~23    1~31    0~6     1~12
- *  30      -1      -1      -1      -1          cron.hourly
- *  30      1       -1      -1      -1          cron.daily
- *  30      1       15      -1      -1          cron.monthly
- *  30      1       -1       7      -1          cron.weekly
- *  30      1        1      -1      10          cron.yearly
- */
-time_t calc_next_timeout(int minute, int hour, int day, int week, int month);
-
 int days_of_month(int month, int year);
 
 int month_atoi(const char* month);
@@ -115,6 +111,17 @@ const char* weekday_itoa(int weekday);
 
 datetime_t hv_compile_datetime();
 
+/*
+ * minute   hour    day     week    month       action
+ * 0~59     0~23    1~31    0~6     1~12
+ *  30      -1      -1      -1      -1          cron.hourly
+ *  30      1       -1      -1      -1          cron.daily
+ *  30      1       15      -1      -1          cron.monthly
+ *  30      1       -1       0      -1          cron.weekly
+ *  30      1        1      -1      10          cron.yearly
+ */
+time_t cron_next_timeout(int minute, int hour, int day, int week, int month);
+
 END_EXTERN_C
 
 #endif // HV_TIME_H_

+ 12 - 13
base/hvar.h

@@ -1,14 +1,13 @@
 #ifndef HV_VAR_H_
 #define HV_VAR_H_
 
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "hdef.h"
-
 class HVar {
- public:
-    enum TYPE {
+public:
+    enum Type {
         UNKNOWN,
         BOOLEAN,
         INTEGER,
@@ -17,18 +16,18 @@ class HVar {
         POINTER
     } type;
 
-    union DATA {
-        bool b;
-        int64_t i;
-        float64 f;
-        char* str;
-        void* ptr;
+    union Data {
+        bool        b;
+        int64_t     i;
+        double      f;
+        char*       str;
+        void*       ptr;
     } data;
 
     HVar()          {memset(&data, 0, sizeof(data)); type = UNKNOWN;}
     HVar(bool b)    {data.b = b; type = BOOLEAN;}
-    HVar(int64_t i)   {data.i = i; type = INTEGER;}
-    HVar(float64 f) {data.f = f; type = FLOAT;}
+    HVar(int64_t i) {data.i = i; type = INTEGER;}
+    HVar(double f)  {data.f = f; type = FLOAT;}
     HVar(char* str) {
         data.str = (char*)malloc(strlen(str)+1);
         strcpy(data.str, str);
@@ -48,7 +47,7 @@ class HVar {
 
     bool    toBool()    {return data.b;}
     int64_t toInt()     {return data.i;}
-    float64 toFloat()   {return data.f;}
+    double  toFloat()   {return data.f;}
     char*   toString()  {return data.str;}
     void*   toPointer() {return data.ptr;}
 };

+ 1 - 1
base/hversion.h

@@ -7,7 +7,7 @@ BEGIN_EXTERN_C
 
 #define HV_VERSION_MAJOR    1
 #define HV_VERSION_MINOR    20
-#define HV_VERSION_PATCH    3
+#define HV_VERSION_PATCH    7
 
 #define HV_VERSION_STRING   STRINGIFY(HV_VERSION_MAJOR) "." \
                             STRINGIFY(HV_VERSION_MINOR) "." \

+ 3 - 0
base/list.h

@@ -27,7 +27,10 @@ struct hlist_node {
 };
 
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
+// TODO: <sys/queue.h> defined LIST_HEAD
+#ifndef LIST_HEAD
 #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
+#endif
 #define INIT_LIST_HEAD  list_init
 static inline void list_init(struct list_head *list)
 {

+ 2 - 1
configure

@@ -95,6 +95,7 @@ TARGET_ARCH=`echo $TARGET_PLATFORM | awk -F'-' '{print $1}'`
 case $TARGET_PLATFORM in
     *mingw*) TARGET_OS=Windows ;;
     *android*) TARGET_OS=Android ;;
+    *darwin*) TARGET_OS=Darwin ;;
     *) TARGET_OS=Linux ;;
 esac
 
@@ -109,8 +110,8 @@ echo "TARGET_ARCH     = $TARGET_ARCH"
 # Checks for libraries
 
 # Checks for header files
-header=stdint.h && check_header
 header=stdbool.h && check_header
+header=stdint.h && check_header
 header=sys/types.h && check_header
 header=sys/stat.h && check_header
 header=sys/time.h && check_header

+ 295 - 290
docs/apis.md

@@ -1,17 +1,84 @@
-#  c
-## functions
-### hversion.h
-- hv_version
-- hv_compile_version
-- version_atoi
-- version_itoa
+# libhv API Manual
+
+## base
+
+### hplatform.h
+- OS: OS_WIN, OS_UNIX (OS_LINUX, OS_ANDROID, OS_DARWIN ...)
+- ARCH: ARCH_X86, ARCH_X64, ARCH_ARM, ARCH_ARM64
+- BYTE_ORDER: BIG_ENDIAN, LITTLE_ENDIAN
+- HV_EXPORT
+- stdbool.h: bool, true, false
+- stdint.h: int8_t, int16_t, int32_t, int64_t
+- var
+- hv_delay
+- hv_mkdir
+- stricmp, strcasecmp
+
+### hdef.h
+- ABS, NABS
+- ARRAY_SIZE
+- BEGIN_EXTERN_C, END_EXTERN_C
+- BEGIN_NAMESPACE, END_NAMESPACE
+- BITSET, BITCLR, BITGET
+- CR, LF, CRLF
+- DEFAULT
+- ENUM, STRUCT
+- FLOAT_EQUAL_ZERO
+- IN, OUT, INOUT
+- INFINITE
+- IS_ALPHA, IS_NUM, IS_NUM
+- IS_CNTRL, IS_GRAPH
+- IS_HEX
+- IS_LOWER, IS_UPPER
+- LOWER, UPPER
+- LD, LU, LLD, LLU
+- MAKEWORD, LOBYTE, HIBYTE
+- MAKELONG, LOWORD, HIWORD
+- MAKEINT64, LOINT, HIINT
+- MAKE_FOURCC
+- MAX, MIN, LIMIT
+- MAX_PATH
+- NULL, TRUE, FALSE
+- OPTIONAL, REQUIRED, REPEATED
+- SAFE_FREE, SAFE_DELETE, SAFE_DELETE_ARRAY, SAFE_RELEASE
+- STRINGCAT
+- STRINGIFY
+- offsetof, offsetofend
+- container_of
+- prefetch
+- printd
+
+### herr.h
+- hv_strerror
+
+### htime.h
+- IS_LEAP_YEAR
+- datetime_t
+- sleep, msleep, usleep
+- gettick
+- gettimeofday
+- gettimeofday_ms
+- gethrtime_us
+- datetime_now
+- datetime_mktime
+- datetime_past
+- datetime_future
+- duration_fmt
+- datetime_fmt
+- gmtime_fmt
+- days_of_month
+- month_atoi
+- month_itoa
+- weekday_atoi
+- weekday_itoa
+- hv_compile_datetime
+- cron_next_timeout
 
 ### hmath.h
 - floor2e
 - ceil2e
 
 ### hbase.h
-- getboolean
 - safe_malloc
 - safe_calloc
 - safe_realloc
@@ -24,49 +91,90 @@
 - strstartswith
 - strendswith
 - strcontains
+- strlcpy
+- strlcat
+- strrchr_dot
+- strrchr_dir
+- hv_basename
+- hv_suffixname
+- hv_mkdir_p
+- hv_rmdir_p
+- getboolean
+- get_executable_path
+- get_executable_dir
+- get_executable_file
+- get_run_dir
 
-### htime.h
-- calc_next_timeout
-- datetime_now
-- datetime_past
-- datetime_future
-- datetime_mktime
-- datetime_fmt
-- gmtime_fmt
-- gettick
-- gethrtime_us
-- sleep
-- msleep
-- usleep
-- hv_compile_datetime
-- days_of_month
-- month_atoi
-- month_itoa
-- weekday_atoi
-- weekday_itoa
+### hversion.h
+- hv_version
+- hv_compile_version
+- version_atoi
+- version_itoa
 
-### hlog.h
-- default_logger
-- file_logger
-- stderr_logger
-- stdout_logger
-- logger_create
-- logger_destroy
-- logger_enable_color
-- logger_enable_fsync
-- logger_fsync
-- logger_print
-- logger_set_file
-- logger_set_handler
-- logger_set_level
-- logger_set_max_bufsize
-- logger_set_max_filesize
-- logger_set_remain_days
+### hsysinfo.h
+- get_ncpu
+- get_meminfo
 
-### herr.h
-- hv_strerror
+### hproc.h
+- hproc_spawn
+
+### hthread.h
+- hv_getpid
+- hv_gettid
+- HTHREAD_RETTYPE
+- HTHREAD_ROUTINE
+- hthread_create
+- hthread_join
+- class HThread
+
+### hmutex.h
+- hmutex_t
+- hmutex_init
+- hmutex_destroy
+- hmutex_lock
+- hmutex_unlock
+- hspinlock_t
+- hspinlock_init
+- hspinlock_destroy
+- hspinlock_lock
+- hspinlock_unlock
+- hrwlock_t
+- hrwlock_init
+- hrwlock_destroy
+- hrwlock_rdlock
+- hrwlock_rdunlock
+- hrwlock_wrlock
+- hrwlock_wrunlock
+- htimed_mutex_t
+- htimed_mutex_init
+- htimed_mutex_destroy
+- htimed_mutex_lock
+- htimed_mutex_lock_for
+- htimed_mutex_unlock
+- hcondvar_t
+- hcondvar_init
+- hcondvar_destroy
+- hcondvar_wait
+- hcondvar_wait_for
+- hcondvar_signal
+- hcondvar_broadcast
+- hsem_init
+- hsem_destroy
+- hsem_wait
+- hsem_post
+- hsem_timedwait
+- honce_t
+- HONCE_INIT
+- honce
+- `hv::MutexLock`
+- `hv::SpinLock`
+- `hv::RWLock`
 
 ### hsocket.h
+- INVALID_SOCKET
+- closesocket
+- blocking
+- nonblocking
 - Bind
 - Listen
 - Connect
@@ -74,14 +182,20 @@
 - ConnectTimeout
 - Resolver
 - Socketpair
+- socket_errno
 - socket_strerror
-- sockaddrlen
-- sockaddr_assign
+- sockaddr_u
 - sockaddr_ip
 - sockaddr_port
+- sockaddr_set_ip
 - sockaddr_set_port
+- sockaddr_set_ipport
+- sockaddr_len
 - sockaddr_str
 - sockaddr_print
+- SOCKADDR_LEN
+- SOCKADDR_STR
+- SOCKADDR_PRINT
 - tcp_nodelay
 - tcp_nopush
 - tcp_keepalive
@@ -89,13 +203,110 @@
 - so_sndtimeo
 - so_rcvtimeo
 
-### hproc.h
-- hproc_spawn
+### hlog.h
+- default_logger
+- file_logger
+- stderr_logger
+- stdout_logger
+- logger_create
+- logger_destroy
+- logger_enable_color
+- logger_enable_fsync
+- logger_fsync
+- logger_print
+- logger_set_file
+- logger_set_handler
+- logger_set_level
+- logger_set_max_bufsize
+- logger_set_max_filesize
+- logger_set_remain_days
+- logger_get_cur_file
+- hlogd, hlogi, hlogw, hloge, hlogf
+- LOGD, LOGI, LOGW, LOGE, LOGF
 
-### hthread.h
-- gettid
-- hthread_create
-- hthread_join
+### hbuf.h
+- hbuf_t
+- offset_buf_t
+- HBuf
+- HVLBuf
+- HRingBuf
+
+### hgui.h
+- HPoint
+- HSize
+- HRect
+
+### hstring.h
+- asprintf
+- trim
+- trimL
+- trimR
+- trim_pairs
+- split
+- splitKV
+- replace
+- basename
+- dirname
+- filename
+- suffixname
+- hv::to_string
+- hv::from_string
+
+### hfile.h
+- class HFile
+
+### hdir.h
+- listdir
+
+### hurl.h
+- url_escape
+- url_unescape
+
+### hscope.h
+- defer
+- ScopeCleanup
+- ScopeFree
+- ScopeDelete
+- ScopeDeleteArray
+- ScopeRelease
+- ScopeLock
+
+### ifconfig.h
+- ifconfig
+
+## utils
+### md5.h
+- MD5Init
+- MD5Update
+- MD5Final
+
+### base64.h
+- base64_decode
+- base64_encode
+
+### json.hpp
+
+### hmain.h
+- main_ctx_init
+- parse_opt
+- parse_opt_long
+- get_arg
+- get_env
+- setproctitle
+- signal_init
+- signal_handle
+- signal_handler
+- create_pidfile
+- delete_pidfile
+- getpid_form_pidfile
+- master_workers_run
+
+### singleton.h
+- DISABLE_COPY
+- SINGLETON_DECL
+- SINGLETON_IMPL
+
+## event
 
 ### hloop.h
 - create_tcp_client
@@ -115,6 +326,13 @@
 - hloop_set_userdata
 - hloop_userdata
 - hloop_post_event
+- hevent_loop
+- hevent_type
+- hevent_id
+- hevent_priority
+- hevent_userdata
+- hevent_set_priority
+- hevent_ser_userdata
 - haccept
 - hconnect
 - hread
@@ -157,6 +375,13 @@
 - network_logger
 - nlog_listen
 
+### nmap.h
+- nmap_discover
+- segment_discover
+- host_discover
+
+## protocol
+
 ### dns.h
 - dns_name_decode
 - dns_name_encode
@@ -188,6 +413,13 @@
 ### icmp.h
 - ping
 
+## http
+- HttpMessage
+- HttpRequest
+- HttpResponse
+- HttpParser
+- HttpService
+
 ### httpdef.h
 - http_content_type_enum
 - http_content_type_enum_by_suffix
@@ -201,58 +433,13 @@
 - http_status_enum
 - http_status_str
 
-### md5.h
-- MD5Init
-- MD5Update
-- MD5Final
-
-### base64.h
-- base64_decode
-- base64_encode
-
-### ssl_ctx.h
-- ssl_ctx_init
-- ssl_ctx_destory
-
-# cpp
-## functions
-### hmain.h
-- main_ctx_init
-- parse_opt
-- parse_opt_long
-- get_arg
-- get_env
-- setproctitle
-- signal_init
-- signal_handler
-- handle_signal
-- create_pidfile
-- delete_pidfile
-- getpid_form_pidfile
-- master_workers_run
-
-### hstring.h
-- asprintf
-- trim
-- trimL
-- trimR
-- trim_pairs
-- split
-- splitKV
-- replace
-- basename
-- dirname
-- filename
-- suffixname
-- hv::to_string
-- hv::from_string
-
-### hdir.h
-- listdir
-
-### hurl.h
-- url_escape
-- url_unescape
+### http_content.h
+- parse_query_params
+- parse_json
+- parse_multipart
+- dump_query_params
+- dump_json
+- dump_multipart
 
 ### http_client.h
 - http_client_new
@@ -269,191 +456,9 @@
 - http_server_run
 - http_server_stop
 
-### http_content.h
-- parse_query_params
-- parse_json
-- parse_multipart
-- dump_query_params
-- dump_json
-- dump_multipart
-
-### hsysinfo.h
-- get_ncpu
-- get_meminfo
-
-### ifconfig.h
-- ifconfig
-
-### nmap.h
-- nmap_discovery
-- segment_discovery
-- host_discovery
-
-## classes
-### hscope.h
-- ScopeCleanup
-- ScopeFree
-- ScopeDelete
-- ScopeDeleteArray
-- ScopeRelease
-- ScopeLock
-
-### http
-- HttpMessage
-- HttpRequest
-- HttpResponse
-- HttpService
-
-### misc
-- IniParser
-- HObject
+## other
 - HVar
-- HFile
+- HObject
 - HThread
 - HThreadPool
 - HObjectPool
-- HBuf
-- HVLBuf
-- HRingBuf
-- HPoint
-- HSize
-- HRect
-- `hv::MutexLock`
-- `hv::SpinLock`
-- `hv::RWLock`
-
-# marcos
-### hdef.h
-- ABS
-- ARRAY_SIZE
-- BITSET
-- BITCLR
-- BITGET
-- CR
-- LF
-- CRLF
-- LOWER
-- UPPER
-- IS_NUM
-- IS_UPPER
-- IS_LOWER
-- IS_ALPHA
-- IS_ALPHANUM
-- IS_HEX
-- IS_GRAPH
-- MAX
-- MIN
-- LIMIT
-- MAKE_FOURCC
-- MAKEWORD
-- HIBYTE
-- LOBYTE
-- MAKELONG
-- HIWORD
-- LOWORD
-- MAKEINT64
-- HIINT
-- LOINT
-- SAFE_ALLOC
-- SAFE_FREE
-- SAFE_DELETE
-- SAFE_DELETE_ARRAY
-- SAFE_RELEASE
-- STRINGIFY
-- STRINGCAT
-- FLOAT_EQUAL_ZERO
-- offsetof
-- offsetoffend
-- container_of
-- prefetch
-- printd
-- NULL
-- TRUE
-- FALSE
-- INFINITE
-- BEGIN_NAMESPACE
-- END_NAMESPACE
-- EXTERN_C
-- BEGIN_EXTERN_C
-- END_EXTERN_C
-- ENUM
-- STRUCT
-- DEFAULT
-
-### hlog.h
-- hlogd
-- hlogi
-- hlogw
-- hloge
-- hlogf
-- LOGD
-- LOGI
-- LOGW
-- LOGE
-- LOGF
-
-### hmutex.h
-- hmutex_t
-- hmutex_init
-- hmutex_destroy
-- hmutex_lock
-- hmutex_unlock
-- hspinlock_t
-- hspinlock_init
-- hspinlock_destroy
-- hspinlock_lock
-- hspinlock_unlock
-- hrwlock_t
-- hrwlock_init
-- hrwlock_destroy
-- hrwlock_rdlock
-- hrwlock_rdunlock
-- hrwlock_wrlock
-- hrwlock_wrunlock
-- htimed_mutex_t
-- htimed_mutex_init
-- htimed_mutex_destroy
-- htimed_mutex_lock
-- htimed_mutex_lock_for
-- htimed_mutex_unlock
-- hcondvar_t
-- hcondvar_init
-- hcondvar_destroy
-- hcondvar_wait
-- hcondvar_wait_for
-- hcondvar_signal
-- hcondvar_broadcast
-- hsem_init
-- hsem_destroy
-- hsem_wait
-- hsem_post
-- hsem_timedwait
-- honce_t
-- HONCE_INIT
-- honce
-
-### hsocket.h
-- INVALID_SOCKET
-- closesocket
-- blocking
-- nonblocking
-- SOCKADDR_STRLEN
-- SOCKADDR_STR
-
-### hloop.h
-- hevent_loop
-- hevent_type
-- hevent_id
-- hevent_priority
-- hevent_userdata
-- hevent_set_priority
-- hevent_ser_userdata
-
-### hscope.h
-- defer
-
-### singleton.h
-- DISABLE_COPY
-- SINGLETON_DECL
-- SINGLETON_IMPL
-

+ 4 - 4
event/hloop.c

@@ -69,7 +69,7 @@ static int hloop_process_timers(hloop_t* loop) {
             }
             else if (timer->event_type == HEVENT_TYPE_PERIOD) {
                 hperiod_t* period = (hperiod_t*)timer;
-                timer->next_timeout = calc_next_timeout(period->minute, period->hour, period->day,
+                timer->next_timeout = cron_next_timeout(period->minute, period->hour, period->day,
                         period->week, period->month) * 1000000;
             }
             heap_insert(&loop->timers, &timer->node);
@@ -174,7 +174,7 @@ static void hloop_init(hloop_t* loop) {
     loop->sockpair[0] = loop->sockpair[1] = -1;
     hmutex_init(&loop->custom_events_mutex);
     // NOTE: init start_time here, because htimer_add use it.
-    loop->start_ms = timestamp_ms();
+    loop->start_ms = gettimeofday_ms();
     loop->start_hrtime = loop->cur_hrtime = gethrtime_us();
 }
 
@@ -301,7 +301,7 @@ void hloop_update_time(hloop_t* loop) {
     loop->cur_hrtime = gethrtime_us();
     if (ABS((int64_t)hloop_now(loop) - (int64_t)time(NULL)) > 1) {
         // systemtime changed, we adjust start_ms
-        loop->start_ms = timestamp_ms() - (loop->cur_hrtime - loop->start_hrtime) / 1000;
+        loop->start_ms = gettimeofday_ms() - (loop->cur_hrtime - loop->start_hrtime) / 1000;
     }
 }
 
@@ -401,7 +401,7 @@ htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
     timer->day    = day;
     timer->month  = month;
     timer->week   = week;
-    timer->next_timeout = calc_next_timeout(minute, hour, day, week, month) * 1000000;
+    timer->next_timeout = cron_next_timeout(minute, hour, day, week, month) * 1000000;
     heap_insert(&loop->timers, &timer->node);
     EVENT_ADD(loop, timer, cb);
     loop->ntimers++;

+ 5 - 5
event/nmap.cpp

@@ -54,7 +54,7 @@ static void on_recvfrom(hio_t* io, void* buf, int readbytes) {
     }
 }
 
-int nmap_discovery(Nmap* nmap) {
+int nmap_discover(Nmap* nmap) {
     hloop_t* loop = hloop_new(0);
     uint64_t start_hrtime = hloop_now_hrtime(loop);
 
@@ -138,7 +138,7 @@ int nmap_discovery(Nmap* nmap) {
     return udata.up_cnt;
 }
 
-int segment_discovery(const char* segment16, Nmap* nmap) {
+int segment_discover(const char* segment16, Nmap* nmap) {
     StringList strlist = split(segment16, '.');
     if (strlist.size() != 4) return -1;
     uint32_t addr = 0;
@@ -152,10 +152,10 @@ int segment_discovery(const char* segment16, Nmap* nmap) {
         p[2] = i;
         (*nmap)[addr] = 0;
     }
-    return nmap_discovery(nmap);
+    return nmap_discover(nmap);
 }
 
-int host_discovery(const char* segment24, Nmap* nmap) {
+int host_discover(const char* segment24, Nmap* nmap) {
     StringList strlist = split(segment24, '.');
     if (strlist.size() != 4) return -1;
     uint32_t addr = 0;
@@ -170,5 +170,5 @@ int host_discovery(const char* segment24, Nmap* nmap) {
         p[3] = i;
         (*nmap)[addr] = 0;
     }
-    return nmap_discovery(nmap);
+    return nmap_discover(nmap);
 }

+ 3 - 3
event/nmap.h

@@ -12,8 +12,8 @@ typedef std::map<uint32_t, int> Nmap;
 // segment24: 192.168.1.x
 
 // @return up_cnt
-int nmap_discovery(Nmap* nmap);
-int segment_discovery(const char* segment16, Nmap* nmap);
-int host_discovery(const char* segment24, Nmap* nmap);
+int nmap_discover(Nmap* nmap);
+int segment_discover(const char* segment16, Nmap* nmap);
+int host_discover(const char* segment24, Nmap* nmap);
 
 #endif // HV_NMAP_H_

+ 1 - 1
examples/consul_cli.cpp

@@ -6,7 +6,7 @@
 
 int main(int argc, char* argv[]) {
     if (argc < 3) {
-        printf("Usage: cmd subcmd ServiceName [ServiceAddress ServicePort] [NodeIP NodePort]\n");
+        printf("Usage: consul_cli subcmd ServiceName [ServiceAddress ServicePort] [NodeIP NodePort]\n");
         printf("subcmd=[register,deregister,discover]\n");
         return -10;
     }

+ 1 - 1
examples/hmain_test.cpp

@@ -250,7 +250,7 @@ int main(int argc, char** argv) {
     signal_init(on_reload);
     const char* signal = get_arg("s");
     if (signal) {
-        handle_signal(signal);
+        signal_handle(signal);
     }
 
 #ifdef OS_UNIX

+ 1 - 1
examples/httpd/httpd.cpp

@@ -227,7 +227,7 @@ int main(int argc, char** argv) {
     signal_init(on_reload);
     const char* signal = get_arg("s");
     if (signal) {
-        handle_signal(signal);
+        signal_handle(signal);
     }
 
 #ifdef OS_UNIX

+ 1 - 1
examples/nc.c

@@ -68,7 +68,7 @@ void on_connect(hio_t* io) {
 int main(int argc, char** argv) {
     if (argc < 3) {
         printf("\
-Usage: cmd [-ut] host port\n\
+Usage: nc [-ut] host port\n\
 Options:\n\
   -t        Use tcp protocol (default)\n\
   -u        Use udp protocol\n\

+ 9 - 9
examples/nmap.cpp

@@ -5,15 +5,15 @@
 #include "hthreadpool.h"
 
 /*
-int host_discovery_task(std::string segment, void* nmap) {
+int host_discover_task(std::string segment, void* nmap) {
     Nmap* hosts= (Nmap*)nmap;
-    return host_discovery(segment.c_str(), hosts);
+    return host_discover(segment.c_str(), hosts);
 }
 */
 
 int main(int argc, char* argv[]) {
     if (argc < 2) {
-        printf("Usage: cmd segment\n");
+        printf("Usage: nmap segment\n");
         printf("Examples: nmap 192.168.1.123\n");
         printf("          nmap 192.168.1.x/24\n");
         printf("          nmap 192.168.x.x/16\n");
@@ -33,13 +33,13 @@ int main(int argc, char* argv[]) {
 
     if (n == 24) {
         Nmap nmap;
-        return host_discovery(segment, &nmap);
+        return host_discover(segment, &nmap);
     }
 
     char ip[INET_ADDRSTRLEN];
     if (n == 16) {
         Nmap segs;
-        int up_nsegs = segment_discovery(segment, &segs);
+        int up_nsegs = segment_discover(segment, &segs);
         if (up_nsegs == 0) return 0;
         Nmap hosts;
         for (auto& pair : segs) {
@@ -53,7 +53,7 @@ int main(int argc, char* argv[]) {
                 }
             }
         }
-        nmap_discovery(&hosts);
+        nmap_discover(&hosts);
         // filter up hosts
         std::vector<uint32_t> up_hosts;
         for (auto& pair : hosts) {
@@ -61,14 +61,14 @@ int main(int argc, char* argv[]) {
                 up_hosts.push_back(pair.first);
             }
         }
-        // ThreadPool + host_discovery
+        // ThreadPool + host_discover
         /*
         if (up_nsegs == 1) {
             for (auto& pair : segs) {
                 if (pair.second == 1) {
                     inet_ntop(AF_INET, (void*)&pair.first, ip, sizeof(ip));
                     Nmap hosts;
-                    return host_discovery(ip, &hosts);
+                    return host_discover(ip, &hosts);
                 }
             }
         }
@@ -81,7 +81,7 @@ int main(int argc, char* argv[]) {
         for (auto& pair : nmap) {
             if (pair.second == 1) {
                 inet_ntop(AF_INET, (void*)&pair.first, ip, sizeof(ip));
-                auto future = tp.commit(host_discovery_task, std::string(ip), &hosts[i++]);
+                auto future = tp.commit(host_discover_task, std::string(ip), &hosts[i++]);
                 futures.push_back(std::move(future));
             }
         }

+ 1 - 1
examples/tcp.c

@@ -33,7 +33,7 @@ void on_accept(hio_t* io) {
 
 int main(int argc, char** argv) {
     if (argc < 2) {
-        printf("Usage: cmd port\n");
+        printf("Usage: tcp port\n");
         return -10;
     }
     int port = atoi(argv[1]);

+ 1 - 1
examples/udp.c

@@ -20,7 +20,7 @@ void on_recvfrom(hio_t* io, void* buf, int readbytes) {
 
 int main(int argc, char** argv) {
     if (argc < 2) {
-        printf("Usage: cmd port\n");
+        printf("Usage: udp port\n");
         return -10;
     }
     int port = atoi(argv[1]);

+ 4 - 4
hconfig.h

@@ -1,14 +1,14 @@
 #ifndef HV_CONFIG_H_
 #define HV_CONFIG_H_
 
-#ifndef HAVE_STDINT_H
-#define HAVE_STDINT_H 1
-#endif
-
 #ifndef HAVE_STDBOOL_H
 #define HAVE_STDBOOL_H 1
 #endif
 
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H 1
+#endif
+
 #ifndef HAVE_SYS_TYPES_H
 #define HAVE_SYS_TYPES_H 1
 #endif

+ 36 - 36
http/Http1Session.cpp → http/Http1Parser.cpp

@@ -1,4 +1,4 @@
-#include "Http1Session.h"
+#include "Http1Parser.h"
 
 static int on_url(http_parser* parser, const char *at, size_t length);
 static int on_status(http_parser* parser, const char *at, size_t length);
@@ -9,9 +9,9 @@ static int on_message_begin(http_parser* parser);
 static int on_headers_complete(http_parser* parser);
 static int on_message_complete(http_parser* parser);
 
-http_parser_settings* Http1Session::cbs = NULL;
+http_parser_settings* Http1Parser::cbs = NULL;
 
-Http1Session::Http1Session(http_session_type type) {
+Http1Parser::Http1Parser(http_session_type type) {
     if (cbs == NULL) {
         cbs = (http_parser_settings*)malloc(sizeof(http_parser_settings));
         http_parser_settings_init(cbs);
@@ -31,83 +31,83 @@ Http1Session::Http1Session(http_session_type type) {
     parsed = NULL;
 }
 
-Http1Session::~Http1Session() {
+Http1Parser::~Http1Parser() {
 }
 
 int on_url(http_parser* parser, const char *at, size_t length) {
     printd("on_url:%.*s\n", (int)length, at);
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_URL;
-    hss->url.append(at, length);
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_URL;
+    hp->url.append(at, length);
     return 0;
 }
 
 int on_status(http_parser* parser, const char *at, size_t length) {
     printd("on_status:%.*s\n", (int)length, at);
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_STATUS;
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_STATUS;
     return 0;
 }
 
 int on_header_field(http_parser* parser, const char *at, size_t length) {
     printd("on_header_field:%.*s\n", (int)length, at);
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->handle_header();
-    hss->state = HP_HEADER_FIELD;
-    hss->header_field.append(at, length);
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->handle_header();
+    hp->state = HP_HEADER_FIELD;
+    hp->header_field.append(at, length);
     return 0;
 }
 
 int on_header_value(http_parser* parser, const char *at, size_t length) {
     printd("on_header_value:%.*s""\n", (int)length, at);
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_HEADER_VALUE;
-    hss->header_value.append(at, length);
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_HEADER_VALUE;
+    hp->header_value.append(at, length);
     return 0;
 }
 
 int on_body(http_parser* parser, const char *at, size_t length) {
     //printd("on_body:%.*s""\n", (int)length, at);
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_BODY;
-    hss->parsed->body.append(at, length);
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_BODY;
+    hp->parsed->body.append(at, length);
     return 0;
 }
 
 int on_message_begin(http_parser* parser) {
     printd("on_message_begin\n");
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_MESSAGE_BEGIN;
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_MESSAGE_BEGIN;
     return 0;
 }
 
 int on_headers_complete(http_parser* parser) {
     printd("on_headers_complete\n");
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->handle_header();
-    auto iter = hss->parsed->headers.find("content-type");
-    if (iter != hss->parsed->headers.end()) {
-        hss->parsed->content_type = http_content_type_enum(iter->second.c_str());
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->handle_header();
+    auto iter = hp->parsed->headers.find("content-type");
+    if (iter != hp->parsed->headers.end()) {
+        hp->parsed->content_type = http_content_type_enum(iter->second.c_str());
     }
-    hss->parsed->http_major = parser->http_major;
-    hss->parsed->http_minor = parser->http_minor;
-    if (hss->parsed->type == HTTP_REQUEST) {
-        HttpRequest* req = (HttpRequest*)hss->parsed;
+    hp->parsed->http_major = parser->http_major;
+    hp->parsed->http_minor = parser->http_minor;
+    if (hp->parsed->type == HTTP_REQUEST) {
+        HttpRequest* req = (HttpRequest*)hp->parsed;
         req->method = (http_method)parser->method;
-        req->url = hss->url;
+        req->url = hp->url;
     }
-    else if (hss->parsed->type == HTTP_RESPONSE) {
-        HttpResponse* res = (HttpResponse*)hss->parsed;
+    else if (hp->parsed->type == HTTP_RESPONSE) {
+        HttpResponse* res = (HttpResponse*)hp->parsed;
         res->status_code = (http_status)parser->status_code;
     }
-    hss->state = HP_HEADERS_COMPLETE;
+    hp->state = HP_HEADERS_COMPLETE;
     return 0;
 }
 
 int on_message_complete(http_parser* parser) {
     printd("on_message_complete\n");
-    Http1Session* hss = (Http1Session*)parser->data;
-    hss->state = HP_MESSAGE_COMPLETE;
+    Http1Parser* hp = (Http1Parser*)parser->data;
+    hp->state = HP_MESSAGE_COMPLETE;
     return 0;
 }
 

+ 7 - 7
http/Http1Session.h → http/Http1Parser.h

@@ -1,7 +1,7 @@
-#ifndef HTTP1_SESSION_H_
-#define HTTP1_SESSION_H_
+#ifndef HTTP1_PARSER_H_
+#define HTTP1_PARSER_H_
 
-#include "HttpSession.h"
+#include "HttpParser.h"
 #include "http_parser.h"
 
 enum http_parser_state {
@@ -16,7 +16,7 @@ enum http_parser_state {
     HP_MESSAGE_COMPLETE
 };
 
-class Http1Session : public HttpSession {
+class Http1Parser : public HttpParser {
 public:
     static http_parser_settings*    cbs;
     http_parser                     parser;
@@ -29,8 +29,8 @@ public:
     std::string header_value; // for on_header_value
     std::string sendbuf;      // for GetSendData
 
-    Http1Session(http_session_type type = HTTP_CLIENT);
-    virtual ~Http1Session();
+    Http1Parser(http_session_type type = HTTP_CLIENT);
+    virtual ~Http1Parser();
 
     void handle_header() {
         if (header_field.size() != 0 && header_value.size() != 0) {
@@ -117,4 +117,4 @@ public:
     }
 };
 
-#endif // HTTP1_SESSION_H_
+#endif // HTTP1_PARSER_H_

+ 31 - 31
http/Http2Session.cpp → http/Http2Parser.cpp

@@ -1,6 +1,6 @@
 #ifdef WITH_NGHTTP2
 
-#include "Http2Session.h"
+#include "Http2Parser.h"
 
 static nghttp2_nv make_nv(const char* name, const char* value) {
     nghttp2_nv nv;
@@ -43,7 +43,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
 */
 
 
-Http2Session::Http2Session(http_session_type type) {
+Http2Parser::Http2Parser(http_session_type type) {
     if (cbs == NULL) {
         nghttp2_session_callbacks_new(&cbs);
         nghttp2_session_callbacks_set_on_header_callback(cbs, on_header_callback);
@@ -74,14 +74,14 @@ Http2Session::Http2Session(http_session_type type) {
     //state = HSS_SEND_PING;
 }
 
-Http2Session::~Http2Session() {
+Http2Parser::~Http2Parser() {
     if (session) {
         nghttp2_session_del(session);
         session = NULL;
     }
 }
 
-int Http2Session::GetSendData(char** data, size_t* len) {
+int Http2Parser::GetSendData(char** data, size_t* len) {
     // HTTP2_MAGIC,HTTP2_SETTINGS,HTTP2_HEADERS
     *len = nghttp2_session_mem_send(session, (const uint8_t**)data);
     printd("nghttp2_session_mem_send %d\n", *len);
@@ -171,7 +171,7 @@ send_done:
     return *len;
 }
 
-int Http2Session::FeedRecvData(const char* data, size_t len) {
+int Http2Parser::FeedRecvData(const char* data, size_t len) {
     printd("nghttp2_session_mem_recv %d\n", len);
     state = HSS_WANT_RECV;
     size_t ret = nghttp2_session_mem_recv(session, (const uint8_t*)data, len);
@@ -181,7 +181,7 @@ int Http2Session::FeedRecvData(const char* data, size_t len) {
     return (int)ret;
 }
 
-int Http2Session::SubmitRequest(HttpRequest* req) {
+int Http2Parser::SubmitRequest(HttpRequest* req) {
     submited = req;
 
     req->FillContentType();
@@ -236,7 +236,7 @@ int Http2Session::SubmitRequest(HttpRequest* req) {
     return 0;
 }
 
-int Http2Session::SubmitResponse(HttpResponse* res) {
+int Http2Parser::SubmitResponse(HttpResponse* res) {
     submited = res;
 
     res->FillContentType();
@@ -288,7 +288,7 @@ int Http2Session::SubmitResponse(HttpResponse* res) {
     return 0;
 }
 
-int Http2Session::InitResponse(HttpResponse* res) {
+int Http2Parser::InitResponse(HttpResponse* res) {
     res->Reset();
     res->http_major = 2;
     res->http_minor = 0;
@@ -296,7 +296,7 @@ int Http2Session::InitResponse(HttpResponse* res) {
     return 0;
 }
 
-int Http2Session::InitRequest(HttpRequest* req) {
+int Http2Parser::InitRequest(HttpRequest* req) {
     req->Reset();
     req->http_major = 2;
     req->http_minor = 0;
@@ -304,7 +304,7 @@ int Http2Session::InitRequest(HttpRequest* req) {
     return 0;
 }
 
-nghttp2_session_callbacks* Http2Session::cbs = NULL;
+nghttp2_session_callbacks* Http2Parser::cbs = NULL;
 
 int on_header_callback(nghttp2_session *session,
     const nghttp2_frame *frame,
@@ -316,11 +316,11 @@ int on_header_callback(nghttp2_session *session,
     const char* name = (const char*)_name;
     const char* value = (const char*)_value;
     printd("%s: %s\n", name, value);
-    Http2Session* hss = (Http2Session*)userdata;
+    Http2Parser* hp = (Http2Parser*)userdata;
     if (*name == ':') {
-        if (hss->parsed->type == HTTP_REQUEST) {
+        if (hp->parsed->type == HTTP_REQUEST) {
             // :method :path :scheme :authority
-            HttpRequest* req = (HttpRequest*)hss->parsed;
+            HttpRequest* req = (HttpRequest*)hp->parsed;
             if (strcmp(name, ":method") == 0) {
                 req->method = http_method_enum(value);
             }
@@ -334,17 +334,17 @@ int on_header_callback(nghttp2_session *session,
                 req->headers["Host"] = value;
             }
         }
-        else if (hss->parsed->type == HTTP_RESPONSE) {
-            HttpResponse* res = (HttpResponse*)hss->parsed;
+        else if (hp->parsed->type == HTTP_RESPONSE) {
+            HttpResponse* res = (HttpResponse*)hp->parsed;
             if (strcmp(name, ":status") == 0) {
                 res->status_code = (http_status)atoi(value);
             }
         }
     }
     else {
-        hss->parsed->headers[name] = value;
+        hp->parsed->headers[name] = value;
         if (strcmp(name, "content-type") == 0) {
-            hss->parsed->content_type = http_content_type_enum(value);
+            hp->parsed->content_type = http_content_type_enum(value);
         }
     }
     return 0;
@@ -356,9 +356,9 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
     printd("on_data_chunk_recv_callback\n");
     printd("stream_id=%d length=%d\n", stream_id, (int)len);
     //printd("%.*s\n", (int)len, data);
-    Http2Session* hss = (Http2Session*)userdata;
+    Http2Parser* hp = (Http2Parser*)userdata;
 
-    if (hss->parsed->ContentType() == APPLICATION_GRPC) {
+    if (hp->parsed->ContentType() == APPLICATION_GRPC) {
         // grpc_message_hd
         if (len >= GRPC_MESSAGE_HDLEN) {
             grpc_message_hd msghd;
@@ -369,7 +369,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
             //printd("%.*s\n", (int)len, data);
         }
     }
-    hss->parsed->body.append((const char*)data, len);
+    hp->parsed->body.append((const char*)data, len);
     return 0;
 }
 
@@ -377,19 +377,19 @@ int on_frame_recv_callback(nghttp2_session *session,
     const nghttp2_frame *frame, void *userdata) {
     printd("on_frame_recv_callback\n");
     print_frame_hd(&frame->hd);
-    Http2Session* hss = (Http2Session*)userdata;
+    Http2Parser* hp = (Http2Parser*)userdata;
     switch (frame->hd.type) {
     case NGHTTP2_DATA:
-        hss->state = HSS_RECV_DATA;
+        hp->state = HSS_RECV_DATA;
         break;
     case NGHTTP2_HEADERS:
-        hss->state = HSS_RECV_HEADERS;
+        hp->state = HSS_RECV_HEADERS;
         break;
     case NGHTTP2_SETTINGS:
-        hss->state = HSS_RECV_SETTINGS;
+        hp->state = HSS_RECV_SETTINGS;
         break;
     case NGHTTP2_PING:
-        hss->state = HSS_RECV_PING;
+        hp->state = HSS_RECV_PING;
         break;
     case NGHTTP2_RST_STREAM:
     case NGHTTP2_WINDOW_UPDATE:
@@ -398,13 +398,13 @@ int on_frame_recv_callback(nghttp2_session *session,
     default:
         break;
     }
-    if (frame->hd.stream_id >= hss->stream_id) {
-        hss->stream_id = frame->hd.stream_id;
-        hss->stream_closed = 0;
+    if (frame->hd.stream_id >= hp->stream_id) {
+        hp->stream_id = frame->hd.stream_id;
+        hp->stream_closed = 0;
         if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
-            printd("on_stream_closed stream_id=%d\n", hss->stream_id);
-            hss->stream_closed = 1;
-            hss->frame_type_when_stream_closed = frame->hd.type;
+            printd("on_stream_closed stream_id=%d\n", hp->stream_id);
+            hp->stream_closed = 1;
+            hp->frame_type_when_stream_closed = frame->hd.type;
         }
     }
 

+ 7 - 7
http/Http2Session.h → http/Http2Parser.h

@@ -1,8 +1,8 @@
-#ifndef HTTP2_SESSION_H_
-#define HTTP2_SESSION_H_
+#ifndef HTTP2_PARSER_H_
+#define HTTP2_PARSER_H_
 
 #ifdef WITH_NGHTTP2
-#include "HttpSession.h"
+#include "HttpParser.h"
 #include "http2def.h"
 #include "grpcdef.h"
 
@@ -24,7 +24,7 @@ enum http2_session_state {
     HSS_RECV_DATA,
 };
 
-class Http2Session : public HttpSession {
+class Http2Parser : public HttpParser {
 public:
     static nghttp2_session_callbacks* cbs;
     nghttp2_session*                session;
@@ -39,8 +39,8 @@ public:
     // at least HTTP2_FRAME_HDLEN + GRPC_MESSAGE_HDLEN = 9 + 5 = 14
     unsigned char                   frame_hdbuf[32];
 
-    Http2Session(http_session_type type = HTTP_CLIENT);
-    virtual ~Http2Session();
+    Http2Parser(http_session_type type = HTTP_CLIENT);
+    virtual ~Http2Parser();
 
     virtual int GetSendData(char** data, size_t* len);
     virtual int FeedRecvData(const char* data, size_t len);
@@ -84,4 +84,4 @@ public:
 
 #endif
 
-#endif // HTTP2_SESSION_H_
+#endif // HTTP2_PARSER_H_

+ 1 - 1
http/HttpMessage.h

@@ -36,7 +36,7 @@ public:
 #ifndef WITHOUT_HTTP_CONTENT
     Json                json;       // APPLICATION_JSON
     MultiPart           form;       // MULTIPART_FORM_DATA
-    KeyValue            kv;         // X_WWW_FORM_URLENCODED
+    hv::KeyValue        kv;         // X_WWW_FORM_URLENCODED
 
     // T=[bool, int64_t, double]
     template<typename T>

+ 25 - 0
http/HttpParser.cpp

@@ -0,0 +1,25 @@
+#include "HttpParser.h"
+
+#include "Http1Parser.h"
+#include "Http2Parser.h"
+
+HttpParser* HttpParser::New(http_session_type type, http_version version) {
+    HttpParser* hp = NULL;
+    if (version == HTTP_V1) {
+        hp = new Http1Parser(type);
+    }
+    else if (version == HTTP_V2) {
+#ifdef WITH_NGHTTP2
+        hp = new Http2Parser(type);
+#else
+        fprintf(stderr, "Please recompile WITH_NGHTTP2!\n");
+#endif
+    }
+
+    if (hp) {
+        hp->version = version;
+        hp->type = type;
+    }
+
+    return hp;
+}

+ 14 - 14
http/HttpSession.h → http/HttpParser.h

@@ -1,34 +1,34 @@
-#ifndef HTTP_SESSION_H_
-#define HTTP_SESSION_H_
+#ifndef HTTP_PARSER_H_
+#define HTTP_PARSER_H_
 
 #include "HttpMessage.h"
 
-class HttpSession {
+class HttpParser {
 public:
     http_version        version;
     http_session_type   type;
 
-    static HttpSession* New(http_session_type type = HTTP_CLIENT, http_version version = HTTP_V1);
-    virtual ~HttpSession() {}
+    static HttpParser* New(http_session_type type = HTTP_CLIENT, http_version version = HTTP_V1);
+    virtual ~HttpParser() {}
 
     virtual int GetSendData(char** data, size_t* len) = 0;
     virtual int FeedRecvData(const char* data, size_t len) = 0;
 
-    // Http1Session: http_parser_state
-    // Http2Session: http2_session_state
+    // Http1Parser: http_parser_state
+    // Http2Parser: http2_session_state
     virtual int GetState() = 0;
 
-    // Http1Session: GetState() != HP_MESSAGE_COMPLETE
-    // Http2Session: GetState() == HSS_WANT_RECV
+    // Http1Parser: GetState() != HP_MESSAGE_COMPLETE
+    // Http2Parser: GetState() == HSS_WANT_RECV
     virtual bool WantRecv() = 0;
 
-    // Http1Session: GetState() == HP_MESSAGE_COMPLETE
-    // Http2Session: GetState() == HSS_WANT_SEND
+    // Http1Parser: GetState() == HP_MESSAGE_COMPLETE
+    // Http2Parser: GetState() == HSS_WANT_SEND
     virtual bool WantSend() = 0;
 
     // IsComplete: Is recved HttpRequest or HttpResponse complete?
-    // Http1Session: GetState() == HP_MESSAGE_COMPLETE
-    // Http2Session: (state == HSS_RECV_HEADERS || state == HSS_RECV_DATA) && stream_closed
+    // Http1Parser: GetState() == HP_MESSAGE_COMPLETE
+    // Http2Parser: (state == HSS_RECV_HEADERS || state == HSS_RECV_DATA) && stream_closed
     virtual bool IsComplete() = 0;
 
     // client
@@ -45,4 +45,4 @@ public:
     virtual const char* StrError(int error) = 0;
 };
 
-#endif // HTTP_SESSION_H_
+#endif // HTTP_PARSER_H_

+ 0 - 25
http/HttpSession.cpp

@@ -1,25 +0,0 @@
-#include "HttpSession.h"
-
-#include "Http1Session.h"
-#include "Http2Session.h"
-
-HttpSession* HttpSession::New(http_session_type type, http_version version) {
-    HttpSession* hs = NULL;
-    if (version == HTTP_V1) {
-        hs = new Http1Session(type);
-    }
-    else if (version == HTTP_V2) {
-#ifdef WITH_NGHTTP2
-        hs = new Http2Session(type);
-#else
-        fprintf(stderr, "Please recompile WITH_NGHTTP2!\n");
-#endif
-    }
-
-    if (hs) {
-        hs->version = version;
-        hs->type = type;
-    }
-
-    return hs;
-}

+ 13 - 13
http/client/http_client.cpp

@@ -9,7 +9,7 @@
 #else
 #include "herr.h"
 #include "hsocket.h"
-#include "HttpSession.h"
+#include "HttpParser.h"
 #include "ssl_ctx.h"
 #endif
 
@@ -29,7 +29,7 @@ struct http_client_s {
     CURL* curl;
 #else
     int fd;
-    HttpSession* session;
+    HttpParser*  parser;
 #endif
 #ifdef WITH_OPENSSL
     SSL* ssl;
@@ -44,7 +44,7 @@ struct http_client_s {
         curl = NULL;
 #else
         fd = -1;
-        session = NULL;
+        parser = NULL;
 #endif
 #ifdef WITH_OPENSSL
         ssl = NULL;
@@ -72,9 +72,9 @@ struct http_client_s {
             closesocket(fd);
             fd = -1;
         }
-        if (session) {
-            delete session;
-            session = NULL;
+        if (parser) {
+            delete parser;
+            parser = NULL;
         }
 #endif
     }
@@ -340,8 +340,8 @@ static int __http_client_connect(http_client_t* cli) {
 #endif
     }
 
-    if (cli->session == NULL) {
-        cli->session = HttpSession::New(HTTP_CLIENT, (http_version)cli->http_version);
+    if (cli->parser == NULL) {
+        cli->parser = HttpParser::New(HTTP_CLIENT, (http_version)cli->http_version);
     }
 
     cli->fd = connfd;
@@ -376,14 +376,14 @@ connect:
         connfd = cli->fd;
     }
 
-    cli->session->SubmitRequest(req);
+    cli->parser->SubmitRequest(req);
     char recvbuf[1024] = {0};
     int total_nsend, nsend, nrecv;
     total_nsend = nsend = nrecv = 0;
 send:
     char* data = NULL;
     size_t len  = 0;
-    while (cli->session->GetSendData(&data, &len)) {
+    while (cli->parser->GetSendData(&data, &len)) {
         total_nsend = 0;
         while (1) {
             if (timeout > 0) {
@@ -417,7 +417,7 @@ send:
             }
         }
     }
-    cli->session->InitResponse(res);
+    cli->parser->InitResponse(res);
 recv:
     do {
         if (timeout > 0) {
@@ -438,11 +438,11 @@ recv:
         if (nrecv <= 0) {
             return socket_errno();
         }
-        int nparse = cli->session->FeedRecvData(recvbuf, nrecv);
+        int nparse = cli->parser->FeedRecvData(recvbuf, nrecv);
         if (nparse != nrecv) {
             return ERR_PARSE;
         }
-    } while(!cli->session->IsComplete());
+    } while(!cli->parser->IsComplete());
     return err;
 }
 

+ 1 - 1
http/http_content.h

@@ -4,7 +4,7 @@
 #include "hstring.h"
 
 // QueryParams
-typedef KeyValue    QueryParams;
+typedef hv::KeyValue    QueryParams;
 std::string dump_query_params(QueryParams& query_params);
 int         parse_query_params(const char* query_string, QueryParams& query_params);
 

+ 3 - 3
http/server/HttpHandler.h

@@ -1,7 +1,7 @@
 #ifndef HTTP_HANDLER_H_
 #define HTTP_HANDLER_H_
 
-#include "HttpSession.h"
+#include "HttpParser.h"
 #include "HttpService.h"
 #include "FileCache.h"
 #include "hloop.h"
@@ -21,7 +21,7 @@ public:
     // for handle_request
     HttpService*            service;
     FileCache*              files;
-    HttpSession*            session;
+    HttpParser*             parser;
     HttpRequest             req;
     HttpResponse            res;
     file_cache_t*           fc;
@@ -32,7 +32,7 @@ public:
     HttpHandler() {
         service = NULL;
         files = NULL;
-        session = NULL;
+        parser = NULL;
         fc = NULL;
         io = NULL;
         keepalive_timer = NULL;

+ 24 - 24
http/server/HttpServer.cpp

@@ -7,7 +7,7 @@
 #include "http2def.h"
 #include "FileCache.h"
 #include "HttpHandler.h"
-#include "Http2Session.h"
+#include "Http2Parser.h"
 
 #define MIN_HTTP_REQUEST        "GET / HTTP/1.1\r\n\r\n"
 #define MIN_HTTP_REQUEST_LEN    14 // exclude CRLF
@@ -23,10 +23,10 @@ static void on_recv(hio_t* io, void* _buf, int readbytes) {
     // printf("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
     const char* buf = (const char*)_buf;
     HttpHandler* handler = (HttpHandler*)hevent_userdata(io);
-    // HTTP1 / HTTP2 -> HttpSession -> InitRequest
+    // HTTP1 / HTTP2 -> HttpParser -> InitRequest
     // recv -> FeedRecvData -> !WantRecv -> HttpRequest ->
     // HandleRequest -> HttpResponse -> SubmitResponse -> while (GetSendData) -> send
-    if (handler->session == NULL) {
+    if (handler->parser == NULL) {
         // check request-line
         if (readbytes < MIN_HTTP_REQUEST_LEN) {
             hloge("[%s:%d] http request-line too small", handler->ip, handler->port);
@@ -46,27 +46,27 @@ static void on_recv(hio_t* io, void* _buf, int readbytes) {
             handler->req.http_major = 2;
             handler->req.http_minor = 0;
         }
-        handler->session = HttpSession::New(HTTP_SERVER, version);
-        if (handler->session == NULL) {
+        handler->parser = HttpParser::New(HTTP_SERVER, version);
+        if (handler->parser == NULL) {
             hloge("[%s:%d] unsupported HTTP%d", handler->ip, handler->port, (int)version);
             hio_close(io);
             return;
         }
-        handler->session->InitRequest(&handler->req);
+        handler->parser->InitRequest(&handler->req);
     }
 
-    HttpSession* session = handler->session;
+    HttpParser* parser = handler->parser;
     HttpRequest* req = &handler->req;
     HttpResponse* res = &handler->res;
 
-    int nfeed = session->FeedRecvData((const char*)buf, readbytes);
+    int nfeed = parser->FeedRecvData((const char*)buf, readbytes);
     if (nfeed != readbytes) {
-        hloge("[%s:%d] http parse error: %s", handler->ip, handler->port, session->StrError(session->GetError()));
+        hloge("[%s:%d] http parse error: %s", handler->ip, handler->port, parser->StrError(parser->GetError()));
         hio_close(io);
         return;
     }
 
-    if (session->WantRecv()) {
+    if (parser->WantRecv()) {
         // NOTE: KeepAlive will reset keepalive_timer,
         // if no data recv within keepalive timeout, closesocket actively.
         handler->KeepAlive();
@@ -74,18 +74,18 @@ static void on_recv(hio_t* io, void* _buf, int readbytes) {
     }
 
 #ifdef WITH_NGHTTP2
-    if (session->version == HTTP_V2) {
+    if (parser->version == HTTP_V2) {
         // HTTP2 extra processing steps
-        Http2Session* h2s = (Http2Session*)session;
-        if (h2s->state == HSS_RECV_PING) {
+        Http2Parser* h2p = (Http2Parser*)parser;
+        if (h2p->state == HSS_RECV_PING) {
             char* data = NULL;
             size_t len = 0;
-            while (session->GetSendData(&data, &len)) {
+            while (parser->GetSendData(&data, &len)) {
                 hio_write(io, data, len);
             }
             return;
         }
-        else if ((h2s->state == HSS_RECV_HEADERS && req->method != HTTP_POST) || h2s->state == HSS_RECV_DATA) {
+        else if ((h2p->state == HSS_RECV_HEADERS && req->method != HTTP_POST) || h2p->state == HSS_RECV_DATA) {
             goto handle_request;
         }
         else {
@@ -102,20 +102,20 @@ static void on_recv(hio_t* io, void* _buf, int readbytes) {
             // h2/h2c
             if (strnicmp(iter_upgrade->second.c_str(), "h2", 2) == 0) {
                 hio_write(io, HTTP2_UPGRADE_RESPONSE, strlen(HTTP2_UPGRADE_RESPONSE));
-                SAFE_DELETE(handler->session);
-                session = handler->session = HttpSession::New(HTTP_SERVER, HTTP_V2);
-                if (session == NULL) {
+                SAFE_DELETE(handler->parser);
+                parser = handler->parser = HttpParser::New(HTTP_SERVER, HTTP_V2);
+                if (parser == NULL) {
                     hloge("[%s:%d] unsupported HTTP2", handler->ip, handler->port);
                     hio_close(io);
                     return;
                 }
                 HttpRequest http1_req = *req;
-                session->InitRequest(req);
+                parser->InitRequest(req);
                 *req = http1_req;
                 req->http_major = 2;
                 req->http_minor = 0;
                 // HTTP2_Settings: ignore
-                // session->FeedRecvData(HTTP2_Settings, );
+                // parser->FeedRecvData(HTTP2_Settings, );
             }
             else {
                 hio_close(io);
@@ -180,10 +180,10 @@ handle_request:
         }
     }
     else if (req->http_major == 2) {
-        session->SubmitResponse(res);
+        parser->SubmitResponse(res);
         char* data = NULL;
         size_t len = 0;
-        while (session->GetSendData(&data, &len)) {
+        while (parser->GetSendData(&data, &len)) {
             hio_write(io, data, len);
         }
     }
@@ -196,7 +196,7 @@ handle_request:
     if (keepalive) {
         handler->KeepAlive();
         handler->Reset();
-        session->InitRequest(req);
+        parser->InitRequest(req);
     }
     else {
         hio_close(io);
@@ -206,7 +206,7 @@ handle_request:
 static void on_close(hio_t* io) {
     HttpHandler* handler = (HttpHandler*)hevent_userdata(io);
     if (handler) {
-        SAFE_DELETE(handler->session);
+        SAFE_DELETE(handler->parser);
         delete handler;
         hevent_set_userdata(io, NULL);
     }

+ 11 - 10
hv.h

@@ -10,32 +10,33 @@
 #include "hplatform.h"
 
 // c
-#include "hdef.h"
-#include "hversion.h"
+#include "hdef.h"   // <stddef.h>
+#include "herr.h"   // <errno.h>
+#include "htime.h"  // <time.h>
+#include "hmath.h"  // <math.h>
+
 #include "hbase.h"
+#include "hversion.h"
 #include "hsysinfo.h"
 #include "hproc.h"
-#include "hmath.h"
-#include "htime.h"
-#include "herr.h"
-#include "hlog.h"
-#include "hmutex.h"
 #include "hthread.h"
+#include "hmutex.h"
 #include "hsocket.h"
+
+#include "hlog.h"
 #include "hbuf.h"
 #include "hgui.h"
 
 // cpp
 #ifdef __cplusplus
-#include "hstring.h"
+#include "hmap.h"       // <map>
+#include "hstring.h"    // <string>
 #include "hvar.h"
 #include "hobj.h"
 #include "hfile.h"
 #include "hdir.h"
 #include "hurl.h"
 #include "hscope.h"
-#include "hthreadpool.h"
-#include "hobjectpool.h"
 #endif
 
 #endif  // HV_H_

+ 8 - 0
unittest/CMakeLists.txt

@@ -1,3 +1,9 @@
+add_executable(mkdir_p mkdir_test.c ../base/hbase.c)
+target_include_directories(mkdir_p PRIVATE .. ../base)
+
+add_executable(date date_test.c ../base/htime.c)
+target_include_directories(date PRIVATE .. ../base)
+
 add_executable(hmutex_test hmutex_test.c ../base/htime.c)
 target_include_directories(hmutex_test PRIVATE .. ../base)
 target_link_libraries(hmutex_test -lpthread)
@@ -46,6 +52,8 @@ add_executable(webbench webbench.c)
 endif()
 
 add_custom_target(unittest DEPENDS
+    mkdir_p
+    date
     hmutex_test
     connect_test
     socketpair_test

+ 15 - 0
unittest/date_test.c

@@ -0,0 +1,15 @@
+#include "htime.h"
+
+int main(int argc, char* argv[]) {
+    datetime_t dt = datetime_now();
+    char buf1[DATETIME_FMT_BUFLEN];
+    datetime_fmt(&dt, buf1);
+    puts(buf1);
+
+    time_t ts = datetime_mktime(&dt);
+    char buf2[GMTIME_FMT_BUFLEN];
+    gmtime_fmt(ts, buf2);
+    puts(buf2);
+
+    return 0;
+}

+ 1 - 1
unittest/hstring_test.cpp

@@ -25,7 +25,7 @@ int main(int argc, char** argv) {
     }
 
     std::string str7("user=admin&pswd=123456");
-    KeyValue kv = splitKV(str7, '&', '=');
+    hv::KeyValue kv = splitKV(str7, '&', '=');
     for (auto& pair : kv) {
         printf("%s=%s\n", pair.first.c_str(), pair.second.c_str());
     }

+ 10 - 0
unittest/mkdir_test.c

@@ -0,0 +1,10 @@
+#include "hbase.h"
+
+int main(int argc, char* argv[]) {
+    if (argc < 2) {
+        printf("Usage: mkdir_p dir\n");
+        return -1;
+    }
+    const char* dir = argv[1];
+    return hv_mkdir_p(dir);
+}

+ 1 - 1
unittest/nslookup_test.c

@@ -5,7 +5,7 @@
 
 int main(int argc, char* argv[]) {
     if (argc < 2) {
-        printf("Usage: cmd domain [nameserver]\n");
+        printf("Usage: nslookup domain [nameserver]\n");
         return -1;
     }
 

+ 2 - 2
unittest/sendmail_test.c

@@ -4,7 +4,7 @@
 
 int main(int argc, char** argv) {
     if (argc < 8) {
-        printf("Usage: cmd smtp_server username password from to subject body\n");
+        printf("Usage: sendmail smtp_server username password from to subject body\n");
     }
 
     const char* smtp_server = argv[1];
@@ -17,7 +17,7 @@ int main(int argc, char** argv) {
     mail.body = argv[7];
 
     int status_code = sendmail(smtp_server, username, password, &mail);
-    printf("sendmail: %d %s\n", status_code, smtp_status_str(status_code));
+    printf("sendmail: %d %s\n", status_code, smtp_status_str((enum smtp_status)status_code));
 
     return status_code == SMTP_STATUS_OK ? 0 : status_code;
 }

+ 4 - 2
utils/hendian.h

@@ -115,7 +115,8 @@ uint8_t* serialize(uint8_t* buf, T value, int host_endian = LITTLE_ENDIAN, int b
 
     if (host_endian == buf_endian) {
         memcpy(pDst, pSrc, size);
-    } else {
+    }
+    else {
         for (int i = 0; i < size; ++i) {
             pDst[i] = pSrc[size-i-1];
         }
@@ -132,7 +133,8 @@ uint8_t* deserialize(uint8_t* buf, T* value, int host_endian = LITTLE_ENDIAN, in
 
     if (host_endian == buf_endian) {
         memcpy(pDst, pSrc, size);
-    } else {
+    }
+    else {
         for (int i = 0; i < size; ++i) {
             pDst[i] = pSrc[size-i-1];
         }

+ 6 - 5
utils/hmain.cpp

@@ -1,5 +1,8 @@
 #include "hmain.h"
 
+#include <signal.h>
+
+#include "hbase.h"
 #include "hlog.h"
 #include "herr.h"
 #include "htime.h"
@@ -7,7 +10,6 @@
 
 #ifdef OS_DARWIN
 #include <crt_externs.h>
-#include <mach-o/dyld.h> // for _NSGetExecutablePath
 #define environ (*_NSGetEnviron())
 #endif
 
@@ -29,8 +31,7 @@ int main_ctx_init(int argc, char** argv) {
 
     get_run_dir(g_main_ctx.run_dir, sizeof(g_main_ctx.run_dir));
     //printf("run_dir=%s\n", g_main_ctx.run_dir);
-    char* pos = strrchr_dir(argv[0]);
-    strncpy(g_main_ctx.program_name, pos+1, sizeof(g_main_ctx.program_name));
+    strncpy(g_main_ctx.program_name, hv_basename(argv[0]), sizeof(g_main_ctx.program_name));
 #ifdef OS_WIN
     if (strcmp(g_main_ctx.program_name+strlen(g_main_ctx.program_name)-4, ".exe") == 0) {
         *(g_main_ctx.program_name+strlen(g_main_ctx.program_name)-4) = '\0';
@@ -39,7 +40,7 @@ int main_ctx_init(int argc, char** argv) {
     //printf("program_name=%s\n", g_main_ctx.program_name);
     char logpath[MAX_PATH] = {0};
     snprintf(logpath, sizeof(logpath), "%s/logs", g_main_ctx.run_dir);
-    MKDIR(logpath);
+    hv_mkdir(logpath);;
     snprintf(g_main_ctx.confile, sizeof(g_main_ctx.confile), "%s/etc/%s.conf", g_main_ctx.run_dir, g_main_ctx.program_name);
     snprintf(g_main_ctx.pidfile, sizeof(g_main_ctx.pidfile), "%s/logs/%s.pid", g_main_ctx.run_dir, g_main_ctx.program_name);
     snprintf(g_main_ctx.logfile, sizeof(g_main_ctx.confile), "%s/logs/%s.log", g_main_ctx.run_dir, g_main_ctx.program_name);
@@ -462,7 +463,7 @@ static void kill_proc(int pid) {
 #endif
 }
 
-void handle_signal(const char* signal) {
+void signal_handle(const char* signal) {
     if (strcmp(signal, "start") == 0) {
         if (g_main_ctx.oldpid > 0) {
             printf("%s is already running, pid=%d\n", g_main_ctx.program_name, g_main_ctx.oldpid);

+ 1 - 1
utils/hmain.h

@@ -69,7 +69,7 @@ pid_t    getpid_from_pidfile();
 
 // signal=[start,stop,restart,status,reload]
 int signal_init(procedure_t reload_fn = NULL, void* reload_userdata = NULL);
-void handle_signal(const char* signal);
+void signal_handle(const char* signal);
 #ifdef OS_UNIX
 // we use SIGTERM to quit process, SIGUSR1 to reload confile
 #define SIGNAL_TERMINATE    SIGTERM

+ 2 - 2
utils/singleton.h

@@ -2,8 +2,8 @@
 #define HV_SINGLETON_H_
 
 #define DISABLE_COPY(Class) \
-    Class(const Class &) = delete; \
-    Class &operator=(const Class &) = delete;
+    Class(const Class&) = delete; \
+    Class& operator=(const Class&) = delete;
 
 #define SINGLETON_DECL(Class) \
     public: \