Init Repo

This commit is contained in:
root
2019-09-06 23:53:10 +08:00
commit f0ef89dfbb
7905 changed files with 914138 additions and 0 deletions

207
vendor/swoole/include/Client.h vendored Executable file
View File

@ -0,0 +1,207 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_CLIENT_H_
#define SW_CLIENT_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "buffer.h"
#include "Connection.h"
#define SW_SOCK_ASYNC 1
#define SW_SOCK_SYNC 0
#define SW_HTTPS_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established"
enum swClient_pipe_flag
{
SW_CLIENT_PIPE_TCP_SESSION = 1,
};
enum swHttp_proxy_state
{
SW_HTTP_PROXY_STATE_WAIT = 0,
SW_HTTP_PROXY_STATE_HANDSHAKE,
SW_HTTP_PROXY_STATE_READY,
};
struct _http_proxy
{
uint8_t state;
int proxy_port;
char *proxy_host;
char *user;
char *password;
int l_user;
int l_password;
char *target_host;
int target_port;
char buf[600];
};
typedef struct _swClient
{
int id;
int type;
long timeout_id; //timeout node id
int _sock_type;
int _sock_domain;
int _protocol;
int reactor_fdtype;
int _redirect_to_file;
int _redirect_to_socket;
int _redirect_to_session;
uint32_t async :1;
uint32_t keep :1;
uint32_t released :1;
uint32_t destroyed :1;
uint32_t redirect :1;
uint32_t http2 :1;
uint32_t sleep :1;
uint32_t wait_dns :1;
uint32_t shutdow_rw :1;
uint32_t shutdown_read :1;
uint32_t shutdown_write :1;
uint32_t remove_delay :1;
/**
* one package: length check
*/
uint32_t open_length_check :1;
uint32_t open_eof_check :1;
swProtocol protocol;
struct _swSocks5 *socks5_proxy;
struct _http_proxy* http_proxy;
uint32_t reuse_count;
char *server_str;
char *server_host;
int server_port;
void *ptr;
void *params;
uint8_t server_strlen;
double timeout;
swTimer_node *timer;
/**
* signal interruption
*/
double interrupt_time;
/**
* sendto, read only.
*/
swSocketAddress server_addr;
/**
* recvfrom
*/
swSocketAddress remote_addr;
swConnection *socket;
/**
* reactor
*/
swReactor *reactor;
void *object;
swString *buffer;
uint32_t wait_length;
uint32_t buffer_input_size;
uint32_t buffer_high_watermark;
uint32_t buffer_low_watermark;
#ifdef SW_USE_OPENSSL
uint8_t open_ssl :1;
uint8_t ssl_wait_handshake :1;
SSL_CTX *ssl_context;
swSSL_option ssl_option;
#endif
void (*onConnect)(struct _swClient *cli);
void (*onError)(struct _swClient *cli);
void (*onReceive)(struct _swClient *cli, char *data, uint32_t length);
void (*onClose)(struct _swClient *cli);
void (*onBufferFull)(struct _swClient *cli);
void (*onBufferEmpty)(struct _swClient *cli);
int (*connect)(struct _swClient *cli, char *host, int port, double _timeout, int sock_flag);
int (*send)(struct _swClient *cli, char *data, int length, int flags);
int (*sendfile)(struct _swClient *cli, char *filename, off_t offset, size_t length);
int (*recv)(struct _swClient *cli, char *data, int len, int flags);
int (*pipe)(struct _swClient *cli, int write_fd, int is_session_id);
int (*close)(struct _swClient *cli);
} swClient;
int swClient_create(swClient *cli, int type, int async);
int swClient_sleep(swClient *cli);
int swClient_wakeup(swClient *cli);
int swClient_shutdown(swClient *cli, int __how);
#ifdef SW_USE_OPENSSL
int swClient_enable_ssl_encrypt(swClient *cli);
int swClient_ssl_handshake(swClient *cli);
int swClient_ssl_verify(swClient *cli, int allow_self_signed);
#endif
void swClient_free(swClient *cli);
typedef struct
{
uint8_t num;
struct
{
uint8_t length;
char address[16];
} hosts[SW_DNS_HOST_BUFFER_SIZE];
} swDNSResolver_result;
int swDNSResolver_request(char *domain, void (*callback)(char *, swDNSResolver_result *, void *), void *data);
int swDNSResolver_free();
//----------------------------------------Stream---------------------------------------
typedef struct _swStream
{
swString *buffer;
uint32_t session_id;
uint8_t cancel;
void (*response)(struct _swStream *stream, char *data, uint32_t length);
swClient client;
} swStream;
swStream* swStream_new(char *dst_host, int dst_port, int type);
int swStream_send(swStream *stream, char *data, size_t length);
void swStream_set_protocol(swProtocol *protocol);
void swStream_set_max_length(swStream *stream, uint32_t max_length);
int swStream_recv_blocking(int fd, void *__buf, size_t __len);
//----------------------------------------Stream End------------------------------------
#ifdef __cplusplus
}
#endif
#endif /* SW_CLIENT_H_ */

260
vendor/swoole/include/Connection.h vendored Executable file
View File

@ -0,0 +1,260 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_CONNECTION_H_
#define SW_CONNECTION_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "buffer.h"
#ifdef SW_USE_OPENSSL
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#define SW_SSL_BUFFER 1
#define SW_SSL_CLIENT 2
typedef struct _swSSL_option
{
char *cert_file;
char *key_file;
char *passphrase;
char *client_cert_file;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
char *tls_host_name;
#endif
char *cafile;
char *capath;
uint8_t verify_depth;
uint8_t method;
uint8_t disable_compress :1;
uint8_t verify_peer :1;
uint8_t allow_self_signed :1;
} swSSL_option;
#endif
int swConnection_buffer_send(swConnection *conn);
swString* swConnection_get_string_buffer(swConnection *conn);
void swConnection_clear_string_buffer(swConnection *conn);
swBuffer_trunk* swConnection_get_out_buffer(swConnection *conn, uint32_t type);
swBuffer_trunk* swConnection_get_in_buffer(swConnection *conn);
int swConnection_sendfile(swConnection *conn, char *filename, off_t offset, size_t length);
int swConnection_onSendfile(swConnection *conn, swBuffer_trunk *chunk);
void swConnection_sendfile_destructor(swBuffer_trunk *chunk);
char* swConnection_get_ip(swConnection *conn);
int swConnection_get_port(swConnection *conn);
#ifdef SW_USE_OPENSSL
enum swSSLState
{
SW_SSL_STATE_HANDSHAKE = 0,
SW_SSL_STATE_READY = 1,
SW_SSL_STATE_WAIT_STREAM = 2,
};
enum swSSLMethod
{
SW_SSLv23_METHOD = 0,
SW_SSLv3_METHOD,
SW_SSLv3_SERVER_METHOD,
SW_SSLv3_CLIENT_METHOD,
SW_SSLv23_SERVER_METHOD,
SW_SSLv23_CLIENT_METHOD,
SW_TLSv1_METHOD,
SW_TLSv1_SERVER_METHOD,
SW_TLSv1_CLIENT_METHOD,
#ifdef TLS1_1_VERSION
SW_TLSv1_1_METHOD,
SW_TLSv1_1_SERVER_METHOD,
SW_TLSv1_1_CLIENT_METHOD,
#endif
#ifdef TLS1_2_VERSION
SW_TLSv1_2_METHOD,
SW_TLSv1_2_SERVER_METHOD,
SW_TLSv1_2_CLIENT_METHOD,
#endif
SW_DTLSv1_METHOD,
SW_DTLSv1_SERVER_METHOD,
SW_DTLSv1_CLIENT_METHOD,
};
typedef struct
{
uint32_t http :1;
uint32_t http_v2 :1;
uint32_t prefer_server_ciphers :1;
uint32_t session_tickets :1;
uint32_t stapling :1;
uint32_t stapling_verify :1;
char *ciphers;
char *ecdh_curve;
char *session_cache;
char *dhparam;
} swSSL_config;
void swSSL_init(void);
void swSSL_init_thread_safety();
int swSSL_server_set_cipher(SSL_CTX* ssl_context, swSSL_config *cfg);
void swSSL_server_http_advise(SSL_CTX* ssl_context, swSSL_config *cfg);
SSL_CTX* swSSL_get_context(swSSL_option *option);
void swSSL_free_context(SSL_CTX* ssl_context);
int swSSL_create(swConnection *conn, SSL_CTX* ssl_context, int flags);
int swSSL_set_client_certificate(SSL_CTX *ctx, char *cert_file, int depth);
int swSSL_set_capath(swSSL_option *cfg, SSL_CTX *ctx);
int swSSL_check_host(swConnection *conn, char *tls_host_name);
int swSSL_get_client_certificate(SSL *ssl, char *buffer, size_t length);
int swSSL_verify(swConnection *conn, int allow_self_signed);
int swSSL_accept(swConnection *conn);
int swSSL_connect(swConnection *conn);
void swSSL_close(swConnection *conn);
ssize_t swSSL_recv(swConnection *conn, void *__buf, size_t __n);
ssize_t swSSL_send(swConnection *conn, void *__buf, size_t __n);
int swSSL_sendfile(swConnection *conn, int fd, off_t *offset, size_t size);
#endif
/**
* Receive data from connection
*/
static sw_inline ssize_t swConnection_recv(swConnection *conn, void *__buf, size_t __n, int __flags)
{
int retval;
#ifdef SW_USE_OPENSSL
if (conn->ssl)
{
int ret = 0;
int n_received = 0;
while (n_received < __n)
{
ret = swSSL_recv(conn, ((char*)__buf) + n_received, __n - n_received);
if (__flags & MSG_WAITALL)
{
if (ret <= 0)
{
retval = ret;
goto _return;
}
else
{
n_received += ret;
}
}
else
{
retval = ret;
goto _return;
}
}
retval = n_received;
}
else
{
retval = recv(conn->fd, __buf, __n, __flags);
}
#else
retval = recv(conn->fd, __buf, __n, __flags);
#endif
#ifdef SW_USE_OPENSSL
_return:
#endif
#ifdef SW_DEBUG
if (retval > 0)
{
conn->total_recv_bytes += retval;
}
#endif
return retval;
}
/**
* Send data to connection
*/
static sw_inline int swConnection_send(swConnection *conn, void *__buf, size_t __n, int __flags)
{
int retval;
#ifdef SW_USE_OPENSSL
if (conn->ssl)
{
retval = swSSL_send(conn, __buf, __n);
}
else
{
retval = send(conn->fd, __buf, __n, __flags);
}
#else
retval = send(conn->fd, __buf, __n, __flags);
#endif
#ifdef SW_DEBUG
if (retval > 0)
{
conn->total_send_bytes += retval;
}
#endif
return retval;
}
static sw_inline int swConnection_error(int err)
{
switch (err)
{
case EFAULT:
abort();
return SW_ERROR;
case EBADF:
case ECONNRESET:
#ifdef __CYGWIN__
case ECONNABORTED:
#endif
case EPIPE:
case ENOTCONN:
case ETIMEDOUT:
case ECONNREFUSED:
case ENETDOWN:
case ENETUNREACH:
case EHOSTDOWN:
case EHOSTUNREACH:
case SW_ERROR_SSL_BAD_CLIENT:
return SW_CLOSE;
case EAGAIN:
#ifdef HAVE_KQUEUE
case ENOBUFS:
#endif
case 0:
return SW_WAIT;
default:
return SW_ERROR;
}
}
#ifdef __cplusplus
}
#endif
#endif /* SW_CONNECTION_H_ */

1
vendor/swoole/include/ReadMe vendored Executable file
View File

@ -0,0 +1 @@
Swoole used Troy D. Hanson's Uhash and Ulist.

73
vendor/swoole/include/RingQueue.h vendored Executable file
View File

@ -0,0 +1,73 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _SW_RINGQUEUE_H_
#define _SW_RINGQUEUE_H_
#ifdef SW_USE_RINGQUEUE_TS
#include "atomic.h"
typedef struct _swRingQueue
{
void **data;
char *flags;
// 0push ready 1: push now
// 2pop ready; 3: pop now
uint size;
uint num;
uint head;
uint tail;
} swRingQueue;
int swRingQueue_init(swRingQueue *, int buffer_size);
#define swRingQueue_count(q) (q->num)
int swRingQueue_push(swRingQueue *, void *);
int swRingQueue_pop(swRingQueue *, void **);
#else
typedef struct _swRingQueue
{
int head; /* 头部,出队列方向*/
int tail; /* 尾部,入队列方向*/
int tag; /* 为空还是为满的标志位*/
int size; /* 队列总尺寸 */
void **data; /* 队列空间 */
} swRingQueue;
int swRingQueue_init(swRingQueue *queue, int buffer_size);
int swRingQueue_push(swRingQueue *queue, void *);
int swRingQueue_pop(swRingQueue *queue, void **);
void swRingQueue_free(swRingQueue *queue);
static inline int swRingQueue_count(swRingQueue *queue)
{
if (queue->tail > queue->head)
{
return queue->tail - queue->head;
}
else if (queue->head == queue->tail)
{
return queue->tag == 1 ? queue->size : 0;
}
else
{
return queue->tail + queue->size - queue->head;
}
}
#define swRingQueue_empty(q) ( (q->head == q->tail) && (q->tag == 0))
#define swRingQueue_full(q) ( (q->head == q->tail) && (q->tag == 1))
#endif
#endif

1066
vendor/swoole/include/Server.h vendored Executable file

File diff suppressed because it is too large Load Diff

63
vendor/swoole/include/array.h vendored Executable file
View File

@ -0,0 +1,63 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _SW_ARRAY_H_
#define _SW_ARRAY_H_
/**
* 默认swArray->pages指针数组的长度为SW_ARRAY_PAGE_MAX,也就是最多可以管理(SW_ARRAY_PAGE_MAX*page_size)个元素
*/
#define SW_ARRAY_PAGE_MAX 1024
typedef struct _swArray
{
void **pages;
/**
* 页的数量
*/
uint16_t page_num;
/**
* 每页的数据元素个数
*/
uint16_t page_size;
/**
* 数据元素的尺寸
*/
uint32_t item_size;
/**
* 数据个数
*/
uint32_t item_num;
uint32_t offset;
} swArray;
#define swArray_page(array, n) ((n) / (array)->page_size)
#define swArray_offset(array, n) ((n) % (array)->page_size)
swArray *swArray_new(int page_size, size_t item_size);
void swArray_free(swArray *array);
void *swArray_fetch(swArray *array, uint32_t n);
int swArray_store(swArray *array, uint32_t n, void *data);
void *swArray_alloc(swArray *array, uint32_t n);
int swArray_append(swArray *array, void *data);
int swArray_extend(swArray *array);
void swArray_clear(swArray *array);
#endif /* _SW_ARRAY_H_ */

44
vendor/swoole/include/asm_context.h vendored Executable file
View File

@ -0,0 +1,44 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2018 The Swoole Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _SW_ASM_CONTEXT_H_
#define _SW_ASM_CONTEXT_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#ifndef SW_NO_USE_ASM_CONTEXT
typedef void* fcontext_t;
intptr_t jump_fcontext(fcontext_t *ofc, fcontext_t nfc, intptr_t vp, bool preserve_fpu = false);
fcontext_t make_fcontext(void *sp, size_t size, void (*fn)(intptr_t));
#endif
#ifdef __cplusplus
}
#endif
#endif

95
vendor/swoole/include/async.h vendored Executable file
View File

@ -0,0 +1,95 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2018 The Swoole Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _SW_ASYNC_H_
#define _SW_ASYNC_H_
#ifndef O_DIRECT
#define O_DIRECT 040000
#endif
enum swAioOpcode
{
SW_AIO_READ = 0,
SW_AIO_WRITE = 1,
SW_AIO_GETHOSTBYNAME = 2,
SW_AIO_GETADDRINFO = 3,
SW_AIO_STREAM_GET_LINE = 4,
SW_AIO_READ_FILE,
SW_AIO_WRITE_FILE,
};
enum swAioFlag
{
SW_AIO_WRITE_FSYNC = 1u << 1,
SW_AIO_EOF = 1u << 2,
};
typedef struct _swAio_event
{
int fd;
int task_id;
uint8_t type;
uint16_t flags;
off_t offset;
size_t nbytes;
void *buf;
void *req;
int ret;
int error;
void *object;
void (*callback)(struct _swAio_event *event);
} swAio_event;
typedef void (*swAio_handler)(swAio_event *event);
typedef struct
{
uint8_t init;
uint8_t thread_num;
uint32_t task_num;
uint16_t current_id;
swLock lock;
swAio_handler handlers[SW_AIO_HANDLER_MAX_SIZE];
void (*destroy)(void);
void (*callback)(swAio_event *aio_event);
int (*read)(int fd, void *outbuf, size_t size, off_t offset);
int (*write)(int fd, void *inbuf, size_t size, off_t offset);
} swAsyncIO;
extern swAsyncIO SwooleAIO;
extern swPipe swoole_aio_pipe;
void swAio_callback_test(swAio_event *aio_event);
int swAio_init(void);
void swAio_free(void);
int swAioBase_init(int max_aio_events);
int swAio_dns_lookup(void *hostname, void *ip_addr, size_t size);
int swAio_dispatch(swAio_event *_event);
#ifdef HAVE_GCC_AIO
int swAioGcc_init(int max_aio_events);
#endif
#ifdef HAVE_LINUX_AIO
#define SW_AIO_MIN_UNIT_SIZE 512
int swAioLinux_init(int max_aio_events);
#endif
#endif /* _SW_ASYNC_H_ */

43
vendor/swoole/include/atomic.h vendored Executable file
View File

@ -0,0 +1,43 @@
#ifndef SW_ATOMIC_H_
#define SW_ATOMIC_H_
typedef volatile int32_t sw_atomic_int32_t;
typedef volatile uint32_t sw_atomic_uint32_t;
#ifdef __x86_64__
typedef volatile int64_t sw_atomic_int64_t;
typedef volatile uint64_t sw_atomic_uint64_t;
#endif
#ifdef __x86_64__
typedef sw_atomic_int64_t sw_atomic_long_t;
typedef sw_atomic_uint64_t sw_atomic_ulong_t;
#else
typedef sw_atomic_int32_t sw_atomic_long_t;
typedef sw_atomic_uint32_t sw_atomic_ulong_t;
#endif
typedef sw_atomic_uint32_t sw_atomic_t;
#define sw_atomic_cmp_set(lock, old, set) __sync_bool_compare_and_swap(lock, old, set)
#define sw_atomic_fetch_add(value, add) __sync_fetch_and_add(value, add)
#define sw_atomic_fetch_sub(value, sub) __sync_fetch_and_sub(value, sub)
#define sw_atomic_memory_barrier() __sync_synchronize()
#define sw_atomic_add_fetch(value, add) __sync_add_and_fetch(value, add)
#define sw_atomic_sub_fetch(value, sub) __sync_sub_and_fetch(value, sub)
#ifdef __arm__
#define sw_atomic_cpu_pause() __asm__ __volatile__ ("NOP");
#elif defined(__x86_64__)
#define sw_atomic_cpu_pause() __asm__ __volatile__ ("pause")
#else
#define sw_atomic_cpu_pause()
#endif
#if 0
#define sw_spinlock_release(lock) __sync_lock_release(lock)
#else
#define sw_spinlock_release(lock) *(lock) = 0
#endif
#endif

31
vendor/swoole/include/base64.h vendored Executable file
View File

@ -0,0 +1,31 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_BASE64_H__
#define SW_BASE64_H__
enum
{
BASE64_OK = 0, BASE64_INVALID
};
#define BASE64_ENCODE_OUT_SIZE(s) (((s) + 2) / 3 * 4)
#define BASE64_DECODE_OUT_SIZE(s) (((s)) / 4 * 3)
int swBase64_encode(unsigned char *in, int inlen, char *out);
int swBase64_decode(char *in, int inlen, unsigned char *out);
#endif /* SW_BASE64_H__ */

76
vendor/swoole/include/buffer.h vendored Executable file
View File

@ -0,0 +1,76 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_BUFFER_H_
#define SW_BUFFER_H_
#ifdef __cplusplus
extern "C"
{
#endif
enum swBufferChunk
{
SW_CHUNK_DATA,
SW_CHUNK_SENDFILE,
SW_CHUNK_CLOSE,
};
typedef struct _swBuffer_trunk
{
uint32_t type;
uint32_t length;
uint32_t offset;
union
{
void *ptr;
struct
{
uint32_t val1;
uint32_t val2;
} data;
} store;
uint32_t size;
void (*destroy)(struct _swBuffer_trunk *chunk);
struct _swBuffer_trunk *next;
} swBuffer_trunk;
typedef struct _swBuffer
{
int fd;
uint8_t trunk_num; //trunk数量
uint16_t trunk_size;
uint32_t length;
swBuffer_trunk *head;
swBuffer_trunk *tail;
} swBuffer;
#define swBuffer_get_trunk(buffer) (buffer->head)
#define swBuffer_empty(buffer) (buffer == NULL || buffer->head == NULL)
swBuffer* swBuffer_new(int trunk_size);
swBuffer_trunk *swBuffer_new_trunk(swBuffer *buffer, uint32_t type, uint32_t size);
void swBuffer_pop_trunk(swBuffer *buffer, swBuffer_trunk *trunk);
int swBuffer_append(swBuffer *buffer, void *data, uint32_t size);
void swBuffer_debug(swBuffer *buffer, int print_data);
int swBuffer_free(swBuffer *buffer);
#ifdef __cplusplus
}
#endif
#endif /* SW_BUFFER_H_ */

109
vendor/swoole/include/context.h vendored Executable file
View File

@ -0,0 +1,109 @@
#pragma once
#ifdef SW_NO_USE_ASM_CONTEXT
#ifdef HAVE_BOOST_CONTEXT
#define USE_BOOST_CONTEXT 1
#include <boost/context/all.hpp>
#else
#define USE_UCONTEXT 1
#include <ucontext.h>
#endif
#else
#include "asm_context.h"
#endif
#ifdef HAVE_VALGRIND
#define USE_VALGRIND 0
#endif
#include "swoole.h"
#include "coroutine.h"
#include "error.h"
#if __linux__
#include <sys/mman.h>
#endif
#ifdef USE_VALGRIND
#include <valgrind/valgrind.h>
#endif
namespace swoole
{
//namespace start
static uint32_t& get_protect_stack_page()
{
static uint32_t protect_stack_page = 0;
return protect_stack_page;
}
static bool protect_stack(void *top, size_t stack_size, uint32_t page)
{
if (stack_size <= SwooleG.pagesize * (page + 1))
{
swoole_error_log(SW_LOG_ERROR, SW_ERROR_CO_PROTECT_STACK_FAILED, "getpagesize() failed.");
return false;
}
void *protect_page_addr = ((size_t) top & 0xfff) ? (void*) (((size_t) top & ~(size_t) 0xfff) + 0x1000) : top;
if (-1 == mprotect(protect_page_addr, SwooleG.pagesize * page, PROT_NONE))
{
swSysError("mprotect() failed: origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top,
protect_page_addr, SwooleG.pagesize, page);
return false;
}
else
{
swDebug("origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u", top, protect_page_addr, page, SwooleG.pagesize);
return true;
}
}
static bool unprotect_stack(void *top, uint32_t page)
{
void *protect_page_addr = ((size_t) top & 0xfff) ? (void*) (((size_t) top & ~(size_t) 0xfff) + 0x1000) : top;
if (-1 == mprotect(protect_page_addr, SwooleG.pagesize * page, PROT_READ | PROT_WRITE))
{
swSysError("mprotect() failed: origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top,
protect_page_addr, SwooleG.pagesize, page);
return false;
}
else
{
swDebug("origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top, protect_page_addr, page, SwooleG.pagesize);
return true;
}
}
class Context
{
public:
Context(size_t stack_size, coroutine_func_t fn, void* private_data);
~Context();
bool SwapIn();
bool SwapOut();
static void context_func(void* arg);
public:
bool end;
private:
#ifdef USE_BOOST_CONTEXT
boost::context::fcontext_t ctx_;
boost::context::fcontext_t swap_ctx_;
#elif USE_UCONTEXT
ucontext_t swap_ctx_;
ucontext_t ctx_;
#else
fcontext_t ctx_;
fcontext_t swap_ctx_;
#endif
coroutine_func_t fn_;
char* stack_;
uint32_t stack_size_;
uint32_t protect_page_;
#ifdef USE_VALGRIND
uint32_t valgrind_stack_id;
#endif
void *private_data_;
};
//namespace end
}

42
vendor/swoole/include/coroutine.h vendored Executable file
View File

@ -0,0 +1,42 @@
#ifndef SW_COROUTINE_H_
#define SW_COROUTINE_H_
#include "swoole.h"
#ifdef __cplusplus
extern "C"
{
#endif
void coro_yield();
void coro_handle_timeout();
#define DEFAULT_MAX_CORO_NUM 3000
#define DEFAULT_STACK_SIZE 8192
#define MAX_CORO_NUM_LIMIT 0x80000
#define CORO_END 0
#define CORO_YIELD 1
#define CORO_LIMIT -1
#define CORO_SAVE 3
typedef struct coroutine_s coroutine_t;
typedef void (*coroutine_func_t)(void*);
typedef void (*coroutine_close_t)();
typedef enum
{
SW_CORO_YIELD = 0, SW_CORO_SUSPENDED, SW_CORO_RUNNING, SW_CORO_END,
} sw_coro_state;
int coroutine_create(coroutine_func_t func, void* args);
void coroutine_resume(coroutine_t *co);
void coroutine_yield(coroutine_t *co);
void coroutine_release(coroutine_t *co);
coroutine_t *coroutine_get_by_id(int cid);
int coroutine_get_cid();
void coroutine_set_close(coroutine_close_t func);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif

133
vendor/swoole/include/error.h vendored Executable file
View File

@ -0,0 +1,133 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_ERRNO_H_
#define SW_ERRNO_H_
enum swErrorCode
{
/**
* common error
*/
SW_ERROR_MALLOC_FAIL = 501,
SW_ERROR_SYSTEM_CALL_FAIL,
SW_ERROR_PHP_FATAL_ERROR,
SW_ERROR_NAME_TOO_LONG,
SW_ERROR_INVALID_PARAMS,
SW_ERROR_QUEUE_FULL,
SW_ERROR_FILE_NOT_EXIST = 700,
SW_ERROR_FILE_TOO_LARGE,
SW_ERROR_FILE_EMPTY,
SW_ERROR_DNSLOOKUP_DUPLICATE_REQUEST,
SW_ERROR_DNSLOOKUP_RESOLVE_FAILED,
SW_ERROR_BAD_IPV6_ADDRESS,
/**
* connection error
*/
SW_ERROR_SESSION_CLOSED_BY_SERVER = 1001,
SW_ERROR_SESSION_CLOSED_BY_CLIENT,
SW_ERROR_SESSION_CLOSING,
SW_ERROR_SESSION_CLOSED,
SW_ERROR_SESSION_NOT_EXIST,
SW_ERROR_SESSION_INVALID_ID,
SW_ERROR_SESSION_DISCARD_TIMEOUT_DATA,
SW_ERROR_OUTPUT_BUFFER_OVERFLOW,
SW_ERROR_SSL_NOT_READY,
SW_ERROR_SSL_CANNOT_USE_SENFILE,
SW_ERROR_SSL_EMPTY_PEER_CERTIFICATE,
SW_ERROR_SSL_VEFIRY_FAILED,
SW_ERROR_SSL_BAD_CLIENT,
SW_ERROR_SSL_BAD_PROTOCOL,
SW_ERROR_PACKAGE_LENGTH_TOO_LARGE = 1201,
SW_ERROR_DATA_LENGTH_TOO_LARGE,
/**
* task error
*/
SW_ERROR_TASK_PACKAGE_TOO_BIG = 2001,
SW_ERROR_TASK_DISPATCH_FAIL,
/**
* http2 protocol error
*/
SW_ERROR_HTTP2_STREAM_ID_TOO_BIG = 3001,
SW_ERROR_HTTP2_STREAM_NO_HEADER,
/**
* AIO
*/
SW_ERROR_AIO_BAD_REQUEST = 4001,
/**
* Client
*/
SW_ERROR_CLIENT_NO_CONNECTION = 5001,
SW_ERROR_SOCKS5_UNSUPPORT_VERSION = 7001,
SW_ERROR_SOCKS5_UNSUPPORT_METHOD,
SW_ERROR_SOCKS5_AUTH_FAILED,
SW_ERROR_SOCKS5_SERVER_ERROR,
SW_ERROR_HTTP_PROXY_HANDSHAKE_ERROR = 8001,
SW_ERROR_HTTP_INVALID_PROTOCOL,
SW_ERROR_WEBSOCKET_BAD_CLIENT = 8501,
SW_ERROR_WEBSOCKET_BAD_OPCODE,
SW_ERROR_WEBSOCKET_UNCONNECTED,
SW_ERROR_WEBSOCKET_HANDSHAKE_FAILED,
/**
* server global error
*/
SW_ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT = 9001,
SW_ERROR_SERVER_TOO_MANY_SOCKET,
SW_ERROR_SERVER_WORKER_TERMINATED,
SW_ERROR_SERVER_INVALID_LISTEN_PORT,
SW_ERROR_SERVER_TOO_MANY_LISTEN_PORT,
SW_ERROR_SERVER_PIPE_BUFFER_FULL,
SW_ERROR_SERVER_NO_IDLE_WORKER,
SW_ERROR_SERVER_ONLY_START_ONE,
/**
* Process exit timeout, forced to end.
*/
SW_ERROR_SERVER_WORKER_EXIT_TIMEOUT,
/**
* Coroutine
*/
SW_ERROR_CO_MUTEX_DOUBLE_UNLOCK = 10001,
SW_ERROR_CO_BLOCK_OBJECT_LOCKED,
SW_ERROR_CO_BLOCK_OBJECT_WAITING,
SW_ERROR_CO_YIELD_FAILED,
SW_ERROR_CO_GETCONTEXT_FAILED,
SW_ERROR_CO_SWAPCONTEXT_FAILED,
SW_ERROR_CO_MAKECONTEXT_FAILED,
SW_ERROR_CO_IOCPINIT_FAILED,
SW_ERROR_CO_PROTECT_STACK_FAILED,
SW_ERROR_CO_STD_THREAD_LINK_ERROR,
SW_ERROR_CO_DISABLED_MULTI_THREAD,
};
void swoole_throw_error(enum swErrorCode code);
#endif /* SW_ERRNO_H_ */

218
vendor/swoole/include/hash.h vendored Executable file
View File

@ -0,0 +1,218 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_HASH_H_
#define SW_HASH_H_
#include <stdint.h>
#define HASH_JEN_MIX(a,b,c) \
do { \
a -= b; a -= c; a ^= ( c >> 13 ); \
b -= c; b -= a; b ^= ( a << 8 ); \
c -= a; c -= b; c ^= ( b >> 13 ); \
a -= b; a -= c; a ^= ( c >> 12 ); \
b -= c; b -= a; b ^= ( a << 16 ); \
c -= a; c -= b; c ^= ( b >> 5 ); \
a -= b; a -= c; a ^= ( c >> 3 ); \
b -= c; b -= a; b ^= ( a << 10 ); \
c -= a; c -= b; c ^= ( b >> 15 ); \
} while (0)
/**
* jenkins
*/
static inline uint64_t swoole_hash_jenkins(char *key, uint32_t keylen)
{
uint64_t hashv;
unsigned i, j, k;
hashv = 0xfeedbeef;
i = j = 0x9e3779b9;
k = (unsigned) (keylen);
while (k >= 12)
{
i += (key[0] + ((unsigned) key[1] << 8) + ((unsigned) key[2] << 16)
+ ((unsigned) key[3] << 24));
j += (key[4] + ((unsigned) key[5] << 8) + ((unsigned) key[6] << 16)
+ ((unsigned) key[7] << 24));
hashv += (key[8] + ((unsigned) key[9] << 8) + ((unsigned) key[10] << 16)
+ ((unsigned) key[11] << 24));
HASH_JEN_MIX(i, j, hashv);
key += 12;
k -= 12;
}
hashv += keylen;
switch (k)
{
case 11:
hashv += ((unsigned) key[10] << 24);
/* no break */
case 10:
hashv += ((unsigned) key[9] << 16);
/* no break */
case 9:
hashv += ((unsigned) key[8] << 8);
/* no break */
case 8:
j += ((unsigned) key[7] << 24);
/* no break */
case 7:
j += ((unsigned) key[6] << 16);
/* no break */
case 6:
j += ((unsigned) key[5] << 8);
/* no break */
case 5:
j += key[4];
/* no break */
case 4:
i += ((unsigned) key[3] << 24);
/* no break */
case 3:
i += ((unsigned) key[2] << 16);
/* no break */
case 2:
i += ((unsigned) key[1] << 8);
/* no break */
case 1:
i += key[0];
}
HASH_JEN_MIX(i, j, hashv);
return hashv;
}
/**
* MurmurHash2(Austin Appleby)
*/
static inline uint32_t swoole_hash_austin(char *key, unsigned int keylen)
{
unsigned int h, k;
h = 0 ^ keylen;
while (keylen >= 4)
{
k = key[0];
k |= key[1] << 8;
k |= key[2] << 16;
k |= key[3] << 24;
k *= 0x5bd1e995;
k ^= k >> 24;
k *= 0x5bd1e995;
h *= 0x5bd1e995;
h ^= k;
key += 4;
keylen -= 4;
}
switch (keylen)
{
case 3:
h ^= key[2] << 16;
/* no break */
case 2:
h ^= key[1] << 8;
/* no break */
case 1:
h ^= key[0];
h *= 0x5bd1e995;
}
h ^= h >> 13;
h *= 0x5bd1e995;
h ^= h >> 15;
return h;
}
/* {{{ DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
*
* This is Daniel J. Bernstein's popular `times 33' hash function as
* posted by him years ago on comp->lang.c. It basically uses a function
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
* known hash functions for strings. Because it is both computed very
* fast and distributes very well.
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as RSE did now) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
* with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
* advantage to the remaining numbers in the large set of possible
* multipliers: their multiply operation can be replaced by a faster
* operation based on just one shift plus either a single addition
* or subtraction operation. And because a hash function has to both
* distribute good _and_ has to be very fast to compute, those few
* numbers should be preferred and seems to be the reason why Daniel J.
* Bernstein also preferred it.
*
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
static inline uint64_t swoole_hash_php(char *key, uint32_t len)
{
register ulong_t hash = 5381;
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8)
{
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
}
switch (len)
{
case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
/* no break */
case 1: hash = ((hash << 5) + hash) + *key++; break;
case 0: break;
default: break;
}
return hash;
}
#define CRC_STRING_MAXLEN 256
uint32_t swoole_crc32(char *data, uint32_t size);
#endif /* SW_HASH_H_ */

55
vendor/swoole/include/hashmap.h vendored Executable file
View File

@ -0,0 +1,55 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef __SW_HASHMAP_H
#define __SW_HASHMAP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*swHashMap_dtor)(void *data);
typedef struct
{
struct swHashMap_node *root;
struct swHashMap_node *iterator;
swHashMap_dtor dtor;
} swHashMap;
swHashMap* swHashMap_new(uint32_t bucket_num, swHashMap_dtor dtor);
void swHashMap_free(swHashMap *hmap);
int swHashMap_add(swHashMap *hmap, char *key, uint16_t key_len, void *data);
int swHashMap_add_int(swHashMap *hmap, uint64_t key, void *data);
void* swHashMap_find(swHashMap *hmap, char *key, uint16_t key_len);
void* swHashMap_find_int(swHashMap *hmap, uint64_t key);
void swHashMap_update_int(swHashMap *hmap, uint64_t key, void *data);
int swHashMap_update(swHashMap *hmap, char *key, uint16_t key_len, void *data);
int swHashMap_del(swHashMap *hmap, char *key, uint16_t key_len);
int swHashMap_del_int(swHashMap *hmap, uint64_t key);
int swHashMap_move(swHashMap *hmap, char *old_key, uint16_t old_key_len, char *new_key, uint16_t new_key_len);
int swHashMap_move_int(swHashMap *hmap, uint64_t old_key, uint64_t new_key);
void* swHashMap_each(swHashMap* hmap, char **key);
void* swHashMap_each_int(swHashMap* hmap, uint64_t *key);
#define swHashMap_each_reset(hmap) (hmap->iterator = NULL)
uint32_t swHashMap_count(swHashMap* hmap);
#ifdef __cplusplus
}
#endif
#endif

59
vendor/swoole/include/heap.h vendored Executable file
View File

@ -0,0 +1,59 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_MINHEAP_H_
#define SW_MINHEAP_H_
enum swHeap_type
{
SW_MIN_HEAP, SW_MAX_HEAP,
};
typedef struct swHeap_node
{
uint64_t priority;
uint32_t position;
void *data;
} swHeap_node;
typedef struct _swHeap
{
uint32_t num;
uint32_t size;
uint8_t type;
swHeap_node **nodes;
} swHeap;
swHeap *swHeap_new(size_t n, uint8_t type);
void swHeap_free(swHeap *heap);
uint32_t swHeap_size(swHeap *heap);
swHeap_node* swHeap_push(swHeap *heap, uint64_t priority, void *data);
void *swHeap_pop(swHeap *heap);
void swHeap_change_priority(swHeap *heap, uint64_t new_priority, void* ptr);
int swHeap_remove(swHeap *heap, swHeap_node *node);
void *swHeap_peek(swHeap *heap);
void swHeap_print(swHeap *heap);
static inline swHeap_node *swHeap_top(swHeap *heap)
{
if (heap->num == 1)
{
return NULL;
}
return heap->nodes[1];
}
#endif /* SW_MINHEAP_H_ */

39
vendor/swoole/include/helper/kqueue.h vendored Executable file
View File

@ -0,0 +1,39 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2015 The Swoole Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef KQUEUE_IDE_HELPER_H_
#define KQUEUE_IDE_HELPER_H_
struct kevent
{
char *udata;
int filter;
};
#define EVFILT_READ 1
#define EVFILT_WRITE 2
#define EV_ADD 2
#define EV_DELETE 4
#define EV_CLEAR 8
int kevent(int, void *, int, struct kevent*, int, struct timespec *);
int kqueue(void);
int EV_SET(struct kevent*, int, int, int, int, int, void*);
#endif /* KQUEUE_IDE_HELPER_H_ */

81
vendor/swoole/include/http.h vendored Executable file
View File

@ -0,0 +1,81 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_HTTP_H_
#define SW_HTTP_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <sys/types.h>
#include <stdint.h>
enum swHttpMethod
{
HTTP_DELETE = 1, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH,
/* pathological */
HTTP_CONNECT, HTTP_OPTIONS, HTTP_TRACE,
/* webdav */
HTTP_COPY, HTTP_LOCK, HTTP_MKCOL, HTTP_MOVE, HTTP_PROPFIND, HTTP_PROPPATCH, HTTP_UNLOCK,
/* subversion */
HTTP_REPORT, HTTP_MKACTIVITY, HTTP_CHECKOUT, HTTP_MERGE,
/* upnp */
HTTP_MSEARCH, HTTP_NOTIFY, HTTP_SUBSCRIBE, HTTP_UNSUBSCRIBE,
/* Http2 */
HTTP_PRI,
};
enum swHttpVersion
{
HTTP_VERSION_10 = 1,
HTTP_VERSION_11,
};
typedef struct _swHttpRequest
{
uint8_t method;
uint8_t offset;
uint8_t version;
uint8_t free_memory;
uint8_t opcode;
uint8_t excepted;
uint32_t url_offset;
uint32_t url_length;
uint32_t header_length;
uint32_t content_length;
swString *buffer;
} swHttpRequest;
int swHttp_get_method(const char *method_str, int method_len);
const char* swHttp_get_method_string(int method);
int swHttpRequest_get_protocol(swHttpRequest *request);
int swHttpRequest_get_content_length(swHttpRequest *request);
int swHttpRequest_get_header_length(swHttpRequest *request);
void swHttpRequest_free(swConnection *conn);
#ifdef SW_HTTP_100_CONTINUE
int swHttpRequest_has_expect_header(swHttpRequest *request);
#endif
#ifdef __cplusplus
}
#endif
#endif /* SW_HTTP_H_ */

160
vendor/swoole/include/http2.h vendored Executable file
View File

@ -0,0 +1,160 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_HTTP2_H_
#define SW_HTTP2_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define SW_HTTP2_PRI_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
enum swHttp2ErrorCode
{
SW_HTTP2_ERROR_NO_ERROR = 0,
SW_HTTP2_ERROR_PROTOCOL_ERROR = 1,
SW_HTTP2_ERROR_INTERNAL_ERROR = 2,
SW_HTTP2_ERROR_FLOW_CONTROL_ERROR = 3,
SW_HTTP2_ERROR_SETTINGS_TIMEOUT = 4,
SW_HTTP2_ERROR_STREAM_CLOSED = 5,
SW_HTTP2_ERROR_FRAME_SIZE_ERROR = 6,
SW_HTTP2_ERROR_REFUSED_STREAM = 7,
SW_HTTP2_ERROR_CANCEL = 8,
SW_HTTP2_ERROR_COMPRESSION_ERROR = 9,
SW_HTTP2_ERROR_CONNECT_ERROR = 10,
SW_HTTP2_ERROR_ENHANCE_YOUR_CALM = 11,
SW_HTTP2_ERROR_INADEQUATE_SECURITY = 12,
};
enum swHttp2FrameType
{
SW_HTTP2_TYPE_DATA = 0,
SW_HTTP2_TYPE_HEADERS = 1,
SW_HTTP2_TYPE_PRIORITY = 2,
SW_HTTP2_TYPE_RST_STREAM = 3,
SW_HTTP2_TYPE_SETTINGS = 4,
SW_HTTP2_TYPE_PUSH_PROMISE = 5,
SW_HTTP2_TYPE_PING = 6,
SW_HTTP2_TYPE_GOAWAY = 7,
SW_HTTP2_TYPE_WINDOW_UPDATE = 8,
SW_HTTP2_TYPE_CONTINUATION = 9,
};
enum swHttp2FrameFlag
{
SW_HTTP2_FLAG_NONE = 0x00,
SW_HTTP2_FLAG_ACK = 0x01,
SW_HTTP2_FLAG_END_STREAM = 0x01,
SW_HTTP2_FLAG_END_HEADERS = 0x04,
SW_HTTP2_FLAG_PADDED = 0x08,
SW_HTTP2_FLAG_PRIORITY = 0x20,
};
enum swHttp2SettingId
{
SW_HTTP2_SETTING_HEADER_TABLE_SIZE = 0x1,
SW_HTTP2_SETTINGS_ENABLE_PUSH = 0x2,
SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 0x3,
SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE = 0x4,
SW_HTTP2_SETTINGS_MAX_FRAME_SIZE = 0x5,
SW_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x6,
};
enum swHttp2StreamType
{
SW_HTTP2_STREAM_NORMAL = 0,
SW_HTTP2_STREAM_PIPELINE = 1,
};
#define SW_HTTP2_FRAME_HEADER_SIZE 9
#define SW_HTTP2_SETTING_OPTION_SIZE 6
#define SW_HTTP2_FRAME_PING_PAYLOAD_SIZE 8
#define SW_HTTP2_RST_STREAM_SIZE 4
#define SW_HTTP2_PRIORITY_SIZE 5
#define SW_HTTP2_PING_SIZE 8
#define SW_HTTP2_GOAWAY_SIZE 8
#define SW_HTTP2_WINDOW_UPDATE_SIZE 4
#define SW_HTTP2_STREAM_ID_SIZE 4
#define SW_HTTP2_SETTINGS_PARAM_SIZE 6
/**
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
*/
typedef struct
{
uint32_t length :24;
uint32_t type :8;
uint32_t flags :8;
uint32_t rsv1 :1;
uint32_t identifier :31;
char data[0];
} swHttp2_frame;
static sw_inline uint32_t swHttp2_get_length(char *buf)
{
return (((uint8_t) buf[0]) << 16) + (((uint8_t) buf[1]) << 8) + (uint8_t) buf[2];
}
static sw_inline uint32_t swHttp2_get_increment_size(char *buf)
{
return (((uint8_t) buf[1 + SW_HTTP2_FRAME_HEADER_SIZE]) << 16) \
+ (((uint8_t) buf[2 + SW_HTTP2_FRAME_HEADER_SIZE]) << 8) \
+ (uint8_t) buf[3 + SW_HTTP2_FRAME_HEADER_SIZE];
}
int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length);
int swHttp2_send_setting_frame(swProtocol *protocol, swConnection *conn);
int swHttp2_parse_frame(swProtocol *protocol, swConnection *conn, char *data, uint32_t length);
char* swHttp2_get_type(int type);
/**
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
*/
static void sw_inline swHttp2_set_frame_header(char *buffer, int type, int length, int flags, int stream_id)
{
buffer[0] = length >> 16;
buffer[1] = length >> 8;
buffer[2] = length;
buffer[3] = type;
buffer[4] = flags;
*(int*) (buffer + 5) = htonl(stream_id);
}
#ifdef __cplusplus
}
#endif
#endif /* SW_HTTP2_H_ */

753
vendor/swoole/include/list.h vendored Executable file
View File

@ -0,0 +1,753 @@
/*
Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTLIST_H
#define UTLIST_H
#define UTLIST_VERSION 1.9.9
#include <assert.h>
/*
* This file contains macros to manipulate singly and doubly-linked lists.
*
* 1. LL_ macros: singly-linked lists.
* 2. DL_ macros: doubly-linked lists.
* 3. CDL_ macros: circular doubly-linked lists.
*
* To use singly-linked lists, your structure must have a "next" pointer.
* To use doubly-linked lists, your structure must "prev" and "next" pointers.
* Either way, the pointer to the head of the list must be initialized to NULL.
*
* ----------------.EXAMPLE -------------------------
* struct item {
* int id;
* struct item *prev, *next;
* }
*
* struct item *list = NULL:
*
* int main() {
* struct item *item;
* ... allocate and populate item ...
* DL_APPEND(list, item);
* }
* --------------------------------------------------
*
* For doubly-linked lists, the append and delete macros are O(1)
* For singly-linked lists, append and delete are O(n) but prepend is O(1)
* The sort macro is O(n log(n)) for all types of single/double/circular lists.
*/
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ code), this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
#ifdef _MSC_VER /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
#define LDECLTYPE(x) decltype(x)
#else /* VS2008 or older (or VS2010 in C mode) */
#define NO_DECLTYPE
#define LDECLTYPE(x) char*
#endif
#elif defined(__ICCARM__)
#define NO_DECLTYPE
#define LDECLTYPE(x) char*
#else /* GNU, Sun and other compilers */
#define LDECLTYPE(x) __typeof(x)
#endif
/* for VS2008 we use some workarounds to get around the lack of decltype,
* namely, we always reassign our tmp variable to the list head if we need
* to dereference its prev/next pointers, and save/restore the real head.*/
#ifdef NO_DECLTYPE
#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
#define _NEXT(elt,list,next) ((char*)((list)->next))
#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */
#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); }
#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; }
#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); }
#else
#define _SV(elt,list)
#define _NEXT(elt,list,next) ((elt)->next)
#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to)
/* #define _PREV(elt,list,prev) ((elt)->prev) */
#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to)
#define _RS(list)
#define _CASTASGN(a,b) (a)=(b)
#endif
/******************************************************************************
* The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort *
* Unwieldy variable names used here to avoid shadowing passed-in variables. *
*****************************************************************************/
#define LL_SORT(list, cmp) \
LL_SORT2(list, cmp, next)
#define LL_SORT2(list, cmp, next) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
} else if (_ls_qsize == 0 || !_ls_q) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \
} \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} \
} while (0)
#define DL_SORT(list, cmp) \
DL_SORT2(list, cmp, prev, next)
#define DL_SORT2(list, cmp, prev, next) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
} else if ((_ls_qsize == 0) || (!_ls_q)) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
_CASTASGN(list->prev, _ls_tail); \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} \
} while (0)
#define CDL_SORT(list, cmp) \
CDL_SORT2(list, cmp, prev, next)
#define CDL_SORT2(list, cmp, prev, next) \
do { \
LDECLTYPE(list) _ls_p; \
LDECLTYPE(list) _ls_q; \
LDECLTYPE(list) _ls_e; \
LDECLTYPE(list) _ls_tail; \
LDECLTYPE(list) _ls_oldhead; \
LDECLTYPE(list) _tmp; \
int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \
if (list) { \
_ls_insize = 1; \
_ls_looping = 1; \
while (_ls_looping) { \
_CASTASGN(_ls_p,list); \
_CASTASGN(_ls_oldhead,list); \
list = NULL; \
_ls_tail = NULL; \
_ls_nmerges = 0; \
while (_ls_p) { \
_ls_nmerges++; \
_ls_q = _ls_p; \
_ls_psize = 0; \
for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \
_ls_psize++; \
_SV(_ls_q,list); \
if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \
_ls_q = NULL; \
} else { \
_ls_q = _NEXT(_ls_q,list,next); \
} \
_RS(list); \
if (!_ls_q) break; \
} \
_ls_qsize = _ls_insize; \
while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \
if (_ls_psize == 0) { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
} else if (_ls_qsize == 0 || !_ls_q) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
} else if (cmp(_ls_p,_ls_q) <= 0) { \
_ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \
_NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \
if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \
} else { \
_ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \
_NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \
if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \
} \
if (_ls_tail) { \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \
} else { \
_CASTASGN(list,_ls_e); \
} \
_SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \
_ls_tail = _ls_e; \
} \
_ls_p = _ls_q; \
} \
_CASTASGN(list->prev,_ls_tail); \
_CASTASGN(_tmp,list); \
_SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \
if (_ls_nmerges <= 1) { \
_ls_looping=0; \
} \
_ls_insize *= 2; \
} \
} \
} while (0)
/******************************************************************************
* singly linked list macros (non-circular) *
*****************************************************************************/
#define LL_PREPEND(head,add) \
LL_PREPEND2(head,add,next)
#define LL_PREPEND2(head,add,next) \
do { \
(add)->next = head; \
head = add; \
} while (0)
#define LL_CONCAT(head1,head2) \
LL_CONCAT2(head1,head2,next)
#define LL_CONCAT2(head1,head2,next) \
do { \
LDECLTYPE(head1) _tmp; \
if (head1) { \
_tmp = head1; \
while (_tmp->next) { _tmp = _tmp->next; } \
_tmp->next=(head2); \
} else { \
(head1)=(head2); \
} \
} while (0)
#define LL_APPEND(head,add) \
LL_APPEND2(head,add,next)
#define LL_APPEND2(head,add,next) \
do { \
LDECLTYPE(head) _tmp; \
(add)->next=NULL; \
if (head) { \
_tmp = head; \
while (_tmp->next) { _tmp = _tmp->next; } \
_tmp->next=(add); \
} else { \
(head)=(add); \
} \
} while (0)
#define LL_DELETE(head,del) \
LL_DELETE2(head,del,next)
#define LL_DELETE2(head,del,next) \
do { \
LDECLTYPE(head) _tmp; \
if ((head) == (del)) { \
(head)=(head)->next; \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (del))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = ((del)->next); \
} \
} \
} while (0)
/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */
#define LL_APPEND_VS2008(head,add) \
LL_APPEND2_VS2008(head,add,next)
#define LL_APPEND2_VS2008(head,add,next) \
do { \
if (head) { \
(add)->next = head; /* use add->next as a temp variable */ \
while ((add)->next->next) { (add)->next = (add)->next->next; } \
(add)->next->next=(add); \
} else { \
(head)=(add); \
} \
(add)->next=NULL; \
} while (0)
#define LL_DELETE_VS2008(head,del) \
LL_DELETE2_VS2008(head,del,next)
#define LL_DELETE2_VS2008(head,del,next) \
do { \
if ((head) == (del)) { \
(head)=(head)->next; \
} else { \
char *_tmp = (char*)(head); \
while ((head)->next && ((head)->next != (del))) { \
head = (head)->next; \
} \
if ((head)->next) { \
(head)->next = ((del)->next); \
} \
{ \
char **_head_alias = (char**)&(head); \
*_head_alias = _tmp; \
} \
} \
} while (0)
#ifdef NO_DECLTYPE
#undef LL_APPEND
#define LL_APPEND LL_APPEND_VS2008
#undef LL_DELETE
#define LL_DELETE LL_DELETE_VS2008
#undef LL_DELETE2
#define LL_DELETE2 LL_DELETE2_VS2008
#undef LL_APPEND2
#define LL_APPEND2 LL_APPEND2_VS2008
#undef LL_CONCAT /* no LL_CONCAT_VS2008 */
#undef DL_CONCAT /* no DL_CONCAT_VS2008 */
#endif
/* end VS2008 replacements */
#define LL_COUNT(head,el,counter) \
LL_COUNT2(head,el,counter,next) \
#define LL_COUNT2(head,el,counter,next) \
{ \
counter = 0; \
LL_FOREACH2(head,el,next){ ++counter; } \
}
#define LL_FOREACH(head,el) \
LL_FOREACH2(head,el,next)
#define LL_FOREACH2(head,el,next) \
for(el=head;el;el=(el)->next)
#define LL_FOREACH_SAFE(head,el,tmp) \
LL_FOREACH_SAFE2(head,el,tmp,next)
#define LL_FOREACH_SAFE2(head,el,tmp,next) \
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
#define LL_SEARCH_SCALAR(head,out,field,val) \
LL_SEARCH_SCALAR2(head,out,field,val,next)
#define LL_SEARCH_SCALAR2(head,out,field,val,next) \
do { \
LL_FOREACH2(head,out,next) { \
if ((out)->field == (val)) break; \
} \
} while(0)
#define LL_SEARCH(head,out,elt,cmp) \
LL_SEARCH2(head,out,elt,cmp,next)
#define LL_SEARCH2(head,out,elt,cmp,next) \
do { \
LL_FOREACH2(head,out,next) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
#define LL_REPLACE_ELEM(head, el, add) \
do { \
LDECLTYPE(head) _tmp; \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el)->next; \
if ((head) == (el)) { \
(head) = (add); \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (el))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = (add); \
} \
} \
} while (0)
#define LL_PREPEND_ELEM(head, el, add) \
do { \
LDECLTYPE(head) _tmp; \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
if ((head) == (el)) { \
(head) = (add); \
} else { \
_tmp = head; \
while (_tmp->next && (_tmp->next != (el))) { \
_tmp = _tmp->next; \
} \
if (_tmp->next) { \
_tmp->next = (add); \
} \
} \
} while (0) \
/******************************************************************************
* doubly linked list macros (non-circular) *
*****************************************************************************/
#define DL_PREPEND(head,add) \
DL_PREPEND2(head,add,prev,next)
#define DL_PREPEND2(head,add,prev,next) \
do { \
(add)->next = head; \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev = (add); \
} else { \
(add)->prev = (add); \
} \
(head) = (add); \
} while (0)
#define DL_APPEND(head,add) \
DL_APPEND2(head,add,prev,next)
#define DL_APPEND2(head,add,prev,next) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(head)->prev->next = (add); \
(head)->prev = (add); \
(add)->next = NULL; \
} else { \
(head)=(add); \
(head)->prev = (head); \
(head)->next = NULL; \
} \
} while (0)
#define DL_CONCAT(head1,head2) \
DL_CONCAT2(head1,head2,prev,next)
#define DL_CONCAT2(head1,head2,prev,next) \
do { \
LDECLTYPE(head1) _tmp; \
if (head2) { \
if (head1) { \
_tmp = (head2)->prev; \
(head2)->prev = (head1)->prev; \
(head1)->prev->next = (head2); \
(head1)->prev = _tmp; \
} else { \
(head1)=(head2); \
} \
} \
} while (0)
#define DL_DELETE(head,del) \
DL_DELETE2(head,del,prev,next)
#define DL_DELETE2(head,del,prev,next) \
do { \
assert((del)->prev != NULL); \
if ((del)->prev == (del)) { \
(head)=NULL; \
} else if ((del)==(head)) { \
(del)->next->prev = (del)->prev; \
(head) = (del)->next; \
} else { \
(del)->prev->next = (del)->next; \
if ((del)->next) { \
(del)->next->prev = (del)->prev; \
} else { \
(head)->prev = (del)->prev; \
} \
} \
} while (0)
#define DL_COUNT(head,el,counter) \
DL_COUNT2(head,el,counter,next) \
#define DL_COUNT2(head,el,counter,next) \
{ \
counter = 0; \
DL_FOREACH2(head,el,next){ ++counter; } \
}
#define DL_FOREACH(head,el) \
DL_FOREACH2(head,el,next)
#define DL_FOREACH2(head,el,next) \
for(el=head;el;el=(el)->next)
/* this version is safe for deleting the elements during iteration */
#define DL_FOREACH_SAFE(head,el,tmp) \
DL_FOREACH_SAFE2(head,el,tmp,next)
#define DL_FOREACH_SAFE2(head,el,tmp,next) \
for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp)
/* these are identical to their singly-linked list counterparts */
#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR
#define DL_SEARCH LL_SEARCH
#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2
#define DL_SEARCH2 LL_SEARCH2
#define DL_REPLACE_ELEM(head, el, add) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
if ((head) == (el)) { \
(head) = (add); \
(add)->next = (el)->next; \
if ((el)->next == NULL) { \
(add)->prev = (add); \
} else { \
(add)->prev = (el)->prev; \
(add)->next->prev = (add); \
} \
} else { \
(add)->next = (el)->next; \
(add)->prev = (el)->prev; \
(add)->prev->next = (add); \
if ((el)->next == NULL) { \
(head)->prev = (add); \
} else { \
(add)->next->prev = (add); \
} \
} \
} while (0)
#define DL_PREPEND_ELEM(head, el, add) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
if ((head) == (el)) { \
(head) = (add); \
} else { \
(add)->prev->next = (add); \
} \
} while (0) \
/******************************************************************************
* circular doubly linked list macros *
*****************************************************************************/
#define CDL_PREPEND(head,add) \
CDL_PREPEND2(head,add,prev,next)
#define CDL_PREPEND2(head,add,prev,next) \
do { \
if (head) { \
(add)->prev = (head)->prev; \
(add)->next = (head); \
(head)->prev = (add); \
(add)->prev->next = (add); \
} else { \
(add)->prev = (add); \
(add)->next = (add); \
} \
(head)=(add); \
} while (0)
#define CDL_DELETE(head,del) \
CDL_DELETE2(head,del,prev,next)
#define CDL_DELETE2(head,del,prev,next) \
do { \
if ( ((head)==(del)) && ((head)->next == (head))) { \
(head) = NULL; \
} else { \
(del)->next->prev = (del)->prev; \
(del)->prev->next = (del)->next; \
if ((del) == (head)) (head)=(del)->next; \
} \
} while (0)
#define CDL_COUNT(head,el,counter) \
CDL_COUNT2(head,el,counter,next) \
#define CDL_COUNT2(head, el, counter,next) \
{ \
counter = 0; \
CDL_FOREACH2(head,el,next){ ++counter; } \
}
#define CDL_FOREACH(head,el) \
CDL_FOREACH2(head,el,next)
#define CDL_FOREACH2(head,el,next) \
for(el=head;el;el=(((el)->next==head) ? 0L : (el)->next))
#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \
CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \
for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \
(el) && ((tmp2)=(el)->next, 1); \
((el) = (((el)==(tmp1)) ? 0L : (tmp2))))
#define CDL_SEARCH_SCALAR(head,out,field,val) \
CDL_SEARCH_SCALAR2(head,out,field,val,next)
#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \
do { \
CDL_FOREACH2(head,out,next) { \
if ((out)->field == (val)) break; \
} \
} while(0)
#define CDL_SEARCH(head,out,elt,cmp) \
CDL_SEARCH2(head,out,elt,cmp,next)
#define CDL_SEARCH2(head,out,elt,cmp,next) \
do { \
CDL_FOREACH2(head,out,next) { \
if ((cmp(out,elt))==0) break; \
} \
} while(0)
#define CDL_REPLACE_ELEM(head, el, add) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
if ((el)->next == (el)) { \
(add)->next = (add); \
(add)->prev = (add); \
(head) = (add); \
} else { \
(add)->next = (el)->next; \
(add)->prev = (el)->prev; \
(add)->next->prev = (add); \
(add)->prev->next = (add); \
if ((head) == (el)) { \
(head) = (add); \
} \
} \
} while (0)
#define CDL_PREPEND_ELEM(head, el, add) \
do { \
assert(head != NULL); \
assert(el != NULL); \
assert(add != NULL); \
(add)->next = (el); \
(add)->prev = (el)->prev; \
(el)->prev = (add); \
(add)->prev->next = (add); \
if ((head) == (el)) { \
(head) = (add); \
} \
} while (0) \
#endif /* UTLIST_H */

73
vendor/swoole/include/mqtt.h vendored Executable file
View File

@ -0,0 +1,73 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2015 The Swoole Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_MQTT_H_
#define SW_MQTT_H_
#include "swoole.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SW_MQTT_MIN_LENGTH 2
#define SW_MQTT_MAX_PAYLOAD_SIZE 268435455
enum swMqtt_type
{
CONNECT = 0x10,
CONNACK = 0x20,
PUBLISH = 0x30,
PUBACK = 0x40,
PUBREC = 0x50,
PUBREL = 0x60,
PUBCOMP = 0x70,
SUBSCRIBE = 0x80,
SUBACK = 0x90,
UNSUBSCRIBE = 0xA0,
UNSUBACK = 0xB0,
PINGREQ = 0xC0,
PINGRESP = 0xD0,
DISCONNECT = 0xE0,
};
typedef struct
{
uint8_t type :4;
uint8_t dup :1;
uint8_t qos :2;
uint8_t retain :1;
uint32_t length;
char protocol_name[8];
} swMqtt_package;
#define SETRETAIN(HDR, R) (HDR | (R))
#define SETQOS(HDR, Q) (HDR | ((Q) << 1))
#define SETDUP(HDR, D) (HDR | ((D) << 3))
int swMqtt_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size);
#ifdef __cplusplus
}
#endif
#endif /* SW_MQTT_H_ */

65
vendor/swoole/include/rbtree.h vendored Executable file
View File

@ -0,0 +1,65 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _NGX_RBTREE_H_INCLUDED_
#define _NGX_RBTREE_H_INCLUDED_
#include <stdint.h>
typedef struct swRbtree_node_s swRbtree_node;
struct swRbtree_node_s
{
uint32_t key;
void *value;
swRbtree_node *left;
swRbtree_node *right;
swRbtree_node *parent;
char color;
};
typedef struct swRbtree_s swRbtree;
struct swRbtree_s
{
swRbtree_node *root;
swRbtree_node *sentinel;
};
swRbtree* swRbtree_new();
void swRbtree_free(swRbtree*);
void swRbtree_insert(swRbtree *tree, uint32_t key, void *value);
void swRbtree_delete(swRbtree *tree, uint32_t key);
void *swRbtree_find(swRbtree *tree, uint32_t key);
#define swRbtree_red(node) ((node)->color = 1)
#define swRbtree_black(node) ((node)->color = 0)
#define swRbtree_is_red(node) ((node)->color)
#define swRbtree_is_black(node) (!swRbtree_is_red(node))
#define swRbtree_copy_color(n1, n2) (n1->color = n2->color)
#define swRbtree_sentinel_init(node) swRbtree_black(node)
static inline swRbtree_node *swRbtree_min(swRbtree_node *node, swRbtree_node *sentinel)
{
while (node->left != sentinel)
{
node = node->left;
}
return node;
}
#endif

72
vendor/swoole/include/redis.h vendored Executable file
View File

@ -0,0 +1,72 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_REDIS_H_
#define SW_REDIS_H_
#ifdef __cplusplus
extern "C"
{
#endif
enum swRedis_receive_state
{
SW_REDIS_RECEIVE_TOTAL_LINE,
SW_REDIS_RECEIVE_LENGTH,
SW_REDIS_RECEIVE_STRING,
};
enum swRedis_reply_type
{
SW_REDIS_REPLY_ERROR,
SW_REDIS_REPLY_NIL,
SW_REDIS_REPLY_STATUS,
SW_REDIS_REPLY_INT,
SW_REDIS_REPLY_STRING,
SW_REDIS_REPLY_SET,
SW_REDIS_REPLY_MAP,
};
#define SW_REDIS_RETURN_NIL "$-1\r\n"
#define SW_REDIS_MAX_COMMAND_SIZE 64
#define SW_REDIS_MAX_LINES 128
#define SW_REDIS_MAX_STRING_SIZE 536870912 //512M
static sw_inline char* swRedis_get_number(char *p, int *_ret)
{
char *endptr;
p++;
int ret = strtol(p, &endptr, 10);
if (strncmp(SW_CRLF, endptr, SW_CRLF_LEN) == 0)
{
p += (endptr - p) + SW_CRLF_LEN;
*_ret = ret;
return p;
}
else
{
return NULL;
}
}
int swRedis_recv(swProtocol *protocol, swConnection *conn, swString *buffer);
#ifdef __cplusplus
}
#endif
#endif /* SW_REDIS_H_ */

64
vendor/swoole/include/sha1.h vendored Executable file
View File

@ -0,0 +1,64 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef _WEBSOCKET_SHA1_H__
#define _WEBSOCKET_SHA1_H__
/* Define this if your machine is LITTLE_ENDIAN, otherwise #undef it: */
#ifdef WORDS_BIGENDIAN
# undef LITTLE_ENDIAN
#else
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN
# endif
#endif
/* Make sure you define these types for your architecture: */
typedef unsigned int sha1_quadbyte; /* 4 byte type */
typedef unsigned char sha1_byte; /* single byte type */
/*
* Be sure to get the above definitions right. For instance, on my
* x86 based FreeBSD box, I define LITTLE_ENDIAN and use the type
* "unsigned long" for the quadbyte. On FreeBSD on the Alpha, however,
* while I still use LITTLE_ENDIAN, I must define the quadbyte type
* as "unsigned int" instead.
*/
#define SHA1_BLOCK_LENGTH 64
#define SHA1_DIGEST_LENGTH 20
/* The SHA1 structure: */
typedef struct _SHA_CTX {
sha1_quadbyte state[5];
sha1_quadbyte count[2];
sha1_byte buffer[SHA1_BLOCK_LENGTH];
} SHA_CTX;
#ifndef NOPROTO
void swSha1_init(SHA_CTX *context);
void swSha1_update(SHA_CTX *context, sha1_byte *data, unsigned int len);
void swSha1_final(sha1_byte digest[SHA1_DIGEST_LENGTH],
SHA_CTX* context);
#else
void swSha1_init();
void swSha1_update();
void swSha1_final();
#endif
#endif

70
vendor/swoole/include/socks5.h vendored Executable file
View File

@ -0,0 +1,70 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_SOCKS5_H_
#define SW_SOCKS5_H_
#include "Client.h"
#define SW_SOCKS5_VERSION_CODE 0x05
enum swSocks5_state
{
SW_SOCKS5_STATE_WAIT = 0,
SW_SOCKS5_STATE_HANDSHAKE,
SW_SOCKS5_STATE_AUTH,
SW_SOCKS5_STATE_CONNECT,
SW_SOCKS5_STATE_READY,
};
enum swSocks5_method
{
SW_SOCKS5_METHOD_AUTH = 0x02,
};
typedef struct _swSocks5
{
char *host;
int l_host;
int port;
uint8_t state;
uint8_t version;
uint8_t method;
uint8_t dns_tunnel;
char *password;
char *username;
char *target_host;
int target_port;
int l_target_host;
int l_username;
int l_password;
char buf[600];
} swSocks5;
static sw_inline void swSocks5_pack(char *buf, int method)
{
buf[0] = SW_SOCKS5_VERSION_CODE;
buf[1] = 0x01;
buf[2] = method;
}
int swSocks5_connect(swClient *cli, char *recv_data, int length);
#endif /* SW_SOCKS5_H_ */

2203
vendor/swoole/include/swoole.h vendored Executable file

File diff suppressed because it is too large Load Diff

192
vendor/swoole/include/table.h vendored Executable file
View File

@ -0,0 +1,192 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_TABLE_H_
#define SW_TABLE_H_
#include "atomic.h"
#include "hashmap.h"
#include "hash.h"
typedef struct _swTableRow
{
#if SW_TABLE_USE_SPINLOCK
sw_atomic_t lock;
#else
pthread_mutex_t lock;
#endif
/**
* 1:used, 0:empty
*/
uint8_t active;
/**
* next slot
*/
struct _swTableRow *next;
/**
* Hash Key
*/
char key[SW_TABLE_KEY_SIZE];
char data[0];
} swTableRow;
typedef struct
{
uint32_t absolute_index;
uint32_t collision_index;
swTableRow *row;
} swTable_iterator;
typedef struct
{
swHashMap *columns;
uint16_t column_num;
swLock lock;
size_t size;
size_t mask;
size_t item_size;
size_t memory_size;
float conflict_proportion;
/**
* total rows that in active state(shm)
*/
sw_atomic_t row_num;
swTableRow **rows;
swMemoryPool *pool;
swTable_iterator *iterator;
void *memory;
} swTable;
typedef struct
{
uint8_t type;
uint32_t size;
swString* name;
uint16_t index;
} swTableColumn;
enum swoole_table_type
{
SW_TABLE_INT = 1,
SW_TABLE_INT8,
SW_TABLE_INT16,
SW_TABLE_INT32,
#ifdef __x86_64__
SW_TABLE_INT64,
#endif
SW_TABLE_FLOAT,
SW_TABLE_STRING,
};
enum swoole_table_find
{
SW_TABLE_FIND_EQ = 1,
SW_TABLE_FIND_NEQ,
SW_TABLE_FIND_GT,
SW_TABLE_FIND_LT,
SW_TABLE_FIND_LEFTLIKE,
SW_TABLE_FIND_RIGHTLIKE,
SW_TABLE_FIND_LIKE,
};
swTable* swTable_new(uint32_t rows_size, float conflict_proportion);
size_t swTable_get_memory_size(swTable *table);
int swTable_create(swTable *table);
void swTable_free(swTable *table);
int swTableColumn_add(swTable *table, char *name, int len, int type, int size);
swTableRow* swTableRow_set(swTable *table, char *key, int keylen, swTableRow **rowlock);
swTableRow* swTableRow_get(swTable *table, char *key, int keylen, swTableRow **rowlock);
void swTable_iterator_rewind(swTable *table);
swTableRow* swTable_iterator_current(swTable *table);
void swTable_iterator_forward(swTable *table);
int swTableRow_del(swTable *table, char *key, int keylen);
static sw_inline swTableColumn* swTableColumn_get(swTable *table, char *column_key, int keylen)
{
return swHashMap_find(table->columns, column_key, keylen);
}
static sw_inline void swTableRow_lock(swTableRow *row)
{
#if SW_TABLE_USE_SPINLOCK
sw_spinlock(&row->lock);
#else
pthread_mutex_lock(&row->lock);
#endif
}
static sw_inline void swTableRow_unlock(swTableRow *row)
{
#if SW_TABLE_USE_SPINLOCK
sw_spinlock_release(&row->lock);
#else
pthread_mutex_unlock(&row->lock);
#endif
}
typedef uint32_t swTable_string_length_t;
static sw_inline void swTableRow_set_value(swTableRow *row, swTableColumn * col, void *value, int vlen)
{
int8_t _i8;
int16_t _i16;
int32_t _i32;
#ifdef __x86_64__
int64_t _i64;
#endif
switch(col->type)
{
case SW_TABLE_INT8:
_i8 = *(int8_t *) value;
memcpy(row->data + col->index, &_i8, 1);
break;
case SW_TABLE_INT16:
_i16 = *(int16_t *) value;
memcpy(row->data + col->index, &_i16, 2);
break;
case SW_TABLE_INT32:
_i32 = *(int32_t *) value;
memcpy(row->data + col->index, &_i32, 4);
break;
#ifdef __x86_64__
case SW_TABLE_INT64:
_i64 = *(int64_t *) value;
memcpy(row->data + col->index, &_i64, 8);
break;
#endif
case SW_TABLE_FLOAT:
memcpy(row->data + col->index, value, sizeof(double));
break;
default:
if (vlen > (col->size - sizeof(swTable_string_length_t)))
{
swWarn("[key=%s,field=%s]string value is too long.", row->key, col->name->str);
vlen = col->size - sizeof(swTable_string_length_t);
}
memcpy(row->data + col->index, &vlen, sizeof(swTable_string_length_t));
memcpy(row->data + col->index + sizeof(swTable_string_length_t), value, vlen);
break;
}
}
#endif /* SW_TABLE_H_ */

73
vendor/swoole/include/tests.h vendored Executable file
View File

@ -0,0 +1,73 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_TESTS_H_
#define SW_TESTS_H_
#define swUnitTest(x) int swUnitTest_##x(swUnitTest *object)
#define swUnitTest_steup(x,n,t) _swUnitTest_setup(swUnitTest_##x, #x, n, t)
typedef struct _swUnitTest
{
int argc;
char **argv;
} swUnitTest;
typedef int (*swUnitTest_Func)(swUnitTest *object);
void _swUnitTest_setup(swUnitTest_Func func, char *func_name, int run_times, char *comment);
int swUnitTest_run(swUnitTest *object);
swUnitTest(mem_test1);
swUnitTest(mem_test2);
swUnitTest(mem_test3);
swUnitTest(mem_test4);
swUnitTest(dnslookup_test);
swUnitTest(client_test);
swUnitTest(server_test);
swUnitTest(hashmap_test1);
swUnitTest(ds_test2);
swUnitTest(ds_test1);
swUnitTest(chan_test);
swUnitTest(u1_test2);
swUnitTest(u1_test1);
swUnitTest(u1_test3);
swUnitTest(http_test2);
swUnitTest(type_test1);
swUnitTest(aio_test);
swUnitTest(aio_test2);
swUnitTest(ws_test1);
swUnitTest(http_test1);
swUnitTest(http_test2);
swUnitTest(heap_test1);
swUnitTest(linkedlist_test);
swUnitTest(rbtree_test);
void p_str(void *str);
swUnitTest(pool_thread);
swUnitTest(ringbuffer_test1);
#endif /* SW_TESTS_H_ */

935
vendor/swoole/include/uthash.h vendored Executable file
View File

