libfastcommon/src/common_define.h

549 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2020 YuQing <384681@qq.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the Lesser GNU General Public License, version 3
* or later ("LGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
//common_define.h
#ifndef _COMMON_DEFINE_H_
#define _COMMON_DEFINE_H_
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
typedef UINT in_addr_t;
#define FILE_SEPERATOR "\\"
#define THREAD_ENTRANCE_FUNC_DECLARE DWORD WINAPI
#define THREAD_RETURN_VALUE 0
typedef DWORD (WINAPI *ThreadEntranceFunc)(LPVOID lpThreadParameter);
#else
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef OS_FREEBSD
//#include <sys/syscall.h>
#endif
/* Internet address (兼容IPv6长度). */
typedef uint64_t in_addr_64_t;
#define FILE_SEPERATOR "/"
typedef int SOCKET;
#define closesocket close
#define INVALID_SOCKET -1
#define THREAD_ENTRANCE_FUNC_DECLARE void *
typedef void *LPVOID;
#define THREAD_RETURN_VALUE NULL
typedef void * (*ThreadEntranceFunc)(LPVOID lpThreadParameter);
#endif
#ifndef WIN32
extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
#endif
#include "_os_define.h"
#ifdef OS_LINUX
#include <sys/prctl.h>
#endif
#ifdef OS_LINUX
#ifndef PTHREAD_MUTEX_ERRORCHECK
#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
#endif
#endif
#ifdef OS_BITS
#if OS_BITS == 64
#define INT64_PRINTF_FORMAT "%ld"
#else
#define INT64_PRINTF_FORMAT "%lld"
#endif
#else
#define INT64_PRINTF_FORMAT "%lld"
#endif
#ifdef OFF_BITS
#if OFF_BITS == 64
#define OFF_PRINTF_FORMAT INT64_PRINTF_FORMAT
#else
#define OFF_PRINTF_FORMAT "%d"
#endif
#else
#define OFF_PRINTF_FORMAT INT64_PRINTF_FORMAT
#endif
#ifndef WIN32
#define USE_SENDFILE
#endif
#define MAX_PATH_SIZE 256
#define LOG_FILE_DIR "logs"
#define CONF_FILE_DIR "conf"
#define DEFAULT_CONNECT_TIMEOUT 10
#define DEFAULT_NETWORK_TIMEOUT 30
#define DEFAULT_MAX_CONNECTONS 256
#define DEFAULT_WORK_THREADS 4
#define SYNC_LOG_BUFF_DEF_INTERVAL 10
#define TIME_NONE -1
#if defined(IOV_MAX) && IOV_MAX > 256
#define FC_IOV_BATCH_SIZE 256
#else
#define FC_IOV_BATCH_SIZE IOV_MAX
#endif
// 由于要支持IPv6所以将IP_ADDRESS_SIZE的值由16修改为46
#define IP_ADDRESS_SIZE INET6_ADDRSTRLEN //46
#define FORMATTED_IP_SIZE (IP_ADDRESS_SIZE + 2)
#define INFINITE_FILE_SIZE (256 * 1024LL * 1024 * 1024 * 1024 * 1024LL)
#define FILE_RESOURCE_TAG_STR "file://"
#define FILE_RESOURCE_TAG_LEN (sizeof(FILE_RESOURCE_TAG_STR) - 1)
#define IS_FILE_RESOURCE(filename) \
(strncasecmp(filename, FILE_RESOURCE_TAG_STR, \
FILE_RESOURCE_TAG_LEN) == 0)
#define IS_FILE_RESOURCE_EX(filename) \
((filename)->len >= FILE_RESOURCE_TAG_LEN && \
memcmp((filename)->str, FILE_RESOURCE_TAG_STR, \
FILE_RESOURCE_TAG_LEN) == 0)
#ifndef byte
#define byte signed char
#endif
#ifndef ubyte
#define ubyte unsigned char
#endif
#ifndef WIN32
#ifndef INADDR_NONE
#define INADDR_NONE ((in_addr_t) 0xffffffff)
#endif
#endif
#ifndef ECANCELED
#define ECANCELED 125
#endif
#ifndef ENODATA
#define ENODATA 61 /* No data available */
#endif
#ifndef ENONET
#define ENONET 64 /* Machine is not on the network */
#endif
#define compile_barrier() __asm__ __volatile__("" : : : "memory")
#define IS_UPPER_HEX(ch) ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F'))
#define IS_HEX_CHAR(ch) (IS_UPPER_HEX(ch) || (ch >= 'a' && ch <= 'f'))
#define FC_IS_DIGITAL(ch) (ch >= '0' && ch <= '9')
#define FC_IS_LETTER(ch) ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
#define FC_IS_UPPER_LETTER(ch) (ch >= 'A' && ch <= 'Z')
#define FC_IS_LOWER_LETTER(ch) (ch >= 'a' && ch <= 'z')
#define FC_MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
#define FC_MAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
#define FC_ABS(n) ((n) >= 0 ? (n) : -1 * (n))
#define FC_NEGATIVE(n) ((n) <= 0 ? (n) : -1 * (n))
#define FC_TIME_UNIT_SECOND 's' //second
#define FC_TIME_UNIT_MSECOND 'm' //millisecond
#define FC_TIME_UNIT_USECOND 'u' //microsecond
#define FC_TIME_UNIT_NSECOND 'n' //nanosecond
#define FC_1E01 10LL
#define FC_1E02 100LL
#define FC_1E03 1000LL
#define FC_1E04 10000LL
#define FC_1E05 100000LL
#define FC_1E06 1000000LL
#define FC_1E07 10000000LL
#define FC_1E08 100000000LL
#define FC_1E09 1000000000LL
#define FC_1E10 10000000000LL
#define FC_1E11 100000000000LL
#define FC_1E12 1000000000000LL
#define FC_1E13 10000000000000LL
#define FC_1E14 100000000000000LL
#define FC_1E15 1000000000000000LL
#define FC_1E16 10000000000000000LL
#define FC_1E17 100000000000000000LL
#define FC_1E18 1000000000000000000LL
#define STRERROR(no) (strerror(no) != NULL ? strerror(no) : "Unkown error")
#if defined(OS_LINUX)
#if defined __USE_MISC || defined __USE_XOPEN2K8
#define st_atimensec st_atim.tv_nsec
#define st_mtimensec st_mtim.tv_nsec
#define st_ctimensec st_ctim.tv_nsec
#endif
#elif defined(OS_FREEBSD)
#ifndef st_atimensec
#define st_atimensec st_atimespec.tv_nsec
#define st_mtimensec st_mtimespec.tv_nsec
#define st_ctimensec st_ctimespec.tv_nsec
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
byte hour;
byte minute;
byte second;
} TimeInfo;
typedef struct
{
char major;
char minor;
char patch;
} Version;
typedef struct
{
char **strs;
int count;
} str_ptr_array_t;
typedef struct
{
char *key;
char *value;
} KeyValuePair;
typedef struct
{
char *key;
char *value;
int key_len;
int value_len;
} KeyValuePairEx;
typedef struct
{
char *buff;
int alloc_size;
int length;
} BufferInfo;
typedef struct
{
char *str;
int len;
} string_t;
typedef struct
{
string_t *strings;
int count;
} string_array_t;
typedef struct
{
int64_t id;
string_t name;
} id_name_pair_t;
typedef struct
{
string_t key;
string_t value;
} key_value_pair_t;
typedef struct
{
key_value_pair_t *kv_pairs;
int count;
} key_value_array_t;
typedef struct
{
int32_t *elts;
int count;
} int32_array_t;
typedef struct
{
int64_t *elts;
int count;
} int64_array_t;
typedef struct
{
id_name_pair_t *elts;
int count;
} id_name_array_t;
typedef struct
{
void *elts;
int count;
} void_array_t;
typedef struct
{
pthread_mutex_t lock;
pthread_cond_t cond;
} pthread_lock_cond_pair_t;
typedef struct
{
int alloc;
int count;
struct iovec *iovs;
} iovec_array_t;
typedef struct
{
char buff[PATH_MAX];
string_t s;
} FilenameString;
typedef struct {
char *filename;
char *tmp_filename;
int fd;
} SafeWriteFileInfo;
typedef struct {
char filename[PATH_MAX];
int fd;
} FilenameFDPair;
typedef void (*FreeDataFunc)(void *ptr);
typedef int (*CompareFunc)(void *p1, void *p2);
typedef void* (*MallocFunc)(size_t size);
#define TO_UPPERCASE(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 32 : c)
#define MEM_ALIGN_FLOOR(x, align_size) ((x) & (~(align_size - 1)))
#define MEM_ALIGN_CEIL(x, align_size) \
(((x) + (align_size - 1)) & (~(align_size - 1)))
#define MEM_ALIGN(x) MEM_ALIGN_CEIL(x, 8)
#define MEM_ALIGN_FLOOR_BY_MASK(x, align_mask) ((x) & (~align_mask))
#define MEM_ALIGN_CEIL_BY_MASK(x, align_mask) \
(((x) + align_mask) & (~align_mask))
#define FC_INIT_CHAIN(chain) (chain).head = (chain).tail = NULL
#define FC_IS_CHAIN_EMPTY(chain) ((chain).head == NULL)
#define FC_SET_CHAIN_TAIL_NEXT(chain, type, ptr) \
((type *)(chain).tail)->next = ptr
#ifdef WIN32
#define strcasecmp _stricmp
#endif
#ifndef likely
#if defined(__GNUC__) && __GNUC__ >= 3
#define likely(cond) __builtin_expect ((cond), 1)
#define unlikely(cond) __builtin_expect ((cond), 0)
#else
#define likely(cond) (cond)
#define unlikely(cond) (cond)
#endif
#endif
#ifdef __GNUC__
#define __gcc_attribute__ __attribute__
#else
#define __gcc_attribute__(x)
#endif
#define FC_IS_CHINESE_UTF8_CHAR(p, end) \
((p + 2 < end) && \
((((unsigned char)*p) & 0xF0) == 0xE0) && \
((((unsigned char)*(p + 1)) & 0xC0) == 0x80) && \
((((unsigned char)*(p + 2)) & 0xC0) == 0x80))
//for printf format %.*s
#define FC_PRINTF_STAR_STRING_PARAMS(s) (s).len, (s).str
#define FC_SET_IOVEC(iovec, buff, len) \
do { \
(iovec).iov_base = buff; \
(iovec).iov_len = len; \
} while (0)
#define FC_SET_STRING(dest, src) \
do { \
(dest).str = src; \
(dest).len = strlen(src); \
} while (0)
#define FC_SET_STRING_EX(dest, s, l) \
do { \
(dest).str = s; \
(dest).len = l; \
} while (0)
#define FC_SET_STRING_EMPTY(dest, s) FC_SET_STRING_EX(dest, s, 0)
#define FC_SET_STRING_NULL(dest) \
do { \
(dest).str = NULL; \
(dest).len = 0; \
} while (0)
#define FC_IS_NULL_STRING(s) ((s)->str == NULL)
#define FC_IS_EMPTY_STRING(s) ((s)->len == 0)
#define FC_INIT_FILENAME_STRING(filename) \
FC_SET_STRING_EX((filename).s, (filename).buff, 0)
#define FC_FILENAME_STRING_OBJ(filename) ((filename).s)
#define FC_FILENAME_STRING_PTR(filename) ((filename).buff)
#define FC_FILENAME_BUFFER_SIZE(filename) sizeof((filename).buff)
#define fc_compare_string(s1, s2) fc_string_compare(s1, s2)
static inline int fc_string_compare(const string_t *s1, const string_t *s2)
{
int result;
if (s1->len == s2->len) {
return memcmp(s1->str, s2->str, s1->len);
} else if (s1->len < s2->len) {
result = memcmp(s1->str, s2->str, s1->len);
return result == 0 ? -1 : result;
} else {
result = memcmp(s1->str, s2->str, s2->len);
return result == 0 ? 1 : result;
}
}
static inline bool fc_string_equal(const string_t *s1, const string_t *s2)
{
return (s1->len == s2->len) && (memcmp(s1->str, s2->str, s1->len) == 0);
}
static inline bool fc_string_equal2(const string_t *s1,
const char *str2, const int len2)
{
return (s1->len == len2) && (memcmp(s1->str, str2, s1->len) == 0);
}
#define fc_string_equals(s1, s2) fc_string_equal(s1, s2)
#define fc_string_equals2(s1, str2, len2) fc_string_equal2(s1, str2, len2)
#define fc_case_compare_string(s1, s2) fc_string_case_compare(s1, s2)
static inline int fc_string_case_compare(const string_t *s1, const string_t *s2)
{
int result;
if (s1->len == s2->len) {
return strncasecmp(s1->str, s2->str, s1->len);
} else if (s1->len < s2->len) {
result = strncasecmp(s1->str, s2->str, s1->len);
return result == 0 ? -1 : result;
} else {
result = strncasecmp(s1->str, s2->str, s2->len);
return result == 0 ? 1 : result;
}
}
static inline bool fc_string_case_equal(const string_t *s1, const string_t *s2)
{
return (s1->len == s2->len) && (strncasecmp(s1->str, s2->str, s1->len) == 0);
}
static inline bool fc_string_case_equal2(const string_t *s1,
const char *str2, const int len2)
{
return (s1->len == len2) && (strncasecmp(s1->str, str2, s1->len) == 0);
}
#define fc_string_case_equals(s1, s2) fc_string_case_equal(s1, s2)
#define fc_string_case_equals2(s1, str2, len2) \
fc_string_case_equal2(s1, str2, len2)
static inline int fc_compare_int64(const int64_t n1, const int64_t n2)
{
int64_t sub;
sub = n1 - n2;
if (sub < 0) {
return -1;
} else if (sub > 0) {
return 1;
} else {
return 0;
}
}
#ifdef OS_LINUX
static inline int fc_fallocate(int fd, const int64_t size)
{
if (fallocate(fd, 0, 0, size) < 0) {
if (errno == EOPNOTSUPP) {
return ftruncate(fd, size);
}
return -1;
}
return 0;
}
#else
#define fc_fallocate(fd, size) ftruncate(fd, size)
#define posix_fadvise(fd, offset, len, advice) 0
#ifndef POSIX_FADV_NORMAL
#define POSIX_FADV_NORMAL 0 /* No further special treatment. */
#define POSIX_FADV_RANDOM 1 /* Expect random page references. */
#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */
#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */
#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */
#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
#ifdef OS_FREEBSD
//#define fdatasync(fd) syscall(SYS_fdatasync, fd)
#define fdatasync(fd) fsync(fd)
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif