/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: swapi.h
 * DESCRIPTION:
 *  "SWAPI" library standard header file
 * SUPPORT PLATFORM: Linux
 * HISTORY:
 * 1, [2010-07-01] created by NiuJiuRu
 * 2, [2013-04-23] modified by NiuJiuRu, add "likely(x)" and "unlikely(x)"
                   macro definition for linux platform
 * 3, [2025-01-07] review for linux
 ************************************************************************/
#ifndef __SWAPI_H__
#define __SWAPI_H__

//////////////////////////////////////////////////////////////////////////
// 1, Select platform

// linux platform
#if (defined __linux || defined __linux__) && !defined LINUX
#define LINUX
#endif

// error, invalid platform
#if !defined LINUX
#error "SWAPI Library" currently not support this platform
#endif

//////////////////////////////////////////////////////////////////////////
// 2, C language common header files

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <stdbool.h>
#include <inttypes.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#include <wchar.h>
#include <limits.h>
#include <locale.h>
#include <assert.h>
#include <errno.h>

//////////////////////////////////////////////////////////////////////////
// 3, For "Linux" platform

#ifdef LINUX

// include "Linux" common header files
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <getopt.h>
#include <termios.h>
#include <netdb.h>
#include <dirent.h>
#include <arpa/inet.h>

#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ether.h>

#include <net/if.h>
#include <net/if_arp.h>

#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/reboot.h>

#include <libgen.h>

// define "Linux" common macros
#define MAKEWORD(a, b)      ((uint16_t)(((uint8_t)(a)) | ((uint16_t)((uint8_t)(b))) << 8))
#define MAKEDWORD(a, b)     ((uint32_t)(((uint16_t)(a)) | ((uint32_t)((uint16_t)(b))) << 16))
#define MAKEQWORD(a, b)     ((uint64_t)(((uint32_t)(a)) | ((uint64_t)((uint32_t)(b))) << 32))
#define LODWORD(q)          ((uint32_t)(q))
#define HIDWORD(q)          ((uint32_t)(((uint64_t)(q) >> 32) & 0xFFFFFFFF))
#define LOWORD(d)           ((uint16_t)(d))
#define HIWORD(d)           ((uint16_t)(((uint32_t)(d) >> 16) & 0xFFFF))
#define LOBYTE(w)           ((uint8_t)(w))
#define HIBYTE(w)           ((uint8_t)(((uint16_t)(w) >> 8) & 0xFF))

// IP address is the multicast address ?
#define IS_MULTICAST_IP(ip) (0xE0 <= ((ip)&0xFF) && ((ip)&0xFF) < 0xF0)

// controls the I/O mode of a socket
#ifndef ioctlsocket
#define ioctlsocket ioctl
#endif

// closes an existing socket
#ifndef closesocket
#define closesocket close
#endif

// somewhere in the middle of the GCC 2.96 development cycle, we implemented
// a mechanism by which the user can annotate likely branch directions and
// expect the blocks to be reordered appropriately. Define __builtin_expect
// to nothing for earlier compilers
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
#endif

#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#endif

#ifndef unlikely
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif

#endif

//////////////////////////////////////////////////////////////////////////
// 4, Define common macros

#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

#ifndef MAX_PATH_CHARS
#define MAX_PATH_CHARS 260
#endif

#ifndef MAX_LINE_CHARS
#define MAX_LINE_CHARS 192
#endif

#ifndef __cplusplus

#ifndef bool
#define bool unsigned char
#endif

#ifndef true
#define true 1
#endif

#ifndef false
#define false 0
#endif

#endif

#ifndef BOOL
#define BOOL int
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

#ifndef null
#define null NULL
#endif

#ifndef HANDLE
#define HANDLE void *
#endif

#ifndef SOCKET
#define SOCKET int
#endif

#ifndef INVALID_SOCKET
#define INVALID_SOCKET (SOCKET)(~0)
#endif

#ifndef SOCKET_ERROR
#define SOCKET_ERROR -1
#endif

#ifndef ERROR
#define ERROR -1
#endif

#ifndef INFINITE
#define INFINITE 0xFFFFFFFF
#endif

#ifndef WAIT_FOREVER
#define WAIT_FOREVER INFINITE
#endif

//////////////////////////////////////////////////////////////////////////
// 5, Show memory allocation situation detailed when you need
#ifndef _MEM_DEBUG_DETAIL
//#define _MEM_DEBUG_DETAIL
#endif

//////////////////////////////////////////////////////////////////////////
// 6, Program logs
#include "swlog.h"

//////////////////////////////////////////////////////////////////////////
// 7, Define common data types and macro
// 等待线程状态切换完成的延时时间, 单位: 毫秒
#define THRDWAIT_DELAY 10

// 等待线程安全退出的超时, 单位: 毫秒
#define WAITTHRD_SAFEEXIT_TIMEOUT 3000

// IPv4字符串最大长度(包含'\0'结尾符, 例如: xxx.xxx.xxx.xxx)
#define MAX_IPV4STR_CHARS (15+1)

// 日期时间字符串长度, 包含'\0'结尾符
#define MAX_TIMESTR_CHARS (19+1)

#endif /* __SWAPI_H__ */