@ -0,0 +1,935 @@
/*
Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTHASH_H
#define UTHASH_H
#include <string.h> /* memcmp,strlen */
#include <stddef.h> /* ptrdiff_t */
#include <stdlib.h> /* exit() */
/* These macros use decltype or the earlier __typeof GNU extension.
As decltype is only available in newer compilers (VS2010 or gcc 4.3+
when compiling c++ source) this code uses whatever method is needed
or, for VS2008 where neither is available, uses casting workarounds. */
#ifdef _MSC_VER /* MS compiler */
#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
#define DECLTYPE(x) (decltype(x))
#else /* VS2008 or older (or VS2010 in C mode) */
#define NO_DECLTYPE
#define DECLTYPE(x)
#endif
#else /* GNU, Sun and other compilers */
#define DECLTYPE(x) (__typeof(x))
#endif
#ifdef NO_DECLTYPE
#define DECLTYPE_ASSIGN(dst,src) \
do { \
char **_da_dst = (char**)(&(dst)); \
*_da_dst = (char*)(src); \
} while(0)
#else
#define DECLTYPE_ASSIGN(dst,src) \
do { \
(dst) = DECLTYPE(dst)(src); \
} while(0)
#endif
/* a number of the hash function use uint32_t which isn't defined on win32 */
#ifdef _MSC_VER
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
#else
#include <inttypes.h> /* uint32_t */
#endif
#define UTHASH_VERSION 1.9.8
#ifndef uthash_fatal
#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
#endif
#ifndef uthash_malloc
#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
#endif
#ifndef uthash_free
#define uthash_free(ptr,sz) free(ptr) /* free fcn */
#endif
#ifndef uthash_noexpand_fyi
#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
#endif
#ifndef uthash_expand_fyi
#define uthash_expand_fyi(tbl) /* can be defined to log expands */
#endif
/* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
/* calculate the element whose hash handle address is hhe */
#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
#define HASH_FIND(hh,head,keyptr,keylen,out) \
do { \
unsigned _hf_bkt,_hf_hashv; \
out=NULL; \
if (head) { \
HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
keyptr,keylen,out); \
} \
} \
} while (0)
#ifdef HASH_BLOOM
#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
#define HASH_BLOOM_MAKE(tbl) \
do { \
(tbl)->bloom_nbits = HASH_BLOOM; \
(tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
(tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
} while (0)
#define HASH_BLOOM_FREE(tbl) \
do { \
uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
} while (0)
#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
#define HASH_BLOOM_ADD(tbl,hashv) \
HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#define HASH_BLOOM_TEST(tbl,hashv) \
HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
#else
#define HASH_BLOOM_MAKE(tbl)
#define HASH_BLOOM_FREE(tbl)
#define HASH_BLOOM_ADD(tbl,hashv)
#define HASH_BLOOM_TEST(tbl,hashv) (1)
#define HASH_BLOOM_BYTELEN 0
#endif
#define HASH_MAKE_TABLE(hh,head) \
do { \
(head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
sizeof(UT_hash_table)); \
if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
(head)->hh.tbl->tail = &((head)->hh); \
(head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
(head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
(head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
(head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
memset((head)->hh.tbl->buckets, 0, \
HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_MAKE((head)->hh.tbl); \
(head)->hh.tbl->signature = HASH_SIGNATURE; \
} while(0)
#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
do { \
replaced=NULL; \
HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
if (replaced!=NULL) { \
HASH_DELETE(hh,head,replaced); \
}; \
HASH_ADD(hh,head,fieldname,keylen_in,add); \
} while(0)
#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
do { \
unsigned _ha_bkt; \
(add)->hh.next = NULL; \
(add)->hh.key = (char*)(keyptr); \
(add)->hh.keylen = (unsigned)(keylen_in); \
if (!(head)) { \
head = (add); \
(head)->hh.prev = NULL; \
HASH_MAKE_TABLE(hh,head); \
} else { \
(head)->hh.tbl->tail->next = (add); \
(add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
(head)->hh.tbl->tail = &((add)->hh); \
} \
(head)->hh.tbl->num_items++; \
(add)->hh.tbl = (head)->hh.tbl; \
HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
(add)->hh.hashv, _ha_bkt); \
HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
HASH_FSCK(hh,head); \
} while(0)
#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
do { \
bkt = ((hashv) & ((num_bkts) - 1)); \
} while(0)
/* delete "delptr" from the hash table.
* "the usual" patch-up process for the app-order doubly-linked-list.
* The use of _hd_hh_del below deserves special explanation.
* These used to be expressed using (delptr) but that led to a bug
* if someone used the same symbol for the head and deletee, like
* HASH_DELETE(hh,users,users);
* We want that to work, but by changing the head (users) below
* we were forfeiting our ability to further refer to the deletee (users)
* in the patch-up process. Solution: use scratch space to
* copy the deletee pointer, then the latter references are via that
* scratch pointer rather than through the repointed (users) symbol.
*/
#define HASH_DELETE(hh,head,delptr) \
do { \
unsigned _hd_bkt; \
struct UT_hash_handle *_hd_hh_del; \
if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
uthash_free((head)->hh.tbl->buckets, \
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
HASH_BLOOM_FREE((head)->hh.tbl); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
head = NULL; \
} else { \
_hd_hh_del = &((delptr)->hh); \
if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
(head)->hh.tbl->tail = \
(UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
(head)->hh.tbl->hho); \
} \
if ((delptr)->hh.prev) { \
((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
(head)->hh.tbl->hho))->next = (delptr)->hh.next; \
} else { \
DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
} \
if (_hd_hh_del->next) { \
((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \
(head)->hh.tbl->hho))->prev = \
_hd_hh_del->prev; \
} \
HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
(head)->hh.tbl->num_items--; \
} \
HASH_FSCK(hh,head); \
} while (0)
/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
#define HASH_FIND_STR(head,findstr,out) \
HASH_FIND(hh,head,findstr,strlen(findstr),out)
#define HASH_ADD_STR(head,strfield,add) \
HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
#define HASH_REPLACE_STR(head,strfield,add,replaced) \
HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced)
#define HASH_FIND_INT(head,findint,out) \
HASH_FIND(hh,head,findint,sizeof(int),out)
#define HASH_ADD_INT(head,intfield,add) \
HASH_ADD(hh,head,intfield,sizeof(int),add)
#define HASH_REPLACE_INT(head,intfield,add,replaced) \
HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
#define HASH_FIND_PTR(head,findptr,out) \
HASH_FIND(hh,head,findptr,sizeof(void *),out)
#define HASH_ADD_PTR(head,ptrfield,add) \
HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
#define HASH_REPLACE_PTR(head,ptrfield,add) \
HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
#define HASH_DEL(head,delptr) \
HASH_DELETE(hh,head,delptr)
/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
* This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
*/
#ifdef HASH_DEBUG
#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
#define HASH_FSCK(hh,head) \
do { \
unsigned _bkt_i; \
unsigned _count, _bkt_count; \
char *_prev; \
struct UT_hash_handle *_thh; \
if (head) { \
_count = 0; \
for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
_bkt_count = 0; \
_thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
_prev = NULL; \
while (_thh) { \
if (_prev != (char*)(_thh->hh_prev)) { \
HASH_OOPS("invalid hh_prev %p, actual %p\n", \
_thh->hh_prev, _prev ); \
} \
_bkt_count++; \
_prev = (char*)(_thh); \
_thh = _thh->hh_next; \
} \
_count += _bkt_count; \
if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
HASH_OOPS("invalid bucket count %d, actual %d\n", \
(head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
} \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid hh item count %d, actual %d\n", \
(head)->hh.tbl->num_items, _count ); \
} \
/* traverse hh in app order; check next/prev integrity, count */ \
_count = 0; \
_prev = NULL; \
_thh = &(head)->hh; \
while (_thh) { \
_count++; \
if (_prev !=(char*)(_thh->prev)) { \
HASH_OOPS("invalid prev %p, actual %p\n", \
_thh->prev, _prev ); \
} \
_prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
_thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
(head)->hh.tbl->hho) : NULL ); \
} \
if (_count != (head)->hh.tbl->num_items) { \
HASH_OOPS("invalid app item count %d, actual %d\n", \
(head)->hh.tbl->num_items, _count ); \
} \
} \
} while (0)
#else
#define HASH_FSCK(hh,head)
#endif
/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
* the descriptor to which this macro is defined for tuning the hash function.
* The app can #include <unistd.h> to get the prototype for write(2). */
#ifdef HASH_EMIT_KEYS
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
do { \
unsigned _klen = fieldlen; \
write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
write(HASH_EMIT_KEYS, keyptr, fieldlen); \
} while (0)
#else
#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
#endif
/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
#ifdef HASH_FUNCTION
#define HASH_FCN HASH_FUNCTION
#else
#define HASH_FCN HASH_JEN
#endif
/* The Bernstein hash function, used in Perl prior to v5.6 */
#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _hb_keylen=keylen; \
char *_hb_key=(char*)(key); \
(hashv) = 0; \
while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
bkt = (hashv) & (num_bkts-1); \
} while (0)
/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _sx_i; \
char *_hs_key=(char*)(key); \
hashv = 0; \
for(_sx_i=0; _sx_i < keylen; _sx_i++) \
hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
bkt = hashv & (num_bkts-1); \
} while (0)
#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _fn_i; \
char *_hf_key=(char*)(key); \
hashv = 2166136261UL; \
for(_fn_i=0; _fn_i < keylen; _fn_i++) \
hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
bkt = hashv & (num_bkts-1); \
} while(0)
#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _ho_i; \
char *_ho_key=(char*)(key); \
hashv = 0; \
for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
hashv += _ho_key[_ho_i]; \
hashv += (hashv << 10); \
hashv ^= (hashv >> 6); \
} \
hashv += (hashv << 3); \
hashv ^= (hashv >> 11); \
hashv += (hashv << 15); \
bkt = hashv & (num_bkts-1); \
} while(0)
#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned _hj_i,_hj_j,_hj_k; \
unsigned char *_hj_key=(unsigned char*)(key); \
hashv = 0xfeedbeef; \
_hj_i = _hj_j = 0x9e3779b9; \
_hj_k = (unsigned)(keylen); \
while (_hj_k >= 12) { \
_hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
+ ( (unsigned)_hj_key[2] << 16 ) \
+ ( (unsigned)_hj_key[3] << 24 ) ); \
_hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
+ ( (unsigned)_hj_key[6] << 16 ) \
+ ( (unsigned)_hj_key[7] << 24 ) ); \
hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
+ ( (unsigned)_hj_key[10] << 16 ) \
+ ( (unsigned)_hj_key[11] << 24 ) ); \
\
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
\
_hj_key += 12; \
_hj_k -= 12; \
} \
hashv += keylen; \
switch ( _hj_k ) { \
case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
case 5: _hj_j += _hj_key[4]; \
case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
case 1: _hj_i += _hj_key[0]; \
} \
HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
bkt = hashv & (num_bkts-1); \
} while(0)
/* The Paul Hsieh hash function */
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
do { \
unsigned char *_sfh_key=(unsigned char*)(key); \
uint32_t _sfh_tmp, _sfh_len = keylen; \
\
int _sfh_rem = _sfh_len & 3; \
_sfh_len >>= 2; \
hashv = 0xcafebabe; \
\
/* Main loop */ \
for (;_sfh_len > 0; _sfh_len--) { \
hashv += get16bits (_sfh_key); \
_sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \
hashv = (hashv << 16) ^ _sfh_tmp; \
_sfh_key += 2*sizeof (uint16_t); \
hashv += hashv >> 11; \
} \
\
/* Handle end cases */ \
switch (_sfh_rem) { \
case 3: hashv += get16bits (_sfh_key); \
hashv ^= hashv << 16; \
hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \
hashv += hashv >> 11; \
break; \
case 2: hashv += get16bits (_sfh_key); \
hashv ^= hashv << 11; \
hashv += hashv >> 17; \
break; \
case 1: hashv += *_sfh_key; \
hashv ^= hashv << 10; \
hashv += hashv >> 1; \
} \
\
/* Force "avalanching" of final 127 bits */ \
hashv ^= hashv << 3; \
hashv += hashv >> 5; \
hashv ^= hashv << 4; \
hashv += hashv >> 17; \
hashv ^= hashv << 25; \
hashv += hashv >> 6; \
bkt = hashv & (num_bkts-1); \
} while(0)
#ifdef HASH_USING_NO_STRICT_ALIASING
/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
* For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
* MurmurHash uses the faster approach only on CPU's where we know it's safe.
*
* Note the preprocessor built-in defines can be emitted using:
*
* gcc -m64 -dM -E - < /dev/null (on gcc)
* cc -## a.c (where a.c is a simple test file) (Sun Studio)
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
#define MUR_GETBLOCK(p,i) p[i]
#else /* non intel */
#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
#else /* assume little endian non-intel */
#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
#endif
#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
(MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
(MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
MUR_ONE_THREE(p))))
#endif
#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
#define MUR_FMIX(_h) \
do { \
_h ^= _h >> 16; \
_h *= 0x85ebca6b; \
_h ^= _h >> 13; \
_h *= 0xc2b2ae35l; \
_h ^= _h >> 16; \
} while(0)
#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
do { \
const uint8_t *_mur_data = (const uint8_t*)(key); \
const int _mur_nblocks = (keylen) / 4; \
uint32_t _mur_h1 = 0xf88D5353; \
uint32_t _mur_c1 = 0xcc9e2d51; \
uint32_t _mur_c2 = 0x1b873593; \
uint32_t _mur_k1 = 0; \
const uint8_t *_mur_tail; \
const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
int _mur_i; \
for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
_mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
\
_mur_h1 ^= _mur_k1; \
_mur_h1 = MUR_ROTL32(_mur_h1,13); \
_mur_h1 = _mur_h1*5+0xe6546b64; \
} \
_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
_mur_k1=0; \
switch((keylen) & 3) { \
case 3: _mur_k1 ^= _mur_tail[2] << 16; \
case 2: _mur_k1 ^= _mur_tail[1] << 8; \
case 1: _mur_k1 ^= _mur_tail[0]; \
_mur_k1 *= _mur_c1; \
_mur_k1 = MUR_ROTL32(_mur_k1,15); \
_mur_k1 *= _mur_c2; \
_mur_h1 ^= _mur_k1; \
} \
_mur_h1 ^= (keylen); \
MUR_FMIX(_mur_h1); \
hashv = _mur_h1; \
bkt = hashv & (num_bkts-1); \
} while(0)
#endif /* HASH_USING_NO_STRICT_ALIASING */
/* key comparison function; return 0 if keys equal */
#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
/* iterate over items in a known bucket to find desired item */
#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
do { \
if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
else out=NULL; \
while (out) { \
if ((out)->hh.keylen == keylen_in) { \
if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \
} \
if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \
else out = NULL; \
} \
} while(0)
/* add an item to a bucket */
#define HASH_ADD_TO_BKT(head,addhh) \
do { \
head.count++; \
(addhh)->hh_next = head.hh_head; \
(addhh)->hh_prev = NULL; \
if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
(head).hh_head=addhh; \
if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
&& (addhh)->tbl->noexpand != 1) { \
HASH_EXPAND_BUCKETS((addhh)->tbl); \
} \
} while(0)
/* remove an item from a given bucket */
#define HASH_DEL_IN_BKT(hh,head,hh_del) \
(head).count--; \
if ((head).hh_head == hh_del) { \
(head).hh_head = hh_del->hh_next; \
} \
if (hh_del->hh_prev) { \
hh_del->hh_prev->hh_next = hh_del->hh_next; \
} \
if (hh_del->hh_next) { \
hh_del->hh_next->hh_prev = hh_del->hh_prev; \
}
/* Bucket expansion has the effect of doubling the number of buckets
* and redistributing the items into the new buckets. Ideally the
* items will distribute more or less evenly into the new buckets
* (the extent to which this is true is a measure of the quality of
* the hash function as it applies to the key domain).
*
* With the items distributed into more buckets, the chain length
* (item count) in each bucket is reduced. Thus by expanding buckets
* the hash keeps a bound on the chain length. This bounded chain
* length is the essence of how a hash provides constant time lookup.
*
* The calculation of tbl->ideal_chain_maxlen below deserves some
* explanation. First, keep in mind that we're calculating the ideal
* maximum chain length based on the *new* (doubled) bucket count.
* In fractions this is just n/b (n=number of items,b=new num buckets).
* Since the ideal chain length is an integer, we want to calculate
* ceil(n/b). We don't depend on floating point arithmetic in this
* hash, so to calculate ceil(n/b) with integers we could write
*
* ceil(n/b) = (n/b) + ((n%b)?1:0)
*
* and in fact a previous version of this hash did just that.
* But now we have improved things a bit by recognizing that b is
* always a power of two. We keep its base 2 log handy (call it lb),
* so now we can write this with a bit shift and logical AND:
*
* ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
*
*/
#define HASH_EXPAND_BUCKETS(tbl) \
do { \
unsigned _he_bkt; \
unsigned _he_bkt_i; \
struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
_he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
memset(_he_new_buckets, 0, \
2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
tbl->ideal_chain_maxlen = \
(tbl->num_items >> (tbl->log2_num_buckets+1)) + \
((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
tbl->nonideal_items = 0; \
for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
{ \
_he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
while (_he_thh) { \
_he_hh_nxt = _he_thh->hh_next; \
HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
_he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
tbl->nonideal_items++; \
_he_newbkt->expand_mult = _he_newbkt->count / \
tbl->ideal_chain_maxlen; \
} \
_he_thh->hh_prev = NULL; \
_he_thh->hh_next = _he_newbkt->hh_head; \
if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
_he_thh; \
_he_newbkt->hh_head = _he_thh; \
_he_thh = _he_hh_nxt; \
} \
} \
uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
tbl->num_buckets *= 2; \
tbl->log2_num_buckets++; \
tbl->buckets = _he_new_buckets; \
tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
(tbl->ineff_expands+1) : 0; \
if (tbl->ineff_expands > 1) { \
tbl->noexpand=1; \
uthash_noexpand_fyi(tbl); \
} \
uthash_expand_fyi(tbl); \
} while(0)
/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
/* Note that HASH_SORT assumes the hash handle name to be hh.
* HASH_SRT was added to allow the hash handle name to be passed in. */
#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
#define HASH_SRT(hh,head,cmpfcn) \
do { \
unsigned _hs_i; \
unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
if (head) { \
_hs_insize = 1; \
_hs_looping = 1; \
_hs_list = &((head)->hh); \
while (_hs_looping) { \
_hs_p = _hs_list; \
_hs_list = NULL; \
_hs_tail = NULL; \
_hs_nmerges = 0; \
while (_hs_p) { \
_hs_nmerges++; \
_hs_q = _hs_p; \
_hs_psize = 0; \
for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
_hs_psize++; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
if (! (_hs_q) ) break; \
} \
_hs_qsize = _hs_insize; \
while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
if (_hs_psize == 0) { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
_hs_e = _hs_p; \
if (_hs_p){ \
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
((void*)((char*)(_hs_p->next) + \
(head)->hh.tbl->hho)) : NULL); \
} \
_hs_psize--; \
} else if (( \
cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
) <= 0) { \
_hs_e = _hs_p; \
if (_hs_p){ \
_hs_p = (UT_hash_handle*)((_hs_p->next) ? \
((void*)((char*)(_hs_p->next) + \
(head)->hh.tbl->hho)) : NULL); \
} \
_hs_psize--; \
} else { \
_hs_e = _hs_q; \
_hs_q = (UT_hash_handle*)((_hs_q->next) ? \
((void*)((char*)(_hs_q->next) + \
(head)->hh.tbl->hho)) : NULL); \
_hs_qsize--; \
} \
if ( _hs_tail ) { \
_hs_tail->next = ((_hs_e) ? \
ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
} else { \
_hs_list = _hs_e; \
} \
if (_hs_e) { \
_hs_e->prev = ((_hs_tail) ? \
ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
} \
_hs_tail = _hs_e; \
} \
_hs_p = _hs_q; \
} \
if (_hs_tail){ \
_hs_tail->next = NULL; \
} \
if ( _hs_nmerges <= 1 ) { \
_hs_looping=0; \
(head)->hh.tbl->tail = _hs_tail; \
DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
} \
_hs_insize *= 2; \
} \
HASH_FSCK(hh,head); \
} \
} while (0)
/* This function selects items from one hash into another hash.
* The end result is that the selected items have dual presence
* in both hashes. There is no copy of the items made; rather
* they are added into the new hash through a secondary hash
* hash handle that must be present in the structure. */
#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
do { \
unsigned _src_bkt, _dst_bkt; \
void *_last_elt=NULL, *_elt; \
UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
if (src) { \
for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
_src_hh; \
_src_hh = _src_hh->hh_next) { \
_elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
if (cond(_elt)) { \
_dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
_dst_hh->key = _src_hh->key; \
_dst_hh->keylen = _src_hh->keylen; \
_dst_hh->hashv = _src_hh->hashv; \
_dst_hh->prev = _last_elt; \
_dst_hh->next = NULL; \
if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
if (!dst) { \
DECLTYPE_ASSIGN(dst,_elt); \
HASH_MAKE_TABLE(hh_dst,dst); \
} else { \
_dst_hh->tbl = (dst)->hh_dst.tbl; \
} \
HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
(dst)->hh_dst.tbl->num_items++; \
_last_elt = _elt; \
_last_elt_hh = _dst_hh; \
} \
} \
} \
} \
HASH_FSCK(hh_dst,dst); \
} while (0)
#define HASH_CLEAR(hh,head) \
do { \
if (head) { \
uthash_free((head)->hh.tbl->buckets, \
(head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
HASH_BLOOM_FREE((head)->hh.tbl); \
uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
(head)=NULL; \
} \
} while(0)
#define HASH_OVERHEAD(hh,head) \
(size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \
((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \
(sizeof(UT_hash_table)) + \
(HASH_BLOOM_BYTELEN)))
#ifdef NO_DECLTYPE
#define HASH_ITER(hh,head,el,tmp) \
for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
#else
#define HASH_ITER(hh,head,el,tmp) \
for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
#endif
/* obtain a count of items in the hash */
#define HASH_COUNT(head) HASH_CNT(hh,head)
#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
typedef struct UT_hash_bucket {
struct UT_hash_handle *hh_head;
unsigned count;
/* expand_mult is normally set to 0. In this situation, the max chain length
* threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
* the bucket's chain exceeds this length, bucket expansion is triggered).
* However, setting expand_mult to a non-zero value delays bucket expansion
* (that would be triggered by additions to this particular bucket)
* until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
* (The multiplier is simply expand_mult+1). The whole idea of this
* multiplier is to reduce bucket expansions, since they are expensive, in
* situations where we know that a particular bucket tends to be overused.
* It is better to let its chain length grow to a longer yet-still-bounded
* value, than to do an O(n) bucket expansion too often.
*/
unsigned expand_mult;
} UT_hash_bucket;
/* random signature used only to find hash tables in external analysis */
#define HASH_SIGNATURE 0xa0111fe1
#define HASH_BLOOM_SIGNATURE 0xb12220f2
typedef struct UT_hash_table {
UT_hash_bucket *buckets;
unsigned num_buckets, log2_num_buckets;
unsigned num_items;
struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
/* in an ideal situation (all buckets used equally), no bucket would have
* more than ceil(#items/#buckets) items. that's the ideal chain length. */
unsigned ideal_chain_maxlen;
/* nonideal_items is the number of items in the hash whose chain position
* exceeds the ideal chain maxlen. these items pay the penalty for an uneven
* hash distribution; reaching them in a chain traversal takes >ideal steps */
unsigned nonideal_items;
/* ineffective expands occur when a bucket doubling was performed, but
* afterward, more than half the items in the hash had nonideal chain
* positions. If this happens on two consecutive expansions we inhibit any
* further expansion, as it's not helping; this happens when the hash
* function isn't a good fit for the key domain. When expansion is inhibited
* the hash will still work, albeit no longer in constant time. */
unsigned ineff_expands, noexpand;
uint32_t signature; /* used only to find hash tables in external analysis */
#ifdef HASH_BLOOM
uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
uint8_t *bloom_bv;
char bloom_nbits;
#endif
} UT_hash_table;
typedef struct UT_hash_handle {
struct UT_hash_table *tbl;
void *prev; /* prev element in app order */
void *next; /* next element in app order */
struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
struct UT_hash_handle *hh_next; /* next hh in bucket order */
void *key; /* ptr to enclosing struct's key */
unsigned keylen; /* enclosing struct's key len */
unsigned hashv; /* result of hash-fcn(key) */
} UT_hash_handle;
#endif /* UTHASH_H */

103
vendor/swoole/include/websocket.h vendored Executable file
View File

@ -0,0 +1,103 @@
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SW_WEBSOCKET_H_
#define SW_WEBSOCKET_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "http.h"
#define SW_WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define SW_WEBSOCKET_HEADER_LEN 2
#define SW_WEBSOCKET_MASK_LEN 4
#define SW_WEBSOCKET_MASK_DATA "258E"
#define SW_WEBSOCKET_EXT16_LENGTH 0x7E
#define SW_WEBSOCKET_EXT16_MAX_LEN 0xFFFF
#define SW_WEBSOCKET_EXT64_LENGTH 0x7F
#define SW_WEBSOCKET_MASKED(frm) (frm->header.MASK)
#define FRAME_SET_FIN(BYTE) (((BYTE) & 0x01) << 7)
#define FRAME_SET_OPCODE(BYTE) ((BYTE) & 0x0F)
#define FRAME_SET_MASK(BYTE) (((BYTE) & 0x01) << 7)
#define FRAME_SET_LENGTH(X64, IDX) (unsigned char)(((X64) >> ((IDX)*8)) & 0xFF)
enum swWebsocketStatus
{
WEBSOCKET_STATUS_CONNECTION = 1,
WEBSOCKET_STATUS_HANDSHAKE = 2,
WEBSOCKET_STATUS_ACTIVE = 3,
};
typedef struct
{
/**
* fin:1 rsv1:1 rsv2:1 rsv3:1 opcode:4
*/
struct
{
uchar OPCODE :4;
uchar RSV3 :1;
uchar RSV2 :1;
uchar RSV1 :1;
uchar FIN :1;
uchar LENGTH :7;
uchar MASK :1;
} header;
char mask_key[SW_WEBSOCKET_MASK_LEN];
uint16_t header_length;
size_t payload_length;
char *payload;
} swWebSocket_frame;
enum swWebsocketCode
{
WEBSOCKET_OPCODE_CONTINUATION_FRAME = 0x0,
WEBSOCKET_OPCODE_TEXT_FRAME = 0x1,
WEBSOCKET_OPCODE_BINARY_FRAME = 0x2,
WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8,
WEBSOCKET_OPCODE_PING = 0x9,
WEBSOCKET_OPCODE_PONG = 0xa,
WEBSOCKET_CLOSE_NORMAL = 1000,
WEBSOCKET_CLOSE_GOING_AWAY = 1001,
WEBSOCKET_CLOSE_PROTOCOL_ERROR = 1002,
WEBSOCKET_CLOSE_DATA_ERROR = 1003,
WEBSOCKET_CLOSE_STATUS_ERROR = 1005,
WEBSOCKET_CLOSE_ABNORMAL = 1006,
WEBSOCKET_CLOSE_MESSAGE_ERROR = 1007,
WEBSOCKET_CLOSE_POLICY_ERROR = 1008,
WEBSOCKET_CLOSE_MESSAGE_TOO_BIG = 1009,
WEBSOCKET_CLOSE_EXTENSION_MISSING = 1010,
WEBSOCKET_CLOSE_SERVER_ERROR = 1011,
WEBSOCKET_CLOSE_TLS = 1015,
WEBSOCKET_VERSION = 13,
};
int swWebSocket_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length);
void swWebSocket_encode(swString *buffer, char *data, size_t length, char opcode, int finish, int mask);
void swWebSocket_decode(swWebSocket_frame *frame, swString *data);
void swWebSocket_print_frame(swWebSocket_frame *frame);
int swWebSocket_dispatch_frame(swConnection *conn, char *data, uint32_t length);
#ifdef __cplusplus
}
#endif
#endif /* SW_WEBSOCKET_H_ */