add linux lib

This commit is contained in:
yangchao 2021-10-20 10:49:04 +08:00
parent 1aac2fcd8d
commit dd53ccade6
633 changed files with 228150 additions and 1 deletions

View File

@ -7,7 +7,7 @@ set(CC_EXTERNAL_PRIVATE_DEFINITIONS)
list(APPEND CC_EXTERNAL_PRIVATE_DEFINITIONS
TBB_USE_EXCEPTIONS=0 # no rtti for now
)
MESSAGE(STATUS "platform path: ${platform_spec_path}")
include(${CMAKE_CURRENT_LIST_DIR}/cmake/CocosExternalConfig.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/sources/CMakeLists.txt)
@ -28,4 +28,6 @@ elseif(APPLE)
endif()
elseif(OHOS)
include(${CMAKE_CURRENT_LIST_DIR}/ohos/CMakeLists.txt)
elseif(LINUX)
include(${CMAKE_CURRENT_LIST_DIR}/linux/CMakeLists.txt)
endif()

View File

@ -15,6 +15,9 @@ elseif(MACOSX)
elseif(OHOS)
set(platform_name ohos)
set(platform_spec_path ohos/${OHOS_ARCH})
elseif(LINUX)
set(platform_name linux)
set(platform_spec_path linux)
endif()
set(platform_spec_path "${CMAKE_CURRENT_LIST_DIR}/../${platform_spec_path}")

125
linux/CMakeLists.txt Normal file
View File

@ -0,0 +1,125 @@
set(linux_lib_dir ${platform_spec_path}/lib)
MESSAGE(STATUS "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx ${platform_spec_path}")
add_library(uv STATIC IMPORTED GLOBAL)
set_target_properties(uv PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libuv_a.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libuv
)
add_library(mpg123 SHARED IMPORTED GLOBAL)
set_target_properties(mpg123 PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libmpg123.so
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/mpg123
)
add_library(ogg STATIC IMPORTED GLOBAL)
set_target_properties(ogg PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libogg.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/ogg
)
add_library(vorbisfile STATIC IMPORTED GLOBAL)
set_target_properties(vorbisfile PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libvorbisfile.a
)
add_library(vorbis STATIC IMPORTED GLOBAL)
set_target_properties(vorbis PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libvorbis.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/vorbis
)
add_library(libz SHARED IMPORTED GLOBAL)
set_target_properties(libz PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libz.so.1.2.11
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libz
)
add_library(sqlite3 SHARED IMPORTED GLOBAL)
set_target_properties(sqlite3 PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libsqlite3.so.0.8.6
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/sqlite
)
add_library(v8 STATIC IMPORTED GLOBAL)
set_target_properties(v8 PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libv8_monolith.a
)
add_library(openal SHARED IMPORTED GLOBAL)
set_target_properties(openal PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libopenal.so.1.21.1
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openal-soft
)
add_library(jpeg STATIC IMPORTED GLOBAL)
set_target_properties(jpeg PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libjpeg.a
)
add_library(png STATIC IMPORTED GLOBAL)
set_target_properties(png PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libpng16.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libpng
)
add_library(ssl STATIC IMPORTED GLOBAL)
set_target_properties(ssl PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libssl.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/openssl
)
add_library(crypto STATIC IMPORTED GLOBAL)
set_target_properties(crypto PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libcrypto.a
)
add_library(websockets STATIC IMPORTED GLOBAL)
set_target_properties(websockets PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libwebsockets.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebsockets
)
add_library(curl SHARED IMPORTED GLOBAL)
set_target_properties(curl PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libcurl.so
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/curl
)
add_library(webp STATIC IMPORTED GLOBAL)
set_target_properties(webp PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libwebp.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/libwebp
)
add_library(tbb STATIC IMPORTED GLOBAL)
set_target_properties(tbb PROPERTIES
IMPORTED_LOCATION ${linux_lib_dir}/libtbb_static.a
INTERFACE_INCLUDE_DIRECTORIES ${platform_spec_path}/include/tbb
)
list(APPEND CC_EXTERNAL_INCLUDES
${platform_spec_path}/include
${platform_spec_path}/include/v8
${platform_spec_path}/include/uv
)
list(APPEND CC_EXTERNAL_LIBS
uv
vorbisfile
vorbis
ogg
libz
sqlite3
v8
openal
mpg123
jpeg
png
websockets
ssl
crypto
curl
webp
tbb
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
#ifndef CURLINC_CURLVER_H
#define CURLINC_CURLVER_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* This header file contains nothing but libcurl version info, generated by
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2021 Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.79.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 79
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal (using 8 bits each). All three numbers are always represented
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
appears as "0x090b07".
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
Note: This define is the full hex number and _does not_ use the
CURL_VERSION_BITS() macro since curl's own configure script greps for it
and needs it to contain the full number.
*/
#define LIBCURL_VERSION_NUM 0x074f00
/*
* This is the date and time when the full source package was created. The
* timestamp is not stored in git, as the timestamp is properly set in the
* tarballs by the maketgz script.
*
* The format of the date follows this template:
*
* "2007-11-23"
*/
#define LIBCURL_TIMESTAMP "[unreleased]"
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
#define CURL_AT_LEAST_VERSION(x,y,z) \
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
#endif /* CURLINC_CURLVER_H */

View File

@ -0,0 +1,123 @@
#ifndef CURLINC_EASY_H
#define CURLINC_EASY_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/* Flag bits in the curl_blob struct: */
#define CURL_BLOB_COPY 1 /* tell libcurl to copy the data */
#define CURL_BLOB_NOCOPY 0 /* tell libcurl to NOT copy the data */
struct curl_blob {
void *data;
size_t len;
unsigned int flags; /* bit 0 is defined, the rest are reserved and should be
left zeroes */
};
CURL_EXTERN CURL *curl_easy_init(void);
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
CURL_EXTERN void curl_easy_cleanup(CURL *curl);
/*
* NAME curl_easy_getinfo()
*
* DESCRIPTION
*
* Request internal information from the curl session with this function. The
* third argument MUST be a pointer to a long, a pointer to a char * or a
* pointer to a double (as the documentation describes elsewhere). The data
* pointed to will be filled in accordingly and can be relied upon only if the
* function returns CURLE_OK. This function is intended to get used *AFTER* a
* performed transfer, all results from this function are undefined until the
* transfer is completed.
*/
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
/*
* NAME curl_easy_duphandle()
*
* DESCRIPTION
*
* Creates a new curl session handle with the same options set for the handle
* passed in. Duplicating a handle could only be a matter of cloning data and
* options, internal state info and things like persistent connections cannot
* be transferred. It is useful in multithreaded applications when you can run
* curl_easy_duphandle() for each new thread to avoid a series of identical
* curl_easy_setopt() invokes in every thread.
*/
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
/*
* NAME curl_easy_reset()
*
* DESCRIPTION
*
* Re-initializes a CURL handle to the default values. This puts back the
* handle to the same state as it was in when it was just created.
*
* It does keep: live connections, the Session ID cache, the DNS cache and the
* cookies.
*/
CURL_EXTERN void curl_easy_reset(CURL *curl);
/*
* NAME curl_easy_recv()
*
* DESCRIPTION
*
* Receives data from the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
size_t *n);
/*
* NAME curl_easy_send()
*
* DESCRIPTION
*
* Sends data over the connected socket. Use after successful
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
*/
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
size_t buflen, size_t *n);
/*
* NAME curl_easy_upkeep()
*
* DESCRIPTION
*
* Performs connection upkeep for the given session handle.
*/
CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,50 @@
#ifndef CURLINC_MPRINTF_H
#define CURLINC_MPRINTF_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdarg.h>
#include <stdio.h> /* needed for FILE */
#include "curl.h" /* for CURL_EXTERN */
#ifdef __cplusplus
extern "C" {
#endif
CURL_EXTERN int curl_mprintf(const char *format, ...);
CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
const char *format, ...);
CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
const char *format, va_list args);
CURL_EXTERN char *curl_maprintf(const char *format, ...);
CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
#ifdef __cplusplus
}
#endif
#endif /* CURLINC_MPRINTF_H */

View File

@ -0,0 +1,456 @@
#ifndef CURLINC_MULTI_H
#define CURLINC_MULTI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
This is an "external" header file. Don't give away any internals here!
GOALS
o Enable a "pull" interface. The application that uses libcurl decides where
and when to ask libcurl to get/send data.
o Enable multiple simultaneous transfers in the same thread without making it
complicated for the application.
o Enable the application to select() on its own file descriptors and curl's
file descriptors simultaneous easily.
*/
/*
* This header file should not really need to include "curl.h" since curl.h
* itself includes this file and we expect user applications to do #include
* <curl/curl.h> without the need for especially including multi.h.
*
* For some reason we added this include here at one point, and rather than to
* break existing (wrongly written) libcurl applications, we leave it as-is
* but with this warning attached.
*/
#include "curl.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
typedef struct Curl_multi CURLM;
#else
typedef void CURLM;
#endif
typedef enum {
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
curl_multi_socket*() soon */
CURLM_OK,
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
CURLM_BAD_SOCKET, /* the passed in socket argument did not match */
CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */
CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was
attempted to get added - again */
CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
callback */
CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */
CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
CURLM_LAST
} CURLMcode;
/* just to make code nicer when using curl_multi_socket() you can now check
for CURLM_CALL_MULTI_SOCKET too in the same style it works for
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
/* bitmask bits for CURLMOPT_PIPELINING */
#define CURLPIPE_NOTHING 0L
#define CURLPIPE_HTTP1 1L
#define CURLPIPE_MULTIPLEX 2L
typedef enum {
CURLMSG_NONE, /* first, not used */
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
the CURLcode of the transfer */
CURLMSG_LAST /* last, not used */
} CURLMSG;
struct CURLMsg {
CURLMSG msg; /* what this message means */
CURL *easy_handle; /* the handle it concerns */
union {
void *whatever; /* message-specific data */
CURLcode result; /* return code for transfer */
} data;
};
typedef struct CURLMsg CURLMsg;
/* Based on poll(2) structure and values.
* We don't use pollfd and POLL* constants explicitly
* to cover platforms without poll(). */
#define CURL_WAIT_POLLIN 0x0001
#define CURL_WAIT_POLLPRI 0x0002
#define CURL_WAIT_POLLOUT 0x0004
struct curl_waitfd {
curl_socket_t fd;
short events;
short revents; /* not supported yet */
};
/*
* Name: curl_multi_init()
*
* Desc: inititalize multi-style curl usage
*
* Returns: a new CURLM handle to use in all 'curl_multi' functions.
*/
CURL_EXTERN CURLM *curl_multi_init(void);
/*
* Name: curl_multi_add_handle()
*
* Desc: add a standard curl handle to the multi stack
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
CURL *curl_handle);
/*
* Name: curl_multi_remove_handle()
*
* Desc: removes a curl handle from the multi stack again
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
CURL *curl_handle);
/*
* Name: curl_multi_fdset()
*
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
* poll() on. We want curl_multi_perform() called as soon as one of
* them are ready.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
fd_set *read_fd_set,
fd_set *write_fd_set,
fd_set *exc_fd_set,
int *max_fd);
/*
* Name: curl_multi_wait()
*
* Desc: Poll on all fds within a CURLM set as well as any
* additional fds passed to the function.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
int *ret);
/*
* Name: curl_multi_poll()
*
* Desc: Poll on all fds within a CURLM set as well as any
* additional fds passed to the function.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
struct curl_waitfd extra_fds[],
unsigned int extra_nfds,
int timeout_ms,
int *ret);
/*
* Name: curl_multi_wakeup()
*
* Desc: wakes up a sleeping curl_multi_poll call.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
/*
* Name: curl_multi_perform()
*
* Desc: When the app thinks there's data available for curl it calls this
* function to read/write whatever there is right now. This returns
* as soon as the reads and writes are done. This function does not
* require that there actually is data available for reading or that
* data can be written, it can be called just in case. It returns
* the number of handles that still transfer data in the second
* argument's integer-pointer.
*
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
* returns errors etc regarding the whole multi stack. There might
* still have occurred problems on individual transfers even when
* this returns OK.
*/
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
int *running_handles);
/*
* Name: curl_multi_cleanup()
*
* Desc: Cleans up and removes a whole multi stack. It does not free or
* touch any individual easy handles in any way. We need to define
* in what state those handles will be if this function is called
* in the middle of a transfer.
*
* Returns: CURLMcode type, general multi error code.
*/
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
/*
* Name: curl_multi_info_read()
*
* Desc: Ask the multi handle if there's any messages/informationals from
* the individual transfers. Messages include informationals such as
* error code from the transfer or just the fact that a transfer is
* completed. More details on these should be written down as well.
*
* Repeated calls to this function will return a new struct each
* time, until a special "end of msgs" struct is returned as a signal
* that there is no more to get at this point.
*
* The data the returned pointer points to will not survive calling
* curl_multi_cleanup().
*
* The 'CURLMsg' struct is meant to be very simple and only contain
* very basic information. If more involved information is wanted,
* we will provide the particular "transfer handle" in that struct
* and that should/could/would be used in subsequent
* curl_easy_getinfo() calls (or similar). The point being that we
* must never expose complex structs to applications, as then we'll
* undoubtably get backwards compatibility problems in the future.
*
* Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
* of structs. It also writes the number of messages left in the
* queue (after this read) in the integer the second argument points
* to.
*/
CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
int *msgs_in_queue);
/*
* Name: curl_multi_strerror()
*
* Desc: The curl_multi_strerror function may be used to turn a CURLMcode
* value into the equivalent human readable error string. This is
* useful for printing meaningful error messages.
*
* Returns: A pointer to a null-terminated error message.
*/
CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
/*
* Name: curl_multi_socket() and
* curl_multi_socket_all()
*
* Desc: An alternative version of curl_multi_perform() that allows the
* application to pass in one of the file descriptors that have been
* detected to have "action" on them and let libcurl perform.
* See man page for details.
*/
#define CURL_POLL_NONE 0
#define CURL_POLL_IN 1
#define CURL_POLL_OUT 2
#define CURL_POLL_INOUT 3
#define CURL_POLL_REMOVE 4
#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
#define CURL_CSELECT_IN 0x01
#define CURL_CSELECT_OUT 0x02
#define CURL_CSELECT_ERR 0x04
typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
void *userp, /* private callback
pointer */
void *socketp); /* private socket
pointer */
/*
* Name: curl_multi_timer_callback
*
* Desc: Called by libcurl whenever the library detects a change in the
* maximum number of milliseconds the app is allowed to wait before
* curl_multi_socket() or curl_multi_perform() must be called
* (to allow libcurl's timed events to take place).
*
* Returns: The callback should return zero.
*/
typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */
long timeout_ms, /* see above */
void *userp); /* private callback
pointer */
CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
curl_socket_t s,
int ev_bitmask,
int *running_handles);
CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
int *running_handles);
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
/* This macro below was added in 7.16.3 to push users who recompile to use
the new curl_multi_socket_action() instead of the old curl_multi_socket()
*/
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
#endif
/*
* Name: curl_multi_timeout()
*
* Desc: Returns the maximum number of milliseconds the app is allowed to
* wait before curl_multi_socket() or curl_multi_perform() must be
* called (to allow libcurl's timed events to take place).
*
* Returns: CURLM error code.
*/
CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
long *milliseconds);
typedef enum {
/* This is the socket callback function pointer */
CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1),
/* This is the argument passed to the socket callback */
CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
/* set to 1 to enable pipelining for this multi handle */
CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
/* This is the timer callback function pointer */
CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
/* This is the argument passed to the timer callback */
CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5),
/* maximum number of entries in the connection cache */
CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6),
/* maximum number of (pipelining) connections to one host */
CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7),
/* maximum number of requests in a pipeline */
CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8),
/* a connection with a content-length longer than this
will not be considered for pipelining */
CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9),
/* a connection with a chunk length longer than this
will not be considered for pipelining */
CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10),
/* a list of site names(+port) that are blocked from pipelining */
CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11),
/* a list of server types that are blocked from pipelining */
CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12),
/* maximum number of open connections in total */
CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13),
/* This is the server push callback function pointer */
CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14),
/* This is the argument passed to the server push callback */
CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15),
/* maximum number of concurrent streams to support on a connection */
CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16),
CURLMOPT_LASTENTRY /* the last unused */
} CURLMoption;
/*
* Name: curl_multi_setopt()
*
* Desc: Sets options for the multi handle.
*
* Returns: CURLM error code.
*/
CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
CURLMoption option, ...);
/*
* Name: curl_multi_assign()
*
* Desc: This function sets an association in the multi handle between the
* given socket and a private pointer of the application. This is
* (only) useful for curl_multi_socket uses.
*
* Returns: CURLM error code.
*/
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
curl_socket_t sockfd, void *sockp);
/*
* Name: curl_push_callback
*
* Desc: This callback gets called when a new stream is being pushed by the
* server. It approves or denies the new stream. It can also decide
* to completely fail the connection.
*
* Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
*/
#define CURL_PUSH_OK 0
#define CURL_PUSH_DENY 1
#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
struct curl_pushheaders; /* forward declaration only */
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
size_t num);
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
const char *name);
typedef int (*curl_push_callback)(CURL *parent,
CURL *easy,
size_t num_headers,
struct curl_pushheaders *headers,
void *userp);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif

View File

@ -0,0 +1,68 @@
#ifndef CURLINC_OPTIONS_H
#define CURLINC_OPTIONS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
CURLOT_LONG, /* long (a range of values) */
CURLOT_VALUES, /* (a defined set or bitmask) */
CURLOT_OFF_T, /* curl_off_t (a range of values) */
CURLOT_OBJECT, /* pointer (void *) */
CURLOT_STRING, /* (char * to zero terminated buffer) */
CURLOT_SLIST, /* (struct curl_slist *) */
CURLOT_CBPTR, /* (void * passed as-is to a callback) */
CURLOT_BLOB, /* blob (struct curl_blob *) */
CURLOT_FUNCTION /* function pointer */
} curl_easytype;
/* Flag bits */
/* "alias" means it is provided for old programs to remain functional,
we prefer another name */
#define CURLOT_FLAG_ALIAS (1<<0)
/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
to use for curl_easy_setopt() for the given id */
struct curl_easyoption {
const char *name;
CURLoption id;
curl_easytype type;
unsigned int flags;
};
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_name(const char *name);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_id (CURLoption id);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_next(const struct curl_easyoption *prev);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* CURLINC_OPTIONS_H */

View File

@ -0,0 +1,33 @@
#ifndef CURLINC_STDCHEADERS_H
#define CURLINC_STDCHEADERS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <sys/types.h>
size_t fread(void *, size_t, size_t, FILE *);
size_t fwrite(const void *, size_t, size_t, FILE *);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);
#endif /* CURLINC_STDCHEADERS_H */

View File

@ -0,0 +1,504 @@
#ifndef CURLINC_SYSTEM_H
#define CURLINC_SYSTEM_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Try to keep one section per platform, compiler and architecture, otherwise,
* if an existing section is reused for a different one and later on the
* original is adjusted, probably the piggybacking one can be adversely
* changed.
*
* In order to differentiate between platforms/compilers/architectures use
* only compiler built in predefined preprocessor symbols.
*
* curl_off_t
* ----------
*
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
* wide signed integral data type. The width of this data type must remain
* constant and independent of any possible large file support settings.
*
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
* wide signed integral data type if there is no 64-bit type.
*
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
* only be violated if off_t is the only 64-bit data type available and the
* size of off_t is independent of large file support settings. Keep your
* build on the safe side avoiding an off_t gating. If you have a 64-bit
* off_t then take for sure that another 64-bit data type exists, dig deeper
* and you will find it.
*
*/
#if defined(__DJGPP__) || defined(__GO32__)
# if defined(__DJGPP__) && (__DJGPP__ > 1)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__SALFORDC__)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__BORLANDC__)
# if (__BORLANDC__ < 0x520)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__TURBOC__)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__WATCOMC__)
# if defined(__386__)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__POCC__)
# if (__POCC__ < 280)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# elif defined(_MSC_VER)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__LCC__)
# if defined(__e2k__) /* MCST eLbrus C Compiler */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# else /* Local (or Little) C Compiler */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
# endif
#elif defined(__SYMBIAN32__)
# if defined(__EABI__) /* Treat all ARM compilers equally */
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__CW32__)
# pragma longlong on
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__VC32__)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__MWERKS__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(_WIN32_WCE)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__MINGW32__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_WS2TCPIP_H 1
#elif defined(__VMS)
# if defined(__VAX)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__OS400__)
# if defined(__ILEC400__)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__MVS__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# elif defined(_LP64)
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(__370__)
# if defined(__IBMC__) || defined(__IBMCPP__)
# if defined(_ILP32)
# elif defined(_LP64)
# endif
# if defined(_LONG_LONG)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
#elif defined(TPF)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#elif defined(__TINYC__) /* also known as tcc */
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */
# if !defined(__LP64) && (defined(__ILP32) || \
defined(__i386) || \
defined(__sparcv8) || \
defined(__sparcv8plus))
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__LP64) || \
defined(__amd64) || defined(__sparcv9)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__xlc__) /* IBM xlc compiler */
# if !defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
/* ===================================== */
/* KEEP MSVC THE PENULTIMATE ENTRY */
/* ===================================== */
#elif defined(_MSC_VER)
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
# define CURL_TYPEOF_CURL_OFF_T __int64
# define CURL_FORMAT_CURL_OFF_T "I64d"
# define CURL_FORMAT_CURL_OFF_TU "I64u"
# define CURL_SUFFIX_CURL_OFF_T i64
# define CURL_SUFFIX_CURL_OFF_TU ui64
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T int
/* ===================================== */
/* KEEP GENERIC GCC THE LAST ENTRY */
/* ===================================== */
#elif defined(__GNUC__) && !defined(_SCO_DS)
# if !defined(__LP64__) && \
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \
defined(__sparc__) || defined(__mips__) || defined(__sh__) || \
defined(__XTENSA__) || \
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \
(defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L))
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# elif defined(__LP64__) || \
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
defined(__e2k__) || \
(defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \
(defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L)
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#else
/* generic "safe guess" on old 32 bit style */
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# define CURL_TYPEOF_CURL_SOCKLEN_T int
#endif
#ifdef _AIX
/* AIX needs <sys/poll.h> */
#define CURL_PULL_SYS_POLL_H
#endif
/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */
/* ws2tcpip.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_WS2TCPIP_H
# include <winsock2.h>
# include <windows.h>
# include <ws2tcpip.h>
#endif
/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */
/* sys/types.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_TYPES_H
# include <sys/types.h>
#endif
/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
/* sys/socket.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */
/* sys/poll.h is required here to properly make type definitions below. */
#ifdef CURL_PULL_SYS_POLL_H
# include <sys/poll.h>
#endif
/* Data type definition of curl_socklen_t. */
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
#endif
/* Data type definition of curl_off_t. */
#ifdef CURL_TYPEOF_CURL_OFF_T
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
#endif
/*
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
* these to be visible and exported by the external libcurl interface API,
* while also making them visible to the library internals, simply including
* curl_setup.h, without actually needing to include curl.h internally.
* If some day this section would grow big enough, all this should be moved
* to its own header file.
*/
/*
* Figure out if we can use the ## preprocessor operator, which is supported
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
* or __cplusplus so we need to carefully check for them too.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
defined(__ILEC400__)
/* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP
#else
/* This compiler is believed NOT to have an ISO compatible preprocessor */
#undef CURL_ISOCPP
#endif
/*
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
*/
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
# define CURLINC_OFF_T_C_HLPR2(x) x
# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x)
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \
CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
#else
# ifdef CURL_ISOCPP
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
# else
# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
# endif
# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix)
# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
#endif
#endif /* CURLINC_SYSTEM_H */

View File

@ -0,0 +1,705 @@
#ifndef CURLINC_TYPECHECK_GCC_H
#define CURLINC_TYPECHECK_GCC_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* wraps curl_easy_setopt() with typechecking */
/* To add a new kind of warning, add an
* if(curlcheck_sometype_option(_curl_opt))
* if(!curlcheck_sometype(value))
* _curl_easy_setopt_err_sometype();
* block and define curlcheck_sometype_option, curlcheck_sometype and
* _curl_easy_setopt_err_sometype below
*
* NOTE: We use two nested 'if' statements here instead of the && operator, in
* order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x
* when compiling with -Wlogical-op.
*
* To add an option that uses the same type as an existing option, you'll just
* need to extend the appropriate _curl_*_option macro
*/
#define curl_easy_setopt(handle, option, value) \
__extension__({ \
__typeof__(option) _curl_opt = option; \
if(__builtin_constant_p(_curl_opt)) { \
if(curlcheck_long_option(_curl_opt)) \
if(!curlcheck_long(value)) \
_curl_easy_setopt_err_long(); \
if(curlcheck_off_t_option(_curl_opt)) \
if(!curlcheck_off_t(value)) \
_curl_easy_setopt_err_curl_off_t(); \
if(curlcheck_string_option(_curl_opt)) \
if(!curlcheck_string(value)) \
_curl_easy_setopt_err_string(); \
if(curlcheck_write_cb_option(_curl_opt)) \
if(!curlcheck_write_cb(value)) \
_curl_easy_setopt_err_write_callback(); \
if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \
if(!curlcheck_resolver_start_callback(value)) \
_curl_easy_setopt_err_resolver_start_callback(); \
if((_curl_opt) == CURLOPT_READFUNCTION) \
if(!curlcheck_read_cb(value)) \
_curl_easy_setopt_err_read_cb(); \
if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \
if(!curlcheck_ioctl_cb(value)) \
_curl_easy_setopt_err_ioctl_cb(); \
if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \
if(!curlcheck_sockopt_cb(value)) \
_curl_easy_setopt_err_sockopt_cb(); \
if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \
if(!curlcheck_opensocket_cb(value)) \
_curl_easy_setopt_err_opensocket_cb(); \
if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \
if(!curlcheck_progress_cb(value)) \
_curl_easy_setopt_err_progress_cb(); \
if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \
if(!curlcheck_debug_cb(value)) \
_curl_easy_setopt_err_debug_cb(); \
if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \
if(!curlcheck_ssl_ctx_cb(value)) \
_curl_easy_setopt_err_ssl_ctx_cb(); \
if(curlcheck_conv_cb_option(_curl_opt)) \
if(!curlcheck_conv_cb(value)) \
_curl_easy_setopt_err_conv_cb(); \
if((_curl_opt) == CURLOPT_SEEKFUNCTION) \
if(!curlcheck_seek_cb(value)) \
_curl_easy_setopt_err_seek_cb(); \
if(curlcheck_cb_data_option(_curl_opt)) \
if(!curlcheck_cb_data(value)) \
_curl_easy_setopt_err_cb_data(); \
if((_curl_opt) == CURLOPT_ERRORBUFFER) \
if(!curlcheck_error_buffer(value)) \
_curl_easy_setopt_err_error_buffer(); \
if((_curl_opt) == CURLOPT_STDERR) \
if(!curlcheck_FILE(value)) \
_curl_easy_setopt_err_FILE(); \
if(curlcheck_postfields_option(_curl_opt)) \
if(!curlcheck_postfields(value)) \
_curl_easy_setopt_err_postfields(); \
if((_curl_opt) == CURLOPT_HTTPPOST) \
if(!curlcheck_arr((value), struct curl_httppost)) \
_curl_easy_setopt_err_curl_httpost(); \
if((_curl_opt) == CURLOPT_MIMEPOST) \
if(!curlcheck_ptr((value), curl_mime)) \
_curl_easy_setopt_err_curl_mimepost(); \
if(curlcheck_slist_option(_curl_opt)) \
if(!curlcheck_arr((value), struct curl_slist)) \
_curl_easy_setopt_err_curl_slist(); \
if((_curl_opt) == CURLOPT_SHARE) \
if(!curlcheck_ptr((value), CURLSH)) \
_curl_easy_setopt_err_CURLSH(); \
} \
curl_easy_setopt(handle, _curl_opt, value); \
})
/* wraps curl_easy_getinfo() with typechecking */
#define curl_easy_getinfo(handle, info, arg) \
__extension__({ \
__typeof__(info) _curl_info = info; \
if(__builtin_constant_p(_curl_info)) { \
if(curlcheck_string_info(_curl_info)) \
if(!curlcheck_arr((arg), char *)) \
_curl_easy_getinfo_err_string(); \
if(curlcheck_long_info(_curl_info)) \
if(!curlcheck_arr((arg), long)) \
_curl_easy_getinfo_err_long(); \
if(curlcheck_double_info(_curl_info)) \
if(!curlcheck_arr((arg), double)) \
_curl_easy_getinfo_err_double(); \
if(curlcheck_slist_info(_curl_info)) \
if(!curlcheck_arr((arg), struct curl_slist *)) \
_curl_easy_getinfo_err_curl_slist(); \
if(curlcheck_tlssessioninfo_info(_curl_info)) \
if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \
_curl_easy_getinfo_err_curl_tlssesssioninfo(); \
if(curlcheck_certinfo_info(_curl_info)) \
if(!curlcheck_arr((arg), struct curl_certinfo *)) \
_curl_easy_getinfo_err_curl_certinfo(); \
if(curlcheck_socket_info(_curl_info)) \
if(!curlcheck_arr((arg), curl_socket_t)) \
_curl_easy_getinfo_err_curl_socket(); \
if(curlcheck_off_t_info(_curl_info)) \
if(!curlcheck_arr((arg), curl_off_t)) \
_curl_easy_getinfo_err_curl_off_t(); \
} \
curl_easy_getinfo(handle, _curl_info, arg); \
})
/*
* For now, just make sure that the functions are called with three arguments
*/
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
* functions */
/* To define a new warning, use _CURL_WARNING(identifier, "message") */
#define CURLWARNING(id, message) \
static void __attribute__((__warning__(message))) \
__attribute__((__unused__)) __attribute__((__noinline__)) \
id(void) { __asm__(""); }
CURLWARNING(_curl_easy_setopt_err_long,
"curl_easy_setopt expects a long argument for this option")
CURLWARNING(_curl_easy_setopt_err_curl_off_t,
"curl_easy_setopt expects a curl_off_t argument for this option")
CURLWARNING(_curl_easy_setopt_err_string,
"curl_easy_setopt expects a "
"string ('char *' or char[]) argument for this option"
)
CURLWARNING(_curl_easy_setopt_err_write_callback,
"curl_easy_setopt expects a curl_write_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
"curl_easy_setopt expects a "
"curl_resolver_start_callback argument for this option"
)
CURLWARNING(_curl_easy_setopt_err_read_cb,
"curl_easy_setopt expects a curl_read_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
"curl_easy_setopt expects a curl_ioctl_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
"curl_easy_setopt expects a curl_sockopt_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
"curl_easy_setopt expects a "
"curl_opensocket_callback argument for this option"
)
CURLWARNING(_curl_easy_setopt_err_progress_cb,
"curl_easy_setopt expects a curl_progress_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_debug_cb,
"curl_easy_setopt expects a curl_debug_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
"curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_conv_cb,
"curl_easy_setopt expects a curl_conv_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_seek_cb,
"curl_easy_setopt expects a curl_seek_callback argument for this option")
CURLWARNING(_curl_easy_setopt_err_cb_data,
"curl_easy_setopt expects a "
"private data pointer as argument for this option")
CURLWARNING(_curl_easy_setopt_err_error_buffer,
"curl_easy_setopt expects a "
"char buffer of CURL_ERROR_SIZE as argument for this option")
CURLWARNING(_curl_easy_setopt_err_FILE,
"curl_easy_setopt expects a 'FILE *' argument for this option")
CURLWARNING(_curl_easy_setopt_err_postfields,
"curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
CURLWARNING(_curl_easy_setopt_err_curl_httpost,
"curl_easy_setopt expects a 'struct curl_httppost *' "
"argument for this option")
CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
"curl_easy_setopt expects a 'curl_mime *' "
"argument for this option")
CURLWARNING(_curl_easy_setopt_err_curl_slist,
"curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
CURLWARNING(_curl_easy_setopt_err_CURLSH,
"curl_easy_setopt expects a CURLSH* argument for this option")
CURLWARNING(_curl_easy_getinfo_err_string,
"curl_easy_getinfo expects a pointer to 'char *' for this info")
CURLWARNING(_curl_easy_getinfo_err_long,
"curl_easy_getinfo expects a pointer to long for this info")
CURLWARNING(_curl_easy_getinfo_err_double,
"curl_easy_getinfo expects a pointer to double for this info")
CURLWARNING(_curl_easy_getinfo_err_curl_slist,
"curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
"curl_easy_getinfo expects a pointer to "
"'struct curl_tlssessioninfo *' for this info")
CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
"curl_easy_getinfo expects a pointer to "
"'struct curl_certinfo *' for this info")
CURLWARNING(_curl_easy_getinfo_err_curl_socket,
"curl_easy_getinfo expects a pointer to curl_socket_t for this info")
CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
"curl_easy_getinfo expects a pointer to curl_off_t for this info")
/* groups of curl_easy_setops options that take the same type of argument */
/* To add a new option to one of the groups, just add
* (option) == CURLOPT_SOMETHING
* to the or-expression. If the option takes a long or curl_off_t, you don't
* have to do anything
*/
/* evaluates to true if option takes a long argument */
#define curlcheck_long_option(option) \
(0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
#define curlcheck_off_t_option(option) \
(((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
/* evaluates to true if option takes a char* argument */
#define curlcheck_string_option(option) \
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
(option) == CURLOPT_ACCEPT_ENCODING || \
(option) == CURLOPT_ALTSVC || \
(option) == CURLOPT_CAINFO || \
(option) == CURLOPT_CAPATH || \
(option) == CURLOPT_COOKIE || \
(option) == CURLOPT_COOKIEFILE || \
(option) == CURLOPT_COOKIEJAR || \
(option) == CURLOPT_COOKIELIST || \
(option) == CURLOPT_CRLFILE || \
(option) == CURLOPT_CUSTOMREQUEST || \
(option) == CURLOPT_DEFAULT_PROTOCOL || \
(option) == CURLOPT_DNS_INTERFACE || \
(option) == CURLOPT_DNS_LOCAL_IP4 || \
(option) == CURLOPT_DNS_LOCAL_IP6 || \
(option) == CURLOPT_DNS_SERVERS || \
(option) == CURLOPT_DOH_URL || \
(option) == CURLOPT_EGDSOCKET || \
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_FTP_ACCOUNT || \
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
(option) == CURLOPT_HSTS || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_KEYPASSWD || \
(option) == CURLOPT_KRBLEVEL || \
(option) == CURLOPT_LOGIN_OPTIONS || \
(option) == CURLOPT_MAIL_AUTH || \
(option) == CURLOPT_MAIL_FROM || \
(option) == CURLOPT_NETRC_FILE || \
(option) == CURLOPT_NOPROXY || \
(option) == CURLOPT_PASSWORD || \
(option) == CURLOPT_PINNEDPUBLICKEY || \
(option) == CURLOPT_PRE_PROXY || \
(option) == CURLOPT_PROXY || \
(option) == CURLOPT_PROXYPASSWORD || \
(option) == CURLOPT_PROXYUSERNAME || \
(option) == CURLOPT_PROXYUSERPWD || \
(option) == CURLOPT_PROXY_CAINFO || \
(option) == CURLOPT_PROXY_CAPATH || \
(option) == CURLOPT_PROXY_CRLFILE || \
(option) == CURLOPT_PROXY_ISSUERCERT || \
(option) == CURLOPT_PROXY_KEYPASSWD || \
(option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \
(option) == CURLOPT_PROXY_SERVICE_NAME || \
(option) == CURLOPT_PROXY_SSLCERT || \
(option) == CURLOPT_PROXY_SSLCERTTYPE || \
(option) == CURLOPT_PROXY_SSLKEY || \
(option) == CURLOPT_PROXY_SSLKEYTYPE || \
(option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \
(option) == CURLOPT_PROXY_TLS13_CIPHERS || \
(option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \
(option) == CURLOPT_PROXY_TLSAUTH_TYPE || \
(option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \
(option) == CURLOPT_RANDOM_FILE || \
(option) == CURLOPT_RANGE || \
(option) == CURLOPT_REFERER || \
(option) == CURLOPT_REQUEST_TARGET || \
(option) == CURLOPT_RTSP_SESSION_ID || \
(option) == CURLOPT_RTSP_STREAM_URI || \
(option) == CURLOPT_RTSP_TRANSPORT || \
(option) == CURLOPT_SASL_AUTHZID || \
(option) == CURLOPT_SERVICE_NAME || \
(option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \
(option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \
(option) == CURLOPT_SSH_KNOWNHOSTS || \
(option) == CURLOPT_SSH_PRIVATE_KEYFILE || \
(option) == CURLOPT_SSH_PUBLIC_KEYFILE || \
(option) == CURLOPT_SSLCERT || \
(option) == CURLOPT_SSLCERTTYPE || \
(option) == CURLOPT_SSLENGINE || \
(option) == CURLOPT_SSLKEY || \
(option) == CURLOPT_SSLKEYTYPE || \
(option) == CURLOPT_SSL_CIPHER_LIST || \
(option) == CURLOPT_TLS13_CIPHERS || \
(option) == CURLOPT_TLSAUTH_PASSWORD || \
(option) == CURLOPT_TLSAUTH_TYPE || \
(option) == CURLOPT_TLSAUTH_USERNAME || \
(option) == CURLOPT_UNIX_SOCKET_PATH || \
(option) == CURLOPT_URL || \
(option) == CURLOPT_USERAGENT || \
(option) == CURLOPT_USERNAME || \
(option) == CURLOPT_AWS_SIGV4 || \
(option) == CURLOPT_USERPWD || \
(option) == CURLOPT_XOAUTH2_BEARER || \
(option) == CURLOPT_SSL_EC_CURVES || \
0)
/* evaluates to true if option takes a curl_write_callback argument */
#define curlcheck_write_cb_option(option) \
((option) == CURLOPT_HEADERFUNCTION || \
(option) == CURLOPT_WRITEFUNCTION)
/* evaluates to true if option takes a curl_conv_callback argument */
#define curlcheck_conv_cb_option(option) \
((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \
(option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \
(option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
/* evaluates to true if option takes a data argument to pass to a callback */
#define curlcheck_cb_data_option(option) \
((option) == CURLOPT_CHUNK_DATA || \
(option) == CURLOPT_CLOSESOCKETDATA || \
(option) == CURLOPT_DEBUGDATA || \
(option) == CURLOPT_FNMATCH_DATA || \
(option) == CURLOPT_HEADERDATA || \
(option) == CURLOPT_HSTSREADDATA || \
(option) == CURLOPT_HSTSWRITEDATA || \
(option) == CURLOPT_INTERLEAVEDATA || \
(option) == CURLOPT_IOCTLDATA || \
(option) == CURLOPT_OPENSOCKETDATA || \
(option) == CURLOPT_PROGRESSDATA || \
(option) == CURLOPT_READDATA || \
(option) == CURLOPT_SEEKDATA || \
(option) == CURLOPT_SOCKOPTDATA || \
(option) == CURLOPT_SSH_KEYDATA || \
(option) == CURLOPT_SSL_CTX_DATA || \
(option) == CURLOPT_WRITEDATA || \
(option) == CURLOPT_RESOLVER_START_DATA || \
(option) == CURLOPT_TRAILERDATA || \
0)
/* evaluates to true if option takes a POST data argument (void* or char*) */
#define curlcheck_postfields_option(option) \
((option) == CURLOPT_POSTFIELDS || \
(option) == CURLOPT_COPYPOSTFIELDS || \
0)
/* evaluates to true if option takes a struct curl_slist * argument */
#define curlcheck_slist_option(option) \
((option) == CURLOPT_HTTP200ALIASES || \
(option) == CURLOPT_HTTPHEADER || \
(option) == CURLOPT_MAIL_RCPT || \
(option) == CURLOPT_POSTQUOTE || \
(option) == CURLOPT_PREQUOTE || \
(option) == CURLOPT_PROXYHEADER || \
(option) == CURLOPT_QUOTE || \
(option) == CURLOPT_RESOLVE || \
(option) == CURLOPT_TELNETOPTIONS || \
(option) == CURLOPT_CONNECT_TO || \
0)
/* groups of curl_easy_getinfo infos that take the same type of argument */
/* evaluates to true if info expects a pointer to char * argument */
#define curlcheck_string_info(info) \
(CURLINFO_STRING < (info) && (info) < CURLINFO_LONG && \
(info) != CURLINFO_PRIVATE)
/* evaluates to true if info expects a pointer to long argument */
#define curlcheck_long_info(info) \
(CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
/* evaluates to true if info expects a pointer to double argument */
#define curlcheck_double_info(info) \
(CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
/* true if info expects a pointer to struct curl_slist * argument */
#define curlcheck_slist_info(info) \
(((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
#define curlcheck_tlssessioninfo_info(info) \
(((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
/* true if info expects a pointer to struct curl_certinfo * argument */
#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
/* true if info expects a pointer to struct curl_socket_t argument */
#define curlcheck_socket_info(info) \
(CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
/* true if info expects a pointer to curl_off_t argument */
#define curlcheck_off_t_info(info) \
(CURLINFO_OFF_T < (info))
/* typecheck helpers -- check whether given expression has requested type*/
/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
* otherwise define a new macro. Search for __builtin_types_compatible_p
* in the GCC manual.
* NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
* the actual expression passed to the curl_easy_setopt macro. This
* means that you can only apply the sizeof and __typeof__ operators, no
* == or whatsoever.
*/
/* XXX: should evaluate to true if expr is a pointer */
#define curlcheck_any_ptr(expr) \
(sizeof(expr) == sizeof(void *))
/* evaluates to true if expr is NULL */
/* XXX: must not evaluate expr, so this check is not accurate */
#define curlcheck_NULL(expr) \
(__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
/* evaluates to true if expr is type*, const type* or NULL */
#define curlcheck_ptr(expr, type) \
(curlcheck_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), type *) || \
__builtin_types_compatible_p(__typeof__(expr), const type *))
/* evaluates to true if expr is one of type[], type*, NULL or const type* */
#define curlcheck_arr(expr, type) \
(curlcheck_ptr((expr), type) || \
__builtin_types_compatible_p(__typeof__(expr), type []))
/* evaluates to true if expr is a string */
#define curlcheck_string(expr) \
(curlcheck_arr((expr), char) || \
curlcheck_arr((expr), signed char) || \
curlcheck_arr((expr), unsigned char))
/* evaluates to true if expr is a long (no matter the signedness)
* XXX: for now, int is also accepted (and therefore short and char, which
* are promoted to int when passed to a variadic function) */
#define curlcheck_long(expr) \
(__builtin_types_compatible_p(__typeof__(expr), long) || \
__builtin_types_compatible_p(__typeof__(expr), signed long) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned long) || \
__builtin_types_compatible_p(__typeof__(expr), int) || \
__builtin_types_compatible_p(__typeof__(expr), signed int) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned int) || \
__builtin_types_compatible_p(__typeof__(expr), short) || \
__builtin_types_compatible_p(__typeof__(expr), signed short) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned short) || \
__builtin_types_compatible_p(__typeof__(expr), char) || \
__builtin_types_compatible_p(__typeof__(expr), signed char) || \
__builtin_types_compatible_p(__typeof__(expr), unsigned char))
/* evaluates to true if expr is of type curl_off_t */
#define curlcheck_off_t(expr) \
(__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
/* XXX: also check size of an char[] array? */
#define curlcheck_error_buffer(expr) \
(curlcheck_NULL(expr) || \
__builtin_types_compatible_p(__typeof__(expr), char *) || \
__builtin_types_compatible_p(__typeof__(expr), char[]))
/* evaluates to true if expr is of type (const) void* or (const) FILE* */
#if 0
#define curlcheck_cb_data(expr) \
(curlcheck_ptr((expr), void) || \
curlcheck_ptr((expr), FILE))
#else /* be less strict */
#define curlcheck_cb_data(expr) \
curlcheck_any_ptr(expr)
#endif
/* evaluates to true if expr is of type FILE* */
#define curlcheck_FILE(expr) \
(curlcheck_NULL(expr) || \
(__builtin_types_compatible_p(__typeof__(expr), FILE *)))
/* evaluates to true if expr can be passed as POST data (void* or char*) */
#define curlcheck_postfields(expr) \
(curlcheck_ptr((expr), void) || \
curlcheck_arr((expr), char) || \
curlcheck_arr((expr), unsigned char))
/* helper: __builtin_types_compatible_p distinguishes between functions and
* function pointers, hide it */
#define curlcheck_cb_compatible(func, type) \
(__builtin_types_compatible_p(__typeof__(func), type) || \
__builtin_types_compatible_p(__typeof__(func) *, type))
/* evaluates to true if expr is of type curl_resolver_start_callback */
#define curlcheck_resolver_start_callback(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_resolver_start_callback))
/* evaluates to true if expr is of type curl_read_callback or "similar" */
#define curlcheck_read_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), __typeof__(fread) *) || \
curlcheck_cb_compatible((expr), curl_read_callback) || \
curlcheck_cb_compatible((expr), _curl_read_callback1) || \
curlcheck_cb_compatible((expr), _curl_read_callback2) || \
curlcheck_cb_compatible((expr), _curl_read_callback3) || \
curlcheck_cb_compatible((expr), _curl_read_callback4) || \
curlcheck_cb_compatible((expr), _curl_read_callback5) || \
curlcheck_cb_compatible((expr), _curl_read_callback6))
typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_write_callback or "similar" */
#define curlcheck_write_cb(expr) \
(curlcheck_read_cb(expr) || \
curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \
curlcheck_cb_compatible((expr), curl_write_callback) || \
curlcheck_cb_compatible((expr), _curl_write_callback1) || \
curlcheck_cb_compatible((expr), _curl_write_callback2) || \
curlcheck_cb_compatible((expr), _curl_write_callback3) || \
curlcheck_cb_compatible((expr), _curl_write_callback4) || \
curlcheck_cb_compatible((expr), _curl_write_callback5) || \
curlcheck_cb_compatible((expr), _curl_write_callback6))
typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
const void *);
typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
const void *);
typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
#define curlcheck_ioctl_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_ioctl_callback) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \
curlcheck_cb_compatible((expr), _curl_ioctl_callback4))
typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
#define curlcheck_sockopt_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_sockopt_callback) || \
curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \
curlcheck_cb_compatible((expr), _curl_sockopt_callback2))
typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
curlsocktype);
/* evaluates to true if expr is of type curl_opensocket_callback or
"similar" */
#define curlcheck_opensocket_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_opensocket_callback) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \
curlcheck_cb_compatible((expr), _curl_opensocket_callback4))
typedef curl_socket_t (*_curl_opensocket_callback1)
(void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback2)
(void *, curlsocktype, const struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback3)
(const void *, curlsocktype, struct curl_sockaddr *);
typedef curl_socket_t (*_curl_opensocket_callback4)
(const void *, curlsocktype, const struct curl_sockaddr *);
/* evaluates to true if expr is of type curl_progress_callback or "similar" */
#define curlcheck_progress_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_progress_callback) || \
curlcheck_cb_compatible((expr), _curl_progress_callback1) || \
curlcheck_cb_compatible((expr), _curl_progress_callback2))
typedef int (*_curl_progress_callback1)(void *,
double, double, double, double);
typedef int (*_curl_progress_callback2)(const void *,
double, double, double, double);
/* evaluates to true if expr is of type curl_debug_callback or "similar" */
#define curlcheck_debug_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_debug_callback) || \
curlcheck_cb_compatible((expr), _curl_debug_callback1) || \
curlcheck_cb_compatible((expr), _curl_debug_callback2) || \
curlcheck_cb_compatible((expr), _curl_debug_callback3) || \
curlcheck_cb_compatible((expr), _curl_debug_callback4) || \
curlcheck_cb_compatible((expr), _curl_debug_callback5) || \
curlcheck_cb_compatible((expr), _curl_debug_callback6) || \
curlcheck_cb_compatible((expr), _curl_debug_callback7) || \
curlcheck_cb_compatible((expr), _curl_debug_callback8))
typedef int (*_curl_debug_callback1) (CURL *,
curl_infotype, char *, size_t, void *);
typedef int (*_curl_debug_callback2) (CURL *,
curl_infotype, char *, size_t, const void *);
typedef int (*_curl_debug_callback3) (CURL *,
curl_infotype, const char *, size_t, void *);
typedef int (*_curl_debug_callback4) (CURL *,
curl_infotype, const char *, size_t, const void *);
typedef int (*_curl_debug_callback5) (CURL *,
curl_infotype, unsigned char *, size_t, void *);
typedef int (*_curl_debug_callback6) (CURL *,
curl_infotype, unsigned char *, size_t, const void *);
typedef int (*_curl_debug_callback7) (CURL *,
curl_infotype, const unsigned char *, size_t, void *);
typedef int (*_curl_debug_callback8) (CURL *,
curl_infotype, const unsigned char *, size_t, const void *);
/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
/* this is getting even messier... */
#define curlcheck_ssl_ctx_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \
curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8))
typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
const void *);
#ifdef HEADER_SSL_H
/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
* this will of course break if we're included before OpenSSL headers...
*/
typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX *, const void *);
typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX *, void *);
typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX *,
const void *);
#else
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
#endif
/* evaluates to true if expr is of type curl_conv_callback or "similar" */
#define curlcheck_conv_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_conv_callback) || \
curlcheck_cb_compatible((expr), _curl_conv_callback1) || \
curlcheck_cb_compatible((expr), _curl_conv_callback2) || \
curlcheck_cb_compatible((expr), _curl_conv_callback3) || \
curlcheck_cb_compatible((expr), _curl_conv_callback4))
typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
/* evaluates to true if expr is of type curl_seek_callback or "similar" */
#define curlcheck_seek_cb(expr) \
(curlcheck_NULL(expr) || \
curlcheck_cb_compatible((expr), curl_seek_callback) || \
curlcheck_cb_compatible((expr), _curl_seek_callback1) || \
curlcheck_cb_compatible((expr), _curl_seek_callback2))
typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
#endif /* CURLINC_TYPECHECK_GCC_H */

View File

@ -0,0 +1,126 @@
#ifndef CURLINC_URLAPI_H
#define CURLINC_URLAPI_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl.h"
#ifdef __cplusplus
extern "C" {
#endif
/* the error codes for the URL API */
typedef enum {
CURLUE_OK,
CURLUE_BAD_HANDLE, /* 1 */
CURLUE_BAD_PARTPOINTER, /* 2 */
CURLUE_MALFORMED_INPUT, /* 3 */
CURLUE_BAD_PORT_NUMBER, /* 4 */
CURLUE_UNSUPPORTED_SCHEME, /* 5 */
CURLUE_URLDECODE, /* 6 */
CURLUE_OUT_OF_MEMORY, /* 7 */
CURLUE_USER_NOT_ALLOWED, /* 8 */
CURLUE_UNKNOWN_PART, /* 9 */
CURLUE_NO_SCHEME, /* 10 */
CURLUE_NO_USER, /* 11 */
CURLUE_NO_PASSWORD, /* 12 */
CURLUE_NO_OPTIONS, /* 13 */
CURLUE_NO_HOST, /* 14 */
CURLUE_NO_PORT, /* 15 */
CURLUE_NO_QUERY, /* 16 */
CURLUE_NO_FRAGMENT /* 17 */
} CURLUcode;
typedef enum {
CURLUPART_URL,
CURLUPART_SCHEME,
CURLUPART_USER,
CURLUPART_PASSWORD,
CURLUPART_OPTIONS,
CURLUPART_HOST,
CURLUPART_PORT,
CURLUPART_PATH,
CURLUPART_QUERY,
CURLUPART_FRAGMENT,
CURLUPART_ZONEID /* added in 7.65.0 */
} CURLUPart;
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
if the port number matches the
default for the scheme */
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
missing */
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
scheme is unknown. */
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
typedef struct Curl_URL CURLU;
/*
* curl_url() creates a new CURLU handle and returns a pointer to it.
* Must be freed with curl_url_cleanup().
*/
CURL_EXTERN CURLU *curl_url(void);
/*
* curl_url_cleanup() frees the CURLU handle and related resources used for
* the URL parsing. It will not free strings previously returned with the URL
* API.
*/
CURL_EXTERN void curl_url_cleanup(CURLU *handle);
/*
* curl_url_dup() duplicates a CURLU handle and returns a new copy. The new
* handle must also be freed with curl_url_cleanup().
*/
CURL_EXTERN CURLU *curl_url_dup(CURLU *in);
/*
* curl_url_get() extracts a specific part of the URL from a CURLU
* handle. Returns error code. The returned pointer MUST be freed with
* curl_free() afterwards.
*/
CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what,
char **part, unsigned int flags);
/*
* curl_url_set() sets a specific part of the URL in a CURLU handle. Returns
* error code. The passed in string will be copied. Passing a NULL instead of
* a part string, clears that part.
*/
CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what,
const char *part, unsigned int flags);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* CURLINC_URLAPI_H */

View File

@ -0,0 +1,60 @@
/* jconfig.h. Generated from jconfig.cfg by configure. */
/* jconfig.cfg --- source file edited by configure script */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES 1
#define HAVE_UNSIGNED_CHAR 1
#define HAVE_UNSIGNED_SHORT 1
/* #undef void */
/* #undef const */
/* #undef CHAR_IS_UNSIGNED */
#define HAVE_STDDEF_H 1
#define HAVE_STDLIB_H 1
#define HAVE_LOCALE_H 1
/* #undef NEED_BSD_STRINGS */
/* #undef NEED_SYS_TYPES_H */
/* #undef NEED_FAR_POINTERS */
/* #undef NEED_SHORT_EXTERNAL_NAMES */
/* Define this if you get warnings about undefined structures. */
/* #undef INCOMPLETE_TYPES_BROKEN */
/* Define "boolean" as unsigned char, not enum, on Windows systems. */
#ifdef _WIN32
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#ifndef FALSE /* in case these macros already exist */
#define FALSE 0 /* values of boolean */
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#endif
#ifdef JPEG_INTERNALS
/* #undef RIGHT_SHIFT_IS_UNSIGNED */
#define INLINE __inline__
/* These are for configuring the JPEG memory manager. */
/* #undef DEFAULT_MAX_MEM */
/* #undef NO_MKTEMP */
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
/* #undef RLE_SUPPORTED */
#define TARGA_SUPPORTED /* Targa image file format */
/* #undef TWO_FILE_COMMANDLINE */
/* #undef NEED_SIGNAL_CATCHER */
/* #undef DONT_USE_B_MODE */
/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
/* #undef PROGRESS_REPORT */
#endif /* JPEG_CJPEG_DJPEG */

304
linux/include/jpeg/jerror.h Normal file
View File

@ -0,0 +1,304 @@
/*
* jerror.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2018 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file defines the error and message codes for the JPEG library.
* Edit this file to add new codes, or to translate the message strings to
* some other language.
* A set of error-reporting macros are defined too. Some applications using
* the JPEG library may wish to include this file to get the error codes
* and/or the macros.
*/
/*
* To define the enum list of message codes, include this file without
* defining macro JMESSAGE. To create a message string table, include it
* again with a suitable JMESSAGE definition (see jerror.c for an example).
*/
#ifndef JMESSAGE
#ifndef JERROR_H
/* First time through, define the enum list */
#define JMAKE_ENUM_LIST
#else
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
#define JMESSAGE(code,string)
#endif /* JERROR_H */
#endif /* JMESSAGE */
#ifdef JMAKE_ENUM_LIST
typedef enum {
#define JMESSAGE(code,string) code ,
#endif /* JMAKE_ENUM_LIST */
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
/* For maintenance convenience, list is alphabetical by message code name */
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
JMESSAGE(JERR_BAD_DCTSIZE, "DCT scaled block size %dx%d not supported")
JMESSAGE(JERR_BAD_DROP_SAMPLING,
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
JMESSAGE(JERR_BAD_LIB_VERSION,
"Wrong JPEG library version: library is %d, caller expects %d")
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
JMESSAGE(JERR_BAD_PROGRESSION,
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
JMESSAGE(JERR_BAD_PROG_SCRIPT,
"Invalid progressive parameters at scan script entry %d")
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
JMESSAGE(JERR_BAD_STRUCT_SIZE,
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
JMESSAGE(JERR_FILE_READ, "Input file read error")
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
JMESSAGE(JERR_HUFF_CLEN_OUTOFBOUNDS, "Huffman code size table out of bounds")
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
"Cannot transcode due to multiple use of quantization table %d")
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
JMESSAGE(JERR_QUANT_COMPONENTS,
"Cannot quantize more than %d color components")
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF")
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
JMESSAGE(JERR_TFILE_WRITE,
"Write failed on temporary file --- out of disk space?")
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
JMESSAGE(JMSG_VERSION, JVERSION)
JMESSAGE(JTRC_16BIT_TABLES,
"Caution: quantization tables are too coarse for baseline JPEG")
JMESSAGE(JTRC_ADOBE,
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
JMESSAGE(JTRC_EOI, "End Of Image")
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
"Warning: thumbnail image size does not match data length %u")
JMESSAGE(JTRC_JFIF_EXTENSION,
"JFIF extension marker: type 0x%02x, length %u")
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
JMESSAGE(JTRC_RST, "RST%d")
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
"Smoothing not supported with nonstandard sampling ratios")
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
JMESSAGE(JTRC_SOI, "Start of Image")
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
JMESSAGE(JTRC_THUMB_JPEG,
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_PALETTE,
"JFIF extension marker: palette thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_RGB,
"JFIF extension marker: RGB thumbnail image, length %u")
JMESSAGE(JTRC_UNKNOWN_IDS,
"Unrecognized component IDs %d %d %d, assuming YCbCr")
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
JMESSAGE(JWRN_BOGUS_PROGRESSION,
"Inconsistent progression sequence for component %d coefficient %d")
JMESSAGE(JWRN_EXTRANEOUS_DATA,
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
JMESSAGE(JWRN_MUST_RESYNC,
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
#ifdef JMAKE_ENUM_LIST
JMSG_LASTMSGCODE
} J_MESSAGE_CODE;
#undef JMAKE_ENUM_LIST
#endif /* JMAKE_ENUM_LIST */
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
#undef JMESSAGE
#ifndef JERROR_H
#define JERROR_H
/* Macros to simplify using the error and trace message stuff */
/* The first parameter is either type of cinfo pointer */
/* Fatal errors (print message and exit) */
#define ERREXIT(cinfo,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT1(cinfo,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT2(cinfo,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT3(cinfo,code,p1,p2,p3) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(cinfo)->err->msg_parm.i[2] = (p3), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(cinfo)->err->msg_parm.i[4] = (p5), \
(cinfo)->err->msg_parm.i[5] = (p6), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXITS(cinfo,code,str) \
((cinfo)->err->msg_code = (code), \
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define MAKESTMT(stuff) do { stuff } while (0)
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
#define WARNMS(cinfo,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
#define WARNMS1(cinfo,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
#define WARNMS2(cinfo,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
/* Informational/debugging messages */
#define TRACEMS(cinfo,lvl,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS1(cinfo,lvl,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
_mp[4] = (p5); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMSS(cinfo,lvl,code,str) \
((cinfo)->err->msg_code = (code), \
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#endif /* JERROR_H */

View File

@ -0,0 +1,446 @@
/*
* jmorecfg.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2013 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains additional configuration options that customize the
* JPEG software for special applications or support machine-dependent
* optimizations. Most users will not need to touch this file.
*/
/*
* Define BITS_IN_JSAMPLE as either
* 8 for 8-bit sample values (the usual setting)
* 9 for 9-bit sample values
* 10 for 10-bit sample values
* 11 for 11-bit sample values
* 12 for 12-bit sample values
* Only 8, 9, 10, 11, and 12 bits sample data precision are supported for
* full-feature DCT processing. Further depths up to 16-bit may be added
* later for the lossless modes of operation.
* Run-time selection and conversion of data precision will be added later
* and are currently not supported, sorry.
* Exception: The transcoding part (jpegtran) supports all settings in a
* single instance, since it operates on the level of DCT coefficients and
* not sample values. The DCT coefficients are of the same type (16 bits)
* in all cases (see below).
*/
#define BITS_IN_JSAMPLE 8 /* use 8, 9, 10, 11, or 12 */
/*
* Maximum number of components (color channels) allowed in JPEG image.
* To meet the letter of the JPEG spec, set this to 255. However, darn
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
* really short on memory. (Each allowed component costs a hundred or so
* bytes of storage, whether actually used in an image or not.)
*/
#define MAX_COMPONENTS 10 /* maximum number of image components */
/*
* Basic data types.
* You may need to change these if you have a machine with unusual data
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
* but it had better be at least 16.
*/
/* Representation of a single sample (pixel element value).
* We frequently allocate large arrays of these, so it's important to keep
* them small. But if you have memory to burn and access to char or short
* arrays is very slow on your hardware, you might want to change these.
*/
#if BITS_IN_JSAMPLE == 8
/* JSAMPLE should be the smallest type that will hold the values 0..255.
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JSAMPLE;
#ifdef CHAR_IS_UNSIGNED
#define GETJSAMPLE(value) ((int) (value))
#else
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
#define MAXJSAMPLE 255
#define CENTERJSAMPLE 128
#endif /* BITS_IN_JSAMPLE == 8 */
#if BITS_IN_JSAMPLE == 9
/* JSAMPLE should be the smallest type that will hold the values 0..511.
* On nearly all machines "short" will do nicely.
*/
typedef short JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#define MAXJSAMPLE 511
#define CENTERJSAMPLE 256
#endif /* BITS_IN_JSAMPLE == 9 */
#if BITS_IN_JSAMPLE == 10
/* JSAMPLE should be the smallest type that will hold the values 0..1023.
* On nearly all machines "short" will do nicely.
*/
typedef short JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#define MAXJSAMPLE 1023
#define CENTERJSAMPLE 512
#endif /* BITS_IN_JSAMPLE == 10 */
#if BITS_IN_JSAMPLE == 11
/* JSAMPLE should be the smallest type that will hold the values 0..2047.
* On nearly all machines "short" will do nicely.
*/
typedef short JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#define MAXJSAMPLE 2047
#define CENTERJSAMPLE 1024
#endif /* BITS_IN_JSAMPLE == 11 */
#if BITS_IN_JSAMPLE == 12
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
* On nearly all machines "short" will do nicely.
*/
typedef short JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#define MAXJSAMPLE 4095
#define CENTERJSAMPLE 2048
#endif /* BITS_IN_JSAMPLE == 12 */
/* Representation of a DCT frequency coefficient.
* This should be a signed value of at least 16 bits; "short" is usually OK.
* Again, we allocate large arrays of these, but you can change to int
* if you have memory to burn and "short" is really slow.
*/
typedef short JCOEF;
/* Compressed datastreams are represented as arrays of JOCTET.
* These must be EXACTLY 8 bits wide, at least once they are written to
* external storage. Note that when using the stdio data source/destination
* managers, this is also the data type passed to fread/fwrite.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JOCTET;
#define GETJOCTET(value) (value)
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JOCTET;
#ifdef CHAR_IS_UNSIGNED
#define GETJOCTET(value) (value)
#else
#define GETJOCTET(value) ((value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
/* These typedefs are used for various table entries and so forth.
* They must be at least as wide as specified; but making them too big
* won't cost a huge amount of memory, so we don't provide special
* extraction code like we did for JSAMPLE. (In other words, these
* typedefs live at a different point on the speed/space tradeoff curve.)
*/
/* UINT8 must hold at least the values 0..255. */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char UINT8;
#else /* not HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char UINT8;
#else /* not CHAR_IS_UNSIGNED */
typedef short UINT8;
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
/* UINT16 must hold at least the values 0..65535. */
#ifdef HAVE_UNSIGNED_SHORT
typedef unsigned short UINT16;
#else /* not HAVE_UNSIGNED_SHORT */
typedef unsigned int UINT16;
#endif /* HAVE_UNSIGNED_SHORT */
/* INT16 must hold at least the values -32768..32767. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
typedef short INT16;
#endif
/* INT32 must hold at least signed 32-bit values. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
#ifndef _BASETSD_H /* MinGW is slightly different */
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
typedef long INT32;
#endif
#endif
#endif
#endif
/* Datatype used for image dimensions. The JPEG standard only supports
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
* "unsigned int" is sufficient on all machines. However, if you need to
* handle larger images and you don't mind deviating from the spec, you
* can change this datatype.
*/
typedef unsigned int JDIMENSION;
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
/* These macros are used in all function definitions and extern declarations.
* You could modify them if you need to change function linkage conventions;
* in particular, you'll need to do that to make the library a Windows DLL.
* Another application is to make all functions global for use with debuggers
* or code profilers that require it.
*/
/* a function called through method pointers: */
#define METHODDEF(type) static type
/* a function used only in its module: */
#define LOCAL(type) static type
/* a function referenced thru EXTERNs: */
#define GLOBAL(type) type
/* a reference to a GLOBAL function: */
#define EXTERN(type) extern type
/* This macro is used to declare a "method", that is, a function pointer.
* We want to supply prototype parameters if the compiler can cope.
* Note that the arglist parameter must be parenthesized!
* Again, you can customize this if you need special linkage keywords.
*/
#ifdef HAVE_PROTOTYPES
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
#else
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
#endif
/* The noreturn type identifier is used to declare functions
* which cannot return.
* Compilers can thus create more optimized code and perform
* better checks for warnings and errors.
* Static analyzer tools can make improved inferences about
* execution paths and are prevented from giving false alerts.
*
* Unfortunately, the proposed specifications of corresponding
* extensions in the Dec 2011 ISO C standard revision (C11),
* GCC, MSVC, etc. are not viable.
* Thus we introduce a user defined type to declare noreturn
* functions at least for clarity. A proper compiler would
* have a suitable noreturn type to match in place of void.
*/
#ifndef HAVE_NORETURN_T
typedef void noreturn_t;
#endif
/* Here is the pseudo-keyword for declaring pointers that must be "far"
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
* by just saying "FAR *" where such a pointer is needed. In a few places
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
*/
#ifndef FAR
#ifdef NEED_FAR_POINTERS
#define FAR far
#else
#define FAR
#endif
#endif
/*
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
* in standard header files. Or you may have conflicts with application-
* specific header files that you want to include together with these files.
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
*/
#ifndef HAVE_BOOLEAN
#if defined FALSE || defined TRUE || defined QGLOBAL_H
/* Qt3 defines FALSE and TRUE as "const" variables in qglobal.h */
typedef int boolean;
#ifndef FALSE /* in case these macros already exist */
#define FALSE 0 /* values of boolean */
#endif
#ifndef TRUE
#define TRUE 1
#endif
#else
typedef enum { FALSE = 0, TRUE = 1 } boolean;
#endif
#endif
/*
* The remaining options affect code selection within the JPEG library,
* but they don't need to be visible to most applications using the library.
* To minimize application namespace pollution, the symbols won't be
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
*/
#ifdef JPEG_INTERNALS
#define JPEG_INTERNAL_OPTIONS
#endif
#ifdef JPEG_INTERNAL_OPTIONS
/*
* These defines indicate whether to include various optional functions.
* Undefining some of these symbols will produce a smaller but less capable
* library. Note that you can leave certain source files out of the
* compilation/linking process if you've #undef'd the corresponding symbols.
* (You may HAVE to do that if your compiler doesn't like null source files.)
*/
/* Capability options common to encoder and decoder: */
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
/* Encoder capability options: */
#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
/* Note: if you selected more than 8-bit data precision, it is dangerous to
* turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only
* good for 8-bit precision, so arithmetic coding is recommended for higher
* precision. The Huffman encoder normally uses entropy optimization to
* compute usable tables for higher precision. Otherwise, you'll have to
* supply different default Huffman tables.
* The exact same statements apply for progressive JPEG: the default tables
* don't work for progressive mode. (This may get fixed, however.)
*/
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
/* Decoder capability options: */
#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
/* more capability options later, no doubt */
/*
* Ordering of RGB data in scanlines passed to or from the application.
* If your application wants to deal with data in the order B,G,R, just
* change these macros. You can also deal with formats such as R,G,B,X
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
* the offsets will also change the order in which colormap data is organized.
* RESTRICTIONS:
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
* 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value.
*/
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
#define RGB_GREEN 1 /* Offset of Green */
#define RGB_BLUE 2 /* Offset of Blue */
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
/* Definitions for speed-related optimizations. */
/* If your compiler supports inline functions, define INLINE
* as the inline keyword; otherwise define it as empty.
*/
#ifndef INLINE
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
#define INLINE __inline__
#endif
#ifndef INLINE
#define INLINE /* default is to define it as empty */
#endif
#endif
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
*/
#ifndef MULTIPLIER
#define MULTIPLIER int /* type for fastest integer multiply */
#endif
/* FAST_FLOAT should be either float or double, whichever is done faster
* by your compiler. (Note that this type is only used in the floating point
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
* Typically, float is faster in ANSI C compilers, while double is faster in
* pre-ANSI compilers (because they insist on converting to double anyway).
* The code below therefore chooses float if we have ANSI-style prototypes.
*/
#ifndef FAST_FLOAT
#ifdef HAVE_PROTOTYPES
#define FAST_FLOAT float
#else
#define FAST_FLOAT double
#endif
#endif
#endif /* JPEG_INTERNAL_OPTIONS */

1183
linux/include/jpeg/jpeglib.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,623 @@
/* pngconf.h - machine-configurable file for libpng
*
* libpng version 1.6.37
*
* Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* Any machine specific code is near the front of this file, so if you
* are configuring libpng for a machine, you may want to read the section
* starting here down to where it starts to typedef png_color, png_text,
* and png_info.
*/
#ifndef PNGCONF_H
#define PNGCONF_H
#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
* compiler for correct compilation. The following header files are required by
* the standard. If your compiler doesn't provide these header files, or they
* do not match the standard, you will need to provide/improve them.
*/
#include <limits.h>
#include <stddef.h>
/* Library header files. These header files are all defined by ISOC90; libpng
* expects conformant implementations, however, an ISOC90 conformant system need
* not provide these header files if the functionality cannot be implemented.
* In this case it will be necessary to disable the relevant parts of libpng in
* the build of pnglibconf.h.
*
* Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
* include this unnecessary header file.
*/
#ifdef PNG_STDIO_SUPPORTED
/* Required for the definition of FILE: */
# include <stdio.h>
#endif
#ifdef PNG_SETJMP_SUPPORTED
/* Required for the definition of jmp_buf and the declaration of longjmp: */
# include <setjmp.h>
#endif
#ifdef PNG_CONVERT_tIME_SUPPORTED
/* Required for struct tm: */
# include <time.h>
#endif
#endif /* PNG_BUILDING_SYMBOL_TABLE */
/* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
* using PNG_NO_CONST. This is no longer supported.
*/
#define PNG_CONST const /* backward compatibility only */
/* This controls optimization of the reading of 16-bit and 32-bit
* values from PNG files. It can be set on a per-app-file basis: it
* just changes whether a macro is used when the function is called.
* The library builder sets the default; if read functions are not
* built into the library the macro implementation is forced on.
*/
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
# define PNG_USE_READ_MACROS
#endif
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
# if PNG_DEFAULT_READ_MACROS
# define PNG_USE_READ_MACROS
# endif
#endif
/* COMPILER SPECIFIC OPTIONS.
*
* These options are provided so that a variety of difficult compilers
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
* below) but still have compiler specific implementations, others
* may be changed on a per-file basis when compiling against libpng.
*/
/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
* against legacy (pre ISOC90) compilers that did not understand function
* prototypes. It is not required for modern C compilers.
*/
#ifndef PNGARG
# define PNGARG(arglist) arglist
#endif
/* Function calling conventions.
* =============================
* Normally it is not necessary to specify to the compiler how to call
* a function - it just does it - however on x86 systems derived from
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
* and some others) there are multiple ways to call a function and the
* default can be changed on the compiler command line. For this reason
* libpng specifies the calling convention of every exported function and
* every function called via a user supplied function pointer. This is
* done in this file by defining the following macros:
*
* PNGAPI Calling convention for exported functions.
* PNGCBAPI Calling convention for user provided (callback) functions.
* PNGCAPI Calling convention used by the ANSI-C library (required
* for longjmp callbacks and sometimes used internally to
* specify the calling convention for zlib).
*
* These macros should never be overridden. If it is necessary to
* change calling convention in a private build this can be done
* by setting PNG_API_RULE (which defaults to 0) to one of the values
* below to select the correct 'API' variants.
*
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
* This is correct in every known environment.
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
* the 'C' calling convention (from PNGCAPI) for
* callbacks (PNGCBAPI). This is no longer required
* in any known environment - if it has to be used
* please post an explanation of the problem to the
* libpng mailing list.
*
* These cases only differ if the operating system does not use the C
* calling convention, at present this just means the above cases
* (x86 DOS/Windows systems) and, even then, this does not apply to
* Cygwin running on those systems.
*
* Note that the value must be defined in pnglibconf.h so that what
* the application uses to call the library matches the conventions
* set when building the library.
*/
/* Symbol export
* =============
* When building a shared library it is almost always necessary to tell
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
* is used to mark the symbols. On some systems these symbols can be
* extracted at link time and need no special processing by the compiler,
* on other systems the symbols are flagged by the compiler and just
* the declaration requires a special tag applied (unfortunately) in a
* compiler dependent way. Some systems can do either.
*
* A small number of older systems also require a symbol from a DLL to
* be flagged to the program that calls it. This is a problem because
* we do not know in the header file included by application code that
* the symbol will come from a shared library, as opposed to a statically
* linked one. For this reason the application must tell us by setting
* the magic flag PNG_USE_DLL to turn on the special processing before
* it includes png.h.
*
* Four additional macros are used to make this happen:
*
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
* the build or imported if PNG_USE_DLL is set - compiler
* and system specific.
*
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
* 'type', compiler specific.
*
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
* make a symbol exported from the DLL. Not used in the
* public header files; see pngpriv.h for how it is used
* in the libpng build.
*
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
* from a DLL - used to define PNG_IMPEXP when
* PNG_USE_DLL is set.
*/
/* System specific discovery.
* ==========================
* This code is used at build time to find PNG_IMPEXP, the API settings
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
* import processing is possible. On Windows systems it also sets
* compiler-specific macros to the values required to change the calling
* conventions of the various functions.
*/
#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
/* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
* MinGW on any architecture currently supported by Windows. Also includes
* Watcom builds but these need special treatment because they are not
* compatible with GCC or Visual C because of different calling conventions.
*/
# if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom!
*/
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
/* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'.
*/
# define PNGAPI __stdcall
# endif
# else
/* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct
* variants for the compiler.
*/
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
# if PNG_API_RULE == 1 && !defined(PNGAPI)
# define PNGAPI _stdcall
# endif
# endif /* compiler/api */
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
# endif
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC
* compilers used '__export' and required this to be after
* the type.
*/
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif
# define PNG_DLL_EXPORT __export
# else /* newer compiler */
# define PNG_DLL_EXPORT __declspec(dllexport)
# ifndef PNG_DLL_IMPORT
# define PNG_DLL_IMPORT __declspec(dllimport)
# endif
# endif /* compiler */
#else /* !Windows */
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!)
*/
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
/* Now do all the defaulting . */
#ifndef PNGCAPI
# define PNGCAPI
#endif
#ifndef PNGCBAPI
# define PNGCBAPI PNGCAPI
#endif
#ifndef PNGAPI
# define PNGAPI PNGCAPI
#endif
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
* then in an internal header file when building the library, otherwise (when
* using the library) it is set here.
*/
#ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
# ifndef PNG_IMPEXP
# define PNG_IMPEXP
# endif
#endif
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
* 'attributes' as a storage class - the attributes go at the start of the
* function definition, and attributes are always appended regardless of the
* compiler. This considerably simplifies these macros but may cause problems
* if any compilers both need function attributes and fail to handle them as
* a storage class (this is unlikely.)
*/
#ifndef PNG_FUNCTION
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
#endif
#ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
#endif
/* The ordinal value is only relevant when preprocessing png.h for symbol
* table entries, so we discard it here. See the .dfn files in the
* scripts directory.
*/
#ifndef PNG_EXPORTA
# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
PNG_LINKAGE_API attributes)
#endif
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
* so make something non-empty to satisfy the requirement:
*/
#define PNG_EMPTY /*empty list*/
#define PNG_EXPORT(ordinal, type, name, args) \
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
/* Use PNG_REMOVED to comment out a removed interface. */
#ifndef PNG_REMOVED
# define PNG_REMOVED(ordinal, type, name, args, attributes)
#endif
#ifndef PNG_CALLBACK
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
#endif
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available incorrect use of API
* functions in png.h will generate compiler warnings.
*
* Added at libpng-1.2.41.
*/
#ifndef PNG_NO_PEDANTIC_WARNINGS
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
# endif
#endif
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available, incorrect use of API
* functions in png.h will generate compiler warnings. Added at libpng
* version 1.2.41. Disabling these removes the warnings but may also produce
* less efficient code.
*/
# if defined(__clang__) && defined(__has_attribute)
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
# define PNG_NORETURN __attribute__((__noreturn__))
# endif
# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# if !defined(PNG_PRIVATE)
# ifdef __has_extension
# if __has_extension(attribute_unavailable_with_message)
# define PNG_PRIVATE __attribute__((__unavailable__(\
"This function is not exported by libpng.")))
# endif
# endif
# endif
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# elif defined(__GNUC__)
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __attribute__((__noreturn__))
# endif
# if __GNUC__ >= 3
# ifndef PNG_ALLOCATED
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# ifndef PNG_PRIVATE
# if 0 /* Doesn't work so we use deprecated instead*/
# define PNG_PRIVATE \
__attribute__((warning("This function is not exported by libpng.")))
# else
# define PNG_PRIVATE \
__attribute__((__deprecated__))
# endif
# endif
# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
# endif /* __GNUC__ >= 3 */
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /* not supported */
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __declspec(noreturn)
# endif
# ifndef PNG_ALLOCATED
# if (_MSC_VER >= 1400)
# define PNG_ALLOCATED __declspec(restrict)
# endif
# endif
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __declspec(deprecated)
# endif
# ifndef PNG_PRIVATE
# define PNG_PRIVATE __declspec(deprecated)
# endif
# ifndef PNG_RESTRICT
# if (_MSC_VER >= 1400)
# define PNG_RESTRICT __restrict
# endif
# endif
# elif defined(__WATCOMC__)
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# endif
#endif /* PNG_PEDANTIC_WARNINGS */
#ifndef PNG_DEPRECATED
# define PNG_DEPRECATED /* Use of this function is deprecated */
#endif
#ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /* The result of this function must be checked */
#endif
#ifndef PNG_NORETURN
# define PNG_NORETURN /* This function does not return */
#endif
#ifndef PNG_ALLOCATED
# define PNG_ALLOCATED /* The result of the function is new memory */
#endif
#ifndef PNG_PRIVATE
# define PNG_PRIVATE /* This is a private libpng function */
#endif
#ifndef PNG_RESTRICT
# define PNG_RESTRICT /* The C99 "restrict" feature */
#endif
#ifndef PNG_FP_EXPORT /* A floating point API. */
# ifdef PNG_FLOATING_POINT_SUPPORTED
# define PNG_FP_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No floating point APIs */
# define PNG_FP_EXPORT(ordinal, type, name, args)
# endif
#endif
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
# ifdef PNG_FIXED_POINT_SUPPORTED
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No fixed point APIs */
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
# endif
#endif
#ifndef PNG_BUILDING_SYMBOL_TABLE
/* Some typedefs to get us started. These should be safe on most of the common
* platforms.
*
* png_uint_32 and png_int_32 may, currently, be larger than required to hold a
* 32-bit value however this is not normally advisable.
*
* png_uint_16 and png_int_16 should always be two bytes in size - this is
* verified at library build time.
*
* png_byte must always be one byte in size.
*
* The checks below use constants from limits.h, as defined by the ISOC90
* standard.
*/
#if CHAR_BIT == 8 && UCHAR_MAX == 255
typedef unsigned char png_byte;
#else
# error "libpng requires 8-bit bytes"
#endif
#if INT_MIN == -32768 && INT_MAX == 32767
typedef int png_int_16;
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
typedef short png_int_16;
#else
# error "libpng requires a signed 16-bit type"
#endif
#if UINT_MAX == 65535
typedef unsigned int png_uint_16;
#elif USHRT_MAX == 65535
typedef unsigned short png_uint_16;
#else
# error "libpng requires an unsigned 16-bit type"
#endif
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
typedef int png_int_32;
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
typedef long int png_int_32;
#else
# error "libpng requires a signed 32-bit (or more) type"
#endif
#if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32;
#else
# error "libpng requires an unsigned 32-bit (or more) type"
#endif
/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
* From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
* behavior of sizeof and ptrdiff_t are required.
* The legacy typedefs are provided here for backwards compatibility.
*/
typedef size_t png_size_t;
typedef ptrdiff_t png_ptrdiff_t;
/* libpng needs to know the maximum value of 'size_t' and this controls the
* definition of png_alloc_size_t, below. This maximum value of size_t limits
* but does not control the maximum allocations the library makes - there is
* direct application control of this through png_set_user_limits().
*/
#ifndef PNG_SMALL_SIZE_T
/* Compiler specific tests for systems where size_t is known to be less than
* 32 bits (some of these systems may no longer work because of the lack of
* 'far' support; see above.)
*/
# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
(defined(_MSC_VER) && defined(MAXSEG_64K))
# define PNG_SMALL_SIZE_T
# endif
#endif
/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
* than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are
* not necessary; in fact, it is recommended not to use them at all, so that
* the compiler can complain when something turns out to be problematic.
*
* Casts in the other direction (from png_alloc_size_t to size_t or
* png_uint_32) should be explicitly applied; however, we do not expect to
* encounter practical situations that require such conversions.
*
* PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
* 4294967295 - i.e. less than the maximum value of png_uint_32.
*/
#ifdef PNG_SMALL_SIZE_T
typedef png_uint_32 png_alloc_size_t;
#else
typedef size_t png_alloc_size_t;
#endif
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
* implementations of Intel CPU specific support of user-mode segmented address
* spaces, where 16-bit pointers address more than 65536 bytes of memory using
* separate 'segment' registers. The implementation requires two different
* types of pointer (only one of which includes the segment value.)
*
* If required this support is available in version 1.2 of libpng and may be
* available in versions through 1.5, although the correctness of the code has
* not been verified recently.
*/
/* Typedef for floating-point numbers that are converted to fixed-point with a
* multiple of 100,000, e.g., gamma
*/
typedef png_int_32 png_fixed_point;
/* Add typedefs for pointers */
typedef void * png_voidp;
typedef const void * png_const_voidp;
typedef png_byte * png_bytep;
typedef const png_byte * png_const_bytep;
typedef png_uint_32 * png_uint_32p;
typedef const png_uint_32 * png_const_uint_32p;
typedef png_int_32 * png_int_32p;
typedef const png_int_32 * png_const_int_32p;
typedef png_uint_16 * png_uint_16p;
typedef const png_uint_16 * png_const_uint_16p;
typedef png_int_16 * png_int_16p;
typedef const png_int_16 * png_const_int_16p;
typedef char * png_charp;
typedef const char * png_const_charp;
typedef png_fixed_point * png_fixed_point_p;
typedef const png_fixed_point * png_const_fixed_point_p;
typedef size_t * png_size_tp;
typedef const size_t * png_const_size_tp;
#ifdef PNG_STDIO_SUPPORTED
typedef FILE * png_FILE_p;
#endif
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double * png_doublep;
typedef const double * png_const_doublep;
#endif
/* Pointers to pointers; i.e. arrays */
typedef png_byte * * png_bytepp;
typedef png_uint_32 * * png_uint_32pp;
typedef png_int_32 * * png_int_32pp;
typedef png_uint_16 * * png_uint_16pp;
typedef png_int_16 * * png_int_16pp;
typedef const char * * png_const_charpp;
typedef char * * png_charpp;
typedef png_fixed_point * * png_fixed_point_pp;
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double * * png_doublepp;
#endif
/* Pointers to pointers to pointers; i.e., pointer to array */
typedef char * * * png_charppp;
#endif /* PNG_BUILDING_SYMBOL_TABLE */
#endif /* PNGCONF_H */

View File

@ -0,0 +1,219 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.6.37 */
/* Copyright (c) 2018-2019 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
/* and license in png.h */
/* pnglibconf.h */
/* Machine generated file: DO NOT EDIT */
/* Derived from: scripts/pnglibconf.dfa */
#ifndef PNGLCONF_H
#define PNGLCONF_H
/* options */
#define PNG_16BIT_SUPPORTED
#define PNG_ALIGNED_MEMORY_SUPPORTED
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
#define PNG_BENIGN_ERRORS_SUPPORTED
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_COLORSPACE_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
#define PNG_EASY_ACCESS_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_ERROR_TEXT_SUPPORTED
#define PNG_FIXED_POINT_SUPPORTED
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
#define PNG_FLOATING_POINT_SUPPORTED
#define PNG_FORMAT_AFIRST_SUPPORTED
#define PNG_FORMAT_BGR_SUPPORTED
#define PNG_GAMMA_SUPPORTED
#define PNG_GET_PALETTE_MAX_SUPPORTED
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_ALPHA_MODE_SUPPORTED
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_READ_BGR_SUPPORTED
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
#define PNG_READ_EXPAND_16_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED
#define PNG_READ_FILLER_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_INVERT_ALPHA_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_PACK_SUPPORTED
#define PNG_READ_QUANTIZE_SUPPORTED
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_READ_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_TEXT_SUPPORTED
#define PNG_READ_TRANSFORMS_SUPPORTED
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_USER_CHUNKS_SUPPORTED
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_eXIf_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_sCAL_SUPPORTED
#define PNG_READ_sPLT_SUPPORTED
#define PNG_READ_sRGB_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
#define PNG_SAVE_INT_32_SUPPORTED
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_SETJMP_SUPPORTED
#define PNG_SET_OPTION_SUPPORTED
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
#define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_TEXT_SUPPORTED
#define PNG_TIME_RFC1123_SUPPORTED
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_CHUNKS_SUPPORTED
#define PNG_USER_LIMITS_SUPPORTED
#define PNG_USER_MEM_SUPPORTED
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
#define PNG_WARNINGS_SUPPORTED
#define PNG_WRITE_16BIT_SUPPORTED
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED
#define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_WRITE_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED
#define PNG_WRITE_TEXT_SUPPORTED
#define PNG_WRITE_TRANSFORMS_SUPPORTED
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_eXIf_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_WRITE_sCAL_SUPPORTED
#define PNG_WRITE_sPLT_SUPPORTED
#define PNG_WRITE_sRGB_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_cHRM_SUPPORTED
#define PNG_eXIf_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
#define PNG_iTXt_SUPPORTED
#define PNG_oFFs_SUPPORTED
#define PNG_pCAL_SUPPORTED
#define PNG_pHYs_SUPPORTED
#define PNG_sBIT_SUPPORTED
#define PNG_sCAL_SUPPORTED
#define PNG_sPLT_SUPPORTED
#define PNG_sRGB_SUPPORTED
#define PNG_tEXt_SUPPORTED
#define PNG_tIME_SUPPORTED
#define PNG_tRNS_SUPPORTED
#define PNG_zTXt_SUPPORTED
/* end of options */
/* settings */
#define PNG_API_RULE 0
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
#define PNG_INFLATE_BUF_SIZE 1024
#define PNG_LINKAGE_API extern
#define PNG_LINKAGE_CALLBACK extern
#define PNG_LINKAGE_DATA extern
#define PNG_LINKAGE_FUNCTION extern
#define PNG_MAX_GAMMA_8 11
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_QUANTIZE_RED_BITS 5
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
#define PNG_USER_CHUNK_CACHE_MAX 1000
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
#define PNG_USER_HEIGHT_MAX 1000000
#define PNG_USER_WIDTH_MAX 1000000
#define PNG_ZBUF_SIZE 8192
#define PNG_ZLIB_VERNUM 0x12b0
#define PNG_Z_DEFAULT_COMPRESSION (-1)
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
#define PNG_Z_DEFAULT_STRATEGY 1
#define PNG_sCAL_PRECISION 5
#define PNG_sRGB_PROFILE_CHECKS 2
/* end of settings */
#endif /* PNGLCONF_H */

3247
linux/include/libpng/png.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,623 @@
/* pngconf.h - machine-configurable file for libpng
*
* libpng version 1.6.37
*
* Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* Any machine specific code is near the front of this file, so if you
* are configuring libpng for a machine, you may want to read the section
* starting here down to where it starts to typedef png_color, png_text,
* and png_info.
*/
#ifndef PNGCONF_H
#define PNGCONF_H
#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
* compiler for correct compilation. The following header files are required by
* the standard. If your compiler doesn't provide these header files, or they
* do not match the standard, you will need to provide/improve them.
*/
#include <limits.h>
#include <stddef.h>
/* Library header files. These header files are all defined by ISOC90; libpng
* expects conformant implementations, however, an ISOC90 conformant system need
* not provide these header files if the functionality cannot be implemented.
* In this case it will be necessary to disable the relevant parts of libpng in
* the build of pnglibconf.h.
*
* Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
* include this unnecessary header file.
*/
#ifdef PNG_STDIO_SUPPORTED
/* Required for the definition of FILE: */
# include <stdio.h>
#endif
#ifdef PNG_SETJMP_SUPPORTED
/* Required for the definition of jmp_buf and the declaration of longjmp: */
# include <setjmp.h>
#endif
#ifdef PNG_CONVERT_tIME_SUPPORTED
/* Required for struct tm: */
# include <time.h>
#endif
#endif /* PNG_BUILDING_SYMBOL_TABLE */
/* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
* using PNG_NO_CONST. This is no longer supported.
*/
#define PNG_CONST const /* backward compatibility only */
/* This controls optimization of the reading of 16-bit and 32-bit
* values from PNG files. It can be set on a per-app-file basis: it
* just changes whether a macro is used when the function is called.
* The library builder sets the default; if read functions are not
* built into the library the macro implementation is forced on.
*/
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
# define PNG_USE_READ_MACROS
#endif
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
# if PNG_DEFAULT_READ_MACROS
# define PNG_USE_READ_MACROS
# endif
#endif
/* COMPILER SPECIFIC OPTIONS.
*
* These options are provided so that a variety of difficult compilers
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
* below) but still have compiler specific implementations, others
* may be changed on a per-file basis when compiling against libpng.
*/
/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
* against legacy (pre ISOC90) compilers that did not understand function
* prototypes. It is not required for modern C compilers.
*/
#ifndef PNGARG
# define PNGARG(arglist) arglist
#endif
/* Function calling conventions.
* =============================
* Normally it is not necessary to specify to the compiler how to call
* a function - it just does it - however on x86 systems derived from
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
* and some others) there are multiple ways to call a function and the
* default can be changed on the compiler command line. For this reason
* libpng specifies the calling convention of every exported function and
* every function called via a user supplied function pointer. This is
* done in this file by defining the following macros:
*
* PNGAPI Calling convention for exported functions.
* PNGCBAPI Calling convention for user provided (callback) functions.
* PNGCAPI Calling convention used by the ANSI-C library (required
* for longjmp callbacks and sometimes used internally to
* specify the calling convention for zlib).
*
* These macros should never be overridden. If it is necessary to
* change calling convention in a private build this can be done
* by setting PNG_API_RULE (which defaults to 0) to one of the values
* below to select the correct 'API' variants.
*
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
* This is correct in every known environment.
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
* the 'C' calling convention (from PNGCAPI) for
* callbacks (PNGCBAPI). This is no longer required
* in any known environment - if it has to be used
* please post an explanation of the problem to the
* libpng mailing list.
*
* These cases only differ if the operating system does not use the C
* calling convention, at present this just means the above cases
* (x86 DOS/Windows systems) and, even then, this does not apply to
* Cygwin running on those systems.
*
* Note that the value must be defined in pnglibconf.h so that what
* the application uses to call the library matches the conventions
* set when building the library.
*/
/* Symbol export
* =============
* When building a shared library it is almost always necessary to tell
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
* is used to mark the symbols. On some systems these symbols can be
* extracted at link time and need no special processing by the compiler,
* on other systems the symbols are flagged by the compiler and just
* the declaration requires a special tag applied (unfortunately) in a
* compiler dependent way. Some systems can do either.
*
* A small number of older systems also require a symbol from a DLL to
* be flagged to the program that calls it. This is a problem because
* we do not know in the header file included by application code that
* the symbol will come from a shared library, as opposed to a statically
* linked one. For this reason the application must tell us by setting
* the magic flag PNG_USE_DLL to turn on the special processing before
* it includes png.h.
*
* Four additional macros are used to make this happen:
*
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
* the build or imported if PNG_USE_DLL is set - compiler
* and system specific.
*
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
* 'type', compiler specific.
*
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
* make a symbol exported from the DLL. Not used in the
* public header files; see pngpriv.h for how it is used
* in the libpng build.
*
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
* from a DLL - used to define PNG_IMPEXP when
* PNG_USE_DLL is set.
*/
/* System specific discovery.
* ==========================
* This code is used at build time to find PNG_IMPEXP, the API settings
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
* import processing is possible. On Windows systems it also sets
* compiler-specific macros to the values required to change the calling
* conventions of the various functions.
*/
#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
/* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
* MinGW on any architecture currently supported by Windows. Also includes
* Watcom builds but these need special treatment because they are not
* compatible with GCC or Visual C because of different calling conventions.
*/
# if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom!
*/
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
/* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'.
*/
# define PNGAPI __stdcall
# endif
# else
/* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct
* variants for the compiler.
*/
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
# if PNG_API_RULE == 1 && !defined(PNGAPI)
# define PNGAPI _stdcall
# endif
# endif /* compiler/api */
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
# endif
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC
* compilers used '__export' and required this to be after
* the type.
*/
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif
# define PNG_DLL_EXPORT __export
# else /* newer compiler */
# define PNG_DLL_EXPORT __declspec(dllexport)
# ifndef PNG_DLL_IMPORT
# define PNG_DLL_IMPORT __declspec(dllimport)
# endif
# endif /* compiler */
#else /* !Windows */
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!)
*/
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
/* Now do all the defaulting . */
#ifndef PNGCAPI
# define PNGCAPI
#endif
#ifndef PNGCBAPI
# define PNGCBAPI PNGCAPI
#endif
#ifndef PNGAPI
# define PNGAPI PNGCAPI
#endif
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
* then in an internal header file when building the library, otherwise (when
* using the library) it is set here.
*/
#ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
# ifndef PNG_IMPEXP
# define PNG_IMPEXP
# endif
#endif
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
* 'attributes' as a storage class - the attributes go at the start of the
* function definition, and attributes are always appended regardless of the
* compiler. This considerably simplifies these macros but may cause problems
* if any compilers both need function attributes and fail to handle them as
* a storage class (this is unlikely.)
*/
#ifndef PNG_FUNCTION
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
#endif
#ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
#endif
/* The ordinal value is only relevant when preprocessing png.h for symbol
* table entries, so we discard it here. See the .dfn files in the
* scripts directory.
*/
#ifndef PNG_EXPORTA
# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
PNG_LINKAGE_API attributes)
#endif
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
* so make something non-empty to satisfy the requirement:
*/
#define PNG_EMPTY /*empty list*/
#define PNG_EXPORT(ordinal, type, name, args) \
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
/* Use PNG_REMOVED to comment out a removed interface. */
#ifndef PNG_REMOVED
# define PNG_REMOVED(ordinal, type, name, args, attributes)
#endif
#ifndef PNG_CALLBACK
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
#endif
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available incorrect use of API
* functions in png.h will generate compiler warnings.
*
* Added at libpng-1.2.41.
*/
#ifndef PNG_NO_PEDANTIC_WARNINGS
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
# endif
#endif
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
/* Support for compiler specific function attributes. These are used
* so that where compiler support is available, incorrect use of API
* functions in png.h will generate compiler warnings. Added at libpng
* version 1.2.41. Disabling these removes the warnings but may also produce
* less efficient code.
*/
# if defined(__clang__) && defined(__has_attribute)
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
# define PNG_NORETURN __attribute__((__noreturn__))
# endif
# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# if !defined(PNG_PRIVATE)
# ifdef __has_extension
# if __has_extension(attribute_unavailable_with_message)
# define PNG_PRIVATE __attribute__((__unavailable__(\
"This function is not exported by libpng.")))
# endif
# endif
# endif
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# elif defined(__GNUC__)
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __attribute__((__noreturn__))
# endif
# if __GNUC__ >= 3
# ifndef PNG_ALLOCATED
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# ifndef PNG_PRIVATE
# if 0 /* Doesn't work so we use deprecated instead*/
# define PNG_PRIVATE \
__attribute__((warning("This function is not exported by libpng.")))
# else
# define PNG_PRIVATE \
__attribute__((__deprecated__))
# endif
# endif
# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
# endif /* __GNUC__ >= 3 */
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /* not supported */
# endif
# ifndef PNG_NORETURN
# define PNG_NORETURN __declspec(noreturn)
# endif
# ifndef PNG_ALLOCATED
# if (_MSC_VER >= 1400)
# define PNG_ALLOCATED __declspec(restrict)
# endif
# endif
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __declspec(deprecated)
# endif
# ifndef PNG_PRIVATE
# define PNG_PRIVATE __declspec(deprecated)
# endif
# ifndef PNG_RESTRICT
# if (_MSC_VER >= 1400)
# define PNG_RESTRICT __restrict
# endif
# endif
# elif defined(__WATCOMC__)
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
# endif
#endif /* PNG_PEDANTIC_WARNINGS */
#ifndef PNG_DEPRECATED
# define PNG_DEPRECATED /* Use of this function is deprecated */
#endif
#ifndef PNG_USE_RESULT
# define PNG_USE_RESULT /* The result of this function must be checked */
#endif
#ifndef PNG_NORETURN
# define PNG_NORETURN /* This function does not return */
#endif
#ifndef PNG_ALLOCATED
# define PNG_ALLOCATED /* The result of the function is new memory */
#endif
#ifndef PNG_PRIVATE
# define PNG_PRIVATE /* This is a private libpng function */
#endif
#ifndef PNG_RESTRICT
# define PNG_RESTRICT /* The C99 "restrict" feature */
#endif
#ifndef PNG_FP_EXPORT /* A floating point API. */
# ifdef PNG_FLOATING_POINT_SUPPORTED
# define PNG_FP_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No floating point APIs */
# define PNG_FP_EXPORT(ordinal, type, name, args)
# endif
#endif
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
# ifdef PNG_FIXED_POINT_SUPPORTED
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No fixed point APIs */
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
# endif
#endif
#ifndef PNG_BUILDING_SYMBOL_TABLE
/* Some typedefs to get us started. These should be safe on most of the common
* platforms.
*
* png_uint_32 and png_int_32 may, currently, be larger than required to hold a
* 32-bit value however this is not normally advisable.
*
* png_uint_16 and png_int_16 should always be two bytes in size - this is
* verified at library build time.
*
* png_byte must always be one byte in size.
*
* The checks below use constants from limits.h, as defined by the ISOC90
* standard.
*/
#if CHAR_BIT == 8 && UCHAR_MAX == 255
typedef unsigned char png_byte;
#else
# error "libpng requires 8-bit bytes"
#endif
#if INT_MIN == -32768 && INT_MAX == 32767
typedef int png_int_16;
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
typedef short png_int_16;
#else
# error "libpng requires a signed 16-bit type"
#endif
#if UINT_MAX == 65535
typedef unsigned int png_uint_16;
#elif USHRT_MAX == 65535
typedef unsigned short png_uint_16;
#else
# error "libpng requires an unsigned 16-bit type"
#endif
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
typedef int png_int_32;
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
typedef long int png_int_32;
#else
# error "libpng requires a signed 32-bit (or more) type"
#endif
#if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32;
#else
# error "libpng requires an unsigned 32-bit (or more) type"
#endif
/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
* From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
* behavior of sizeof and ptrdiff_t are required.
* The legacy typedefs are provided here for backwards compatibility.
*/
typedef size_t png_size_t;
typedef ptrdiff_t png_ptrdiff_t;
/* libpng needs to know the maximum value of 'size_t' and this controls the
* definition of png_alloc_size_t, below. This maximum value of size_t limits
* but does not control the maximum allocations the library makes - there is
* direct application control of this through png_set_user_limits().
*/
#ifndef PNG_SMALL_SIZE_T
/* Compiler specific tests for systems where size_t is known to be less than
* 32 bits (some of these systems may no longer work because of the lack of
* 'far' support; see above.)
*/
# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
(defined(_MSC_VER) && defined(MAXSEG_64K))
# define PNG_SMALL_SIZE_T
# endif
#endif
/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
* than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are
* not necessary; in fact, it is recommended not to use them at all, so that
* the compiler can complain when something turns out to be problematic.
*
* Casts in the other direction (from png_alloc_size_t to size_t or
* png_uint_32) should be explicitly applied; however, we do not expect to
* encounter practical situations that require such conversions.
*
* PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
* 4294967295 - i.e. less than the maximum value of png_uint_32.
*/
#ifdef PNG_SMALL_SIZE_T
typedef png_uint_32 png_alloc_size_t;
#else
typedef size_t png_alloc_size_t;
#endif
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
* implementations of Intel CPU specific support of user-mode segmented address
* spaces, where 16-bit pointers address more than 65536 bytes of memory using
* separate 'segment' registers. The implementation requires two different
* types of pointer (only one of which includes the segment value.)
*
* If required this support is available in version 1.2 of libpng and may be
* available in versions through 1.5, although the correctness of the code has
* not been verified recently.
*/
/* Typedef for floating-point numbers that are converted to fixed-point with a
* multiple of 100,000, e.g., gamma
*/
typedef png_int_32 png_fixed_point;
/* Add typedefs for pointers */
typedef void * png_voidp;
typedef const void * png_const_voidp;
typedef png_byte * png_bytep;
typedef const png_byte * png_const_bytep;
typedef png_uint_32 * png_uint_32p;
typedef const png_uint_32 * png_const_uint_32p;
typedef png_int_32 * png_int_32p;
typedef const png_int_32 * png_const_int_32p;
typedef png_uint_16 * png_uint_16p;
typedef const png_uint_16 * png_const_uint_16p;
typedef png_int_16 * png_int_16p;
typedef const png_int_16 * png_const_int_16p;
typedef char * png_charp;
typedef const char * png_const_charp;
typedef png_fixed_point * png_fixed_point_p;
typedef const png_fixed_point * png_const_fixed_point_p;
typedef size_t * png_size_tp;
typedef const size_t * png_const_size_tp;
#ifdef PNG_STDIO_SUPPORTED
typedef FILE * png_FILE_p;
#endif
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double * png_doublep;
typedef const double * png_const_doublep;
#endif
/* Pointers to pointers; i.e. arrays */
typedef png_byte * * png_bytepp;
typedef png_uint_32 * * png_uint_32pp;
typedef png_int_32 * * png_int_32pp;
typedef png_uint_16 * * png_uint_16pp;
typedef png_int_16 * * png_int_16pp;
typedef const char * * png_const_charpp;
typedef char * * png_charpp;
typedef png_fixed_point * * png_fixed_point_pp;
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double * * png_doublepp;
#endif
/* Pointers to pointers to pointers; i.e., pointer to array */
typedef char * * * png_charppp;
#endif /* PNG_BUILDING_SYMBOL_TABLE */
#endif /* PNGCONF_H */

View File

@ -0,0 +1,219 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.6.37 */
/* Copyright (c) 2018-2019 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
/* and license in png.h */
/* pnglibconf.h */
/* Machine generated file: DO NOT EDIT */
/* Derived from: scripts/pnglibconf.dfa */
#ifndef PNGLCONF_H
#define PNGLCONF_H
/* options */
#define PNG_16BIT_SUPPORTED
#define PNG_ALIGNED_MEMORY_SUPPORTED
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
#define PNG_BENIGN_ERRORS_SUPPORTED
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_COLORSPACE_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
#define PNG_EASY_ACCESS_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_ERROR_TEXT_SUPPORTED
#define PNG_FIXED_POINT_SUPPORTED
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
#define PNG_FLOATING_POINT_SUPPORTED
#define PNG_FORMAT_AFIRST_SUPPORTED
#define PNG_FORMAT_BGR_SUPPORTED
#define PNG_GAMMA_SUPPORTED
#define PNG_GET_PALETTE_MAX_SUPPORTED
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_ALPHA_MODE_SUPPORTED
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_READ_BGR_SUPPORTED
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
#define PNG_READ_EXPAND_16_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED
#define PNG_READ_FILLER_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_INVERT_ALPHA_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_PACK_SUPPORTED
#define PNG_READ_QUANTIZE_SUPPORTED
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_READ_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_TEXT_SUPPORTED
#define PNG_READ_TRANSFORMS_SUPPORTED
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_USER_CHUNKS_SUPPORTED
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_eXIf_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_sCAL_SUPPORTED
#define PNG_READ_sPLT_SUPPORTED
#define PNG_READ_sRGB_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
#define PNG_SAVE_INT_32_SUPPORTED
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_SETJMP_SUPPORTED
#define PNG_SET_OPTION_SUPPORTED
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
#define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_TEXT_SUPPORTED
#define PNG_TIME_RFC1123_SUPPORTED
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_CHUNKS_SUPPORTED
#define PNG_USER_LIMITS_SUPPORTED
#define PNG_USER_MEM_SUPPORTED
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
#define PNG_WARNINGS_SUPPORTED
#define PNG_WRITE_16BIT_SUPPORTED
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED
#define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_WRITE_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED
#define PNG_WRITE_TEXT_SUPPORTED
#define PNG_WRITE_TRANSFORMS_SUPPORTED
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_eXIf_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_WRITE_sCAL_SUPPORTED
#define PNG_WRITE_sPLT_SUPPORTED
#define PNG_WRITE_sRGB_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_cHRM_SUPPORTED
#define PNG_eXIf_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
#define PNG_iTXt_SUPPORTED
#define PNG_oFFs_SUPPORTED
#define PNG_pCAL_SUPPORTED
#define PNG_pHYs_SUPPORTED
#define PNG_sBIT_SUPPORTED
#define PNG_sCAL_SUPPORTED
#define PNG_sPLT_SUPPORTED
#define PNG_sRGB_SUPPORTED
#define PNG_tEXt_SUPPORTED
#define PNG_tIME_SUPPORTED
#define PNG_tRNS_SUPPORTED
#define PNG_zTXt_SUPPORTED
/* end of options */
/* settings */
#define PNG_API_RULE 0
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
#define PNG_INFLATE_BUF_SIZE 1024
#define PNG_LINKAGE_API extern
#define PNG_LINKAGE_CALLBACK extern
#define PNG_LINKAGE_DATA extern
#define PNG_LINKAGE_FUNCTION extern
#define PNG_MAX_GAMMA_8 11
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_QUANTIZE_RED_BITS 5
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
#define PNG_USER_CHUNK_CACHE_MAX 1000
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
#define PNG_USER_HEIGHT_MAX 1000000
#define PNG_USER_WIDTH_MAX 1000000
#define PNG_ZBUF_SIZE 8192
#define PNG_ZLIB_VERNUM 0x12b0
#define PNG_Z_DEFAULT_COMPRESSION (-1)
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
#define PNG_Z_DEFAULT_STRATEGY 1
#define PNG_sCAL_PRECISION 5
#define PNG_sRGB_PROFILE_CHECKS 2
/* end of settings */
#endif /* PNGLCONF_H */

1833
linux/include/libuv/uv.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_AIX_H
#define UV_AIX_H
#define UV_PLATFORM_LOOP_FIELDS \
int fs_fd; \
#define UV_PLATFORM_FS_EVENT_FIELDS \
uv__io_t event_watcher; \
char *dir_filename; \
#endif /* UV_AIX_H */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 1995, 1999
* Berkeley Software Design, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
*
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
*/
#ifndef _IFADDRS_H_
#define _IFADDRS_H_
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
void *ifa_data;
};
/*
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
* to be included it must be included before this header file.
*/
#ifndef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS
#endif

View File

@ -0,0 +1,34 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_BSD_H
#define UV_BSD_H
#define UV_PLATFORM_FS_EVENT_FIELDS \
uv__io_t event_watcher; \
#define UV_IO_PRIVATE_PLATFORM_FIELDS \
int rcount; \
int wcount; \
#define UV_HAVE_KQUEUE 1
#endif /* UV_BSD_H */

View File

@ -0,0 +1,61 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_DARWIN_H
#define UV_DARWIN_H
#if defined(__APPLE__) && defined(__MACH__)
# include <mach/mach.h>
# include <mach/task.h>
# include <mach/semaphore.h>
# include <TargetConditionals.h>
# define UV_PLATFORM_SEM_T semaphore_t
#endif
#define UV_IO_PRIVATE_PLATFORM_FIELDS \
int rcount; \
int wcount; \
#define UV_PLATFORM_LOOP_FIELDS \
uv_thread_t cf_thread; \
void* _cf_reserved; \
void* cf_state; \
uv_mutex_t cf_mutex; \
uv_sem_t cf_sem; \
void* cf_signals[2]; \
#define UV_PLATFORM_FS_EVENT_FIELDS \
uv__io_t event_watcher; \
char* realpath; \
int realpath_len; \
int cf_flags; \
uv_async_t* cf_cb; \
void* cf_events[2]; \
void* cf_member[2]; \
int cf_error; \
uv_mutex_t cf_mutex; \
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
void* select; \
#define UV_HAVE_KQUEUE 1
#endif /* UV_DARWIN_H */

View File

@ -0,0 +1,448 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_ERRNO_H_
#define UV_ERRNO_H_
#include <errno.h>
#if EDOM > 0
# define UV__ERR(x) (-(x))
#else
# define UV__ERR(x) (x)
#endif
#define UV__EOF (-4095)
#define UV__UNKNOWN (-4094)
#define UV__EAI_ADDRFAMILY (-3000)
#define UV__EAI_AGAIN (-3001)
#define UV__EAI_BADFLAGS (-3002)
#define UV__EAI_CANCELED (-3003)
#define UV__EAI_FAIL (-3004)
#define UV__EAI_FAMILY (-3005)
#define UV__EAI_MEMORY (-3006)
#define UV__EAI_NODATA (-3007)
#define UV__EAI_NONAME (-3008)
#define UV__EAI_OVERFLOW (-3009)
#define UV__EAI_SERVICE (-3010)
#define UV__EAI_SOCKTYPE (-3011)
#define UV__EAI_BADHINTS (-3013)
#define UV__EAI_PROTOCOL (-3014)
/* Only map to the system errno on non-Windows platforms. It's apparently
* a fairly common practice for Windows programmers to redefine errno codes.
*/
#if defined(E2BIG) && !defined(_WIN32)
# define UV__E2BIG UV__ERR(E2BIG)
#else
# define UV__E2BIG (-4093)
#endif
#if defined(EACCES) && !defined(_WIN32)
# define UV__EACCES UV__ERR(EACCES)
#else
# define UV__EACCES (-4092)
#endif
#if defined(EADDRINUSE) && !defined(_WIN32)
# define UV__EADDRINUSE UV__ERR(EADDRINUSE)
#else
# define UV__EADDRINUSE (-4091)
#endif
#if defined(EADDRNOTAVAIL) && !defined(_WIN32)
# define UV__EADDRNOTAVAIL UV__ERR(EADDRNOTAVAIL)
#else
# define UV__EADDRNOTAVAIL (-4090)
#endif
#if defined(EAFNOSUPPORT) && !defined(_WIN32)
# define UV__EAFNOSUPPORT UV__ERR(EAFNOSUPPORT)
#else
# define UV__EAFNOSUPPORT (-4089)
#endif
#if defined(EAGAIN) && !defined(_WIN32)
# define UV__EAGAIN UV__ERR(EAGAIN)
#else
# define UV__EAGAIN (-4088)
#endif
#if defined(EALREADY) && !defined(_WIN32)
# define UV__EALREADY UV__ERR(EALREADY)
#else
# define UV__EALREADY (-4084)
#endif
#if defined(EBADF) && !defined(_WIN32)
# define UV__EBADF UV__ERR(EBADF)
#else
# define UV__EBADF (-4083)
#endif
#if defined(EBUSY) && !defined(_WIN32)
# define UV__EBUSY UV__ERR(EBUSY)
#else
# define UV__EBUSY (-4082)
#endif
#if defined(ECANCELED) && !defined(_WIN32)
# define UV__ECANCELED UV__ERR(ECANCELED)
#else
# define UV__ECANCELED (-4081)
#endif
#if defined(ECHARSET) && !defined(_WIN32)
# define UV__ECHARSET UV__ERR(ECHARSET)
#else
# define UV__ECHARSET (-4080)
#endif
#if defined(ECONNABORTED) && !defined(_WIN32)
# define UV__ECONNABORTED UV__ERR(ECONNABORTED)
#else
# define UV__ECONNABORTED (-4079)
#endif
#if defined(ECONNREFUSED) && !defined(_WIN32)
# define UV__ECONNREFUSED UV__ERR(ECONNREFUSED)
#else
# define UV__ECONNREFUSED (-4078)
#endif
#if defined(ECONNRESET) && !defined(_WIN32)
# define UV__ECONNRESET UV__ERR(ECONNRESET)
#else
# define UV__ECONNRESET (-4077)
#endif
#if defined(EDESTADDRREQ) && !defined(_WIN32)
# define UV__EDESTADDRREQ UV__ERR(EDESTADDRREQ)
#else
# define UV__EDESTADDRREQ (-4076)
#endif
#if defined(EEXIST) && !defined(_WIN32)
# define UV__EEXIST UV__ERR(EEXIST)
#else
# define UV__EEXIST (-4075)
#endif
#if defined(EFAULT) && !defined(_WIN32)
# define UV__EFAULT UV__ERR(EFAULT)
#else
# define UV__EFAULT (-4074)
#endif
#if defined(EHOSTUNREACH) && !defined(_WIN32)
# define UV__EHOSTUNREACH UV__ERR(EHOSTUNREACH)
#else
# define UV__EHOSTUNREACH (-4073)
#endif
#if defined(EINTR) && !defined(_WIN32)
# define UV__EINTR UV__ERR(EINTR)
#else
# define UV__EINTR (-4072)
#endif
#if defined(EINVAL) && !defined(_WIN32)
# define UV__EINVAL UV__ERR(EINVAL)
#else
# define UV__EINVAL (-4071)
#endif
#if defined(EIO) && !defined(_WIN32)
# define UV__EIO UV__ERR(EIO)
#else
# define UV__EIO (-4070)
#endif
#if defined(EISCONN) && !defined(_WIN32)
# define UV__EISCONN UV__ERR(EISCONN)
#else
# define UV__EISCONN (-4069)
#endif
#if defined(EISDIR) && !defined(_WIN32)
# define UV__EISDIR UV__ERR(EISDIR)
#else
# define UV__EISDIR (-4068)
#endif
#if defined(ELOOP) && !defined(_WIN32)
# define UV__ELOOP UV__ERR(ELOOP)
#else
# define UV__ELOOP (-4067)
#endif
#if defined(EMFILE) && !defined(_WIN32)
# define UV__EMFILE UV__ERR(EMFILE)
#else
# define UV__EMFILE (-4066)
#endif
#if defined(EMSGSIZE) && !defined(_WIN32)
# define UV__EMSGSIZE UV__ERR(EMSGSIZE)
#else
# define UV__EMSGSIZE (-4065)
#endif
#if defined(ENAMETOOLONG) && !defined(_WIN32)
# define UV__ENAMETOOLONG UV__ERR(ENAMETOOLONG)
#else
# define UV__ENAMETOOLONG (-4064)
#endif
#if defined(ENETDOWN) && !defined(_WIN32)
# define UV__ENETDOWN UV__ERR(ENETDOWN)
#else
# define UV__ENETDOWN (-4063)
#endif
#if defined(ENETUNREACH) && !defined(_WIN32)
# define UV__ENETUNREACH UV__ERR(ENETUNREACH)
#else
# define UV__ENETUNREACH (-4062)
#endif
#if defined(ENFILE) && !defined(_WIN32)
# define UV__ENFILE UV__ERR(ENFILE)
#else
# define UV__ENFILE (-4061)
#endif
#if defined(ENOBUFS) && !defined(_WIN32)
# define UV__ENOBUFS UV__ERR(ENOBUFS)
#else
# define UV__ENOBUFS (-4060)
#endif
#if defined(ENODEV) && !defined(_WIN32)
# define UV__ENODEV UV__ERR(ENODEV)
#else
# define UV__ENODEV (-4059)
#endif
#if defined(ENOENT) && !defined(_WIN32)
# define UV__ENOENT UV__ERR(ENOENT)
#else
# define UV__ENOENT (-4058)
#endif
#if defined(ENOMEM) && !defined(_WIN32)
# define UV__ENOMEM UV__ERR(ENOMEM)
#else
# define UV__ENOMEM (-4057)
#endif
#if defined(ENONET) && !defined(_WIN32)
# define UV__ENONET UV__ERR(ENONET)
#else
# define UV__ENONET (-4056)
#endif
#if defined(ENOSPC) && !defined(_WIN32)
# define UV__ENOSPC UV__ERR(ENOSPC)
#else
# define UV__ENOSPC (-4055)
#endif
#if defined(ENOSYS) && !defined(_WIN32)
# define UV__ENOSYS UV__ERR(ENOSYS)
#else
# define UV__ENOSYS (-4054)
#endif
#if defined(ENOTCONN) && !defined(_WIN32)
# define UV__ENOTCONN UV__ERR(ENOTCONN)
#else
# define UV__ENOTCONN (-4053)
#endif
#if defined(ENOTDIR) && !defined(_WIN32)
# define UV__ENOTDIR UV__ERR(ENOTDIR)
#else
# define UV__ENOTDIR (-4052)
#endif
#if defined(ENOTEMPTY) && !defined(_WIN32)
# define UV__ENOTEMPTY UV__ERR(ENOTEMPTY)
#else
# define UV__ENOTEMPTY (-4051)
#endif
#if defined(ENOTSOCK) && !defined(_WIN32)
# define UV__ENOTSOCK UV__ERR(ENOTSOCK)
#else
# define UV__ENOTSOCK (-4050)
#endif
#if defined(ENOTSUP) && !defined(_WIN32)
# define UV__ENOTSUP UV__ERR(ENOTSUP)
#else
# define UV__ENOTSUP (-4049)
#endif
#if defined(EPERM) && !defined(_WIN32)
# define UV__EPERM UV__ERR(EPERM)
#else
# define UV__EPERM (-4048)
#endif
#if defined(EPIPE) && !defined(_WIN32)
# define UV__EPIPE UV__ERR(EPIPE)
#else
# define UV__EPIPE (-4047)
#endif
#if defined(EPROTO) && !defined(_WIN32)
# define UV__EPROTO UV__ERR(EPROTO)
#else
# define UV__EPROTO (-4046)
#endif
#if defined(EPROTONOSUPPORT) && !defined(_WIN32)
# define UV__EPROTONOSUPPORT UV__ERR(EPROTONOSUPPORT)
#else
# define UV__EPROTONOSUPPORT (-4045)
#endif
#if defined(EPROTOTYPE) && !defined(_WIN32)
# define UV__EPROTOTYPE UV__ERR(EPROTOTYPE)
#else
# define UV__EPROTOTYPE (-4044)
#endif
#if defined(EROFS) && !defined(_WIN32)
# define UV__EROFS UV__ERR(EROFS)
#else
# define UV__EROFS (-4043)
#endif
#if defined(ESHUTDOWN) && !defined(_WIN32)
# define UV__ESHUTDOWN UV__ERR(ESHUTDOWN)
#else
# define UV__ESHUTDOWN (-4042)
#endif
#if defined(ESPIPE) && !defined(_WIN32)
# define UV__ESPIPE UV__ERR(ESPIPE)
#else
# define UV__ESPIPE (-4041)
#endif
#if defined(ESRCH) && !defined(_WIN32)
# define UV__ESRCH UV__ERR(ESRCH)
#else
# define UV__ESRCH (-4040)
#endif
#if defined(ETIMEDOUT) && !defined(_WIN32)
# define UV__ETIMEDOUT UV__ERR(ETIMEDOUT)
#else
# define UV__ETIMEDOUT (-4039)
#endif
#if defined(ETXTBSY) && !defined(_WIN32)
# define UV__ETXTBSY UV__ERR(ETXTBSY)
#else
# define UV__ETXTBSY (-4038)
#endif
#if defined(EXDEV) && !defined(_WIN32)
# define UV__EXDEV UV__ERR(EXDEV)
#else
# define UV__EXDEV (-4037)
#endif
#if defined(EFBIG) && !defined(_WIN32)
# define UV__EFBIG UV__ERR(EFBIG)
#else
# define UV__EFBIG (-4036)
#endif
#if defined(ENOPROTOOPT) && !defined(_WIN32)
# define UV__ENOPROTOOPT UV__ERR(ENOPROTOOPT)
#else
# define UV__ENOPROTOOPT (-4035)
#endif
#if defined(ERANGE) && !defined(_WIN32)
# define UV__ERANGE UV__ERR(ERANGE)
#else
# define UV__ERANGE (-4034)
#endif
#if defined(ENXIO) && !defined(_WIN32)
# define UV__ENXIO UV__ERR(ENXIO)
#else
# define UV__ENXIO (-4033)
#endif
#if defined(EMLINK) && !defined(_WIN32)
# define UV__EMLINK UV__ERR(EMLINK)
#else
# define UV__EMLINK (-4032)
#endif
/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is
* defined. Fortunately, its value is always 64 so it's possible albeit
* icky to hard-code it.
*/
#if defined(EHOSTDOWN) && !defined(_WIN32)
# define UV__EHOSTDOWN UV__ERR(EHOSTDOWN)
#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__NetBSD__) || \
defined(__OpenBSD__)
# define UV__EHOSTDOWN (-64)
#else
# define UV__EHOSTDOWN (-4031)
#endif
#if defined(EREMOTEIO) && !defined(_WIN32)
# define UV__EREMOTEIO UV__ERR(EREMOTEIO)
#else
# define UV__EREMOTEIO (-4030)
#endif
#if defined(ENOTTY) && !defined(_WIN32)
# define UV__ENOTTY UV__ERR(ENOTTY)
#else
# define UV__ENOTTY (-4029)
#endif
#if defined(EFTYPE) && !defined(_WIN32)
# define UV__EFTYPE UV__ERR(EFTYPE)
#else
# define UV__EFTYPE (-4028)
#endif
#if defined(EILSEQ) && !defined(_WIN32)
# define UV__EILSEQ UV__ERR(EILSEQ)
#else
# define UV__EILSEQ (-4027)
#endif
#endif /* UV_ERRNO_H_ */

View File

@ -0,0 +1,34 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_LINUX_H
#define UV_LINUX_H
#define UV_PLATFORM_LOOP_FIELDS \
uv__io_t inotify_read_watcher; \
void* inotify_watchers; \
int inotify_fd; \
#define UV_PLATFORM_FS_EVENT_FIELDS \
void* watchers[2]; \
int wd; \
#endif /* UV_LINUX_H */

View File

@ -0,0 +1,33 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_MVS_H
#define UV_MVS_H
#define UV_PLATFORM_SEM_T long
#define UV_PLATFORM_LOOP_FIELDS \
void* ep; \
#define UV_PLATFORM_FS_EVENT_FIELDS \
char rfis_rftok[8]; \
#endif /* UV_MVS_H */

View File

@ -0,0 +1,31 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_POSIX_H
#define UV_POSIX_H
#define UV_PLATFORM_LOOP_FIELDS \
struct pollfd* poll_fds; \
size_t poll_fds_used; \
size_t poll_fds_size; \
unsigned char poll_fds_iterating; \
#endif /* UV_POSIX_H */

View File

@ -0,0 +1,247 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

View File

@ -0,0 +1,44 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_SUNOS_H
#define UV_SUNOS_H
#include <sys/port.h>
#include <port.h>
/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c,
* add the fs_event fields even when this version of SunOS doesn't support
* file watching.
*/
#define UV_PLATFORM_LOOP_FIELDS \
uv__io_t fs_event_watcher; \
int fs_fd; \
#if defined(PORT_SOURCE_FILE)
# define UV_PLATFORM_FS_EVENT_FIELDS \
file_obj_t fo; \
int fd; \
#endif /* defined(PORT_SOURCE_FILE) */
#endif /* UV_SUNOS_H */

View File

@ -0,0 +1,37 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* This file is private to libuv. It provides common functionality to both
* Windows and Unix backends.
*/
#ifndef UV_THREADPOOL_H_
#define UV_THREADPOOL_H_
struct uv__work {
void (*work)(struct uv__work *w);
void (*done)(struct uv__work *w, int status);
struct uv_loop_s* loop;
void* wq[2];
};
#endif /* UV_THREADPOOL_H_ */

View File

@ -0,0 +1,768 @@
/*-
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 UV_TREE_H_
#define UV_TREE_H_
#ifndef UV__UNUSED
# if __GNUC__
# define UV__UNUSED __attribute__((unused))
# else
# define UV__UNUSED
# endif
#endif
/*
* This file defines data structures for different types of trees:
* splay trees and red-black trees.
*
* A splay tree is a self-organizing data structure. Every operation
* on the tree causes a splay to happen. The splay moves the requested
* node to the root of the tree and partly rebalances it.
*
* This has the benefit that request locality causes faster lookups as
* the requested nodes move to the top of the tree. On the other hand,
* every lookup causes memory writes.
*
* The Balance Theorem bounds the total access time for m operations
* and n inserts on an initially empty tree as O((m + n)lg n). The
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
*
* A red-black tree is a binary search tree with the node color as an
* extra attribute. It fulfills a set of conditions:
* - every search path from the root to a leaf consists of the
* same number of black nodes,
* - each red node (except for the root) has a black parent,
* - each leaf node is black.
*
* Every operation on a red-black tree is bounded as O(lg n).
* The maximum height of a red-black tree is 2lg (n+1).
*/
#define SPLAY_HEAD(name, type) \
struct name { \
struct type *sph_root; /* root of the tree */ \
}
#define SPLAY_INITIALIZER(root) \
{ NULL }
#define SPLAY_INIT(root) do { \
(root)->sph_root = NULL; \
} while (/*CONSTCOND*/ 0)
#define SPLAY_ENTRY(type) \
struct { \
struct type *spe_left; /* left element */ \
struct type *spe_right; /* right element */ \
}
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
#define SPLAY_ROOT(head) (head)->sph_root
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (/*CONSTCOND*/ 0)
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (/*CONSTCOND*/ 0)
#define SPLAY_LINKLEFT(head, tmp, field) do { \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
} while (/*CONSTCOND*/ 0)
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} while (/*CONSTCOND*/ 0)
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
} while (/*CONSTCOND*/ 0)
/* Generates prototypes and inline functions */
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */ \
static __inline struct type * \
name##_SPLAY_FIND(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) \
return(NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) \
return (head->sph_root); \
return (NULL); \
} \
\
static __inline struct type * \
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
{ \
name##_SPLAY(head, elm); \
if (SPLAY_RIGHT(elm, field) != NULL) { \
elm = SPLAY_RIGHT(elm, field); \
while (SPLAY_LEFT(elm, field) != NULL) { \
elm = SPLAY_LEFT(elm, field); \
} \
} else \
elm = NULL; \
return (elm); \
} \
\
static __inline struct type * \
name##_SPLAY_MIN_MAX(struct name *head, int val) \
{ \
name##_SPLAY_MINMAX(head, val); \
return (SPLAY_ROOT(head)); \
}
/* Main splay operation.
* Moves node close to the key of elm to top
*/
#define SPLAY_GENERATE(name, type, field, cmp) \
struct type * \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type * \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void \
name##_SPLAY(struct name *head, struct type *elm) \
{ \
struct type __node, *__left, *__right, *__tmp; \
int __comp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
__left = __right = &__node; \
\
while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) > 0){ \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
} \
\
/* Splay with either the minimum or the maximum element \
* Used to find minimum or maximum element in tree. \
*/ \
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
{ \
struct type __node, *__left, *__right, *__tmp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
__left = __right = &__node; \
\
while (1) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
}
#define SPLAY_NEGINF -1
#define SPLAY_INF 1
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
#define SPLAY_FOREACH(x, name, head) \
for ((x) = SPLAY_MIN(name, head); \
(x) != NULL; \
(x) = SPLAY_NEXT(name, head, x))
/* Macros that define a red-black tree */
#define RB_HEAD(name, type) \
struct name { \
struct type *rbh_root; /* root of the tree */ \
}
#define RB_INITIALIZER(root) \
{ NULL }
#define RB_INIT(root) do { \
(root)->rbh_root = NULL; \
} while (/*CONSTCOND*/ 0)
#define RB_BLACK 0
#define RB_RED 1
#define RB_ENTRY(type) \
struct { \
struct type *rbe_left; /* left element */ \
struct type *rbe_right; /* right element */ \
struct type *rbe_parent; /* parent element */ \
int rbe_color; /* node color */ \
}
#define RB_LEFT(elm, field) (elm)->field.rbe_left
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
#define RB_COLOR(elm, field) (elm)->field.rbe_color
#define RB_ROOT(head) (head)->rbh_root
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
#define RB_SET(elm, parent, field) do { \
RB_PARENT(elm, field) = parent; \
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
RB_COLOR(elm, field) = RB_RED; \
} while (/*CONSTCOND*/ 0)
#define RB_SET_BLACKRED(black, red, field) do { \
RB_COLOR(black, field) = RB_BLACK; \
RB_COLOR(red, field) = RB_RED; \
} while (/*CONSTCOND*/ 0)
#ifndef RB_AUGMENT
#define RB_AUGMENT(x) do {} while (0)
#endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
(tmp) = RB_RIGHT(elm, field); \
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
} else \
(head)->rbh_root = (tmp); \
RB_LEFT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (/*CONSTCOND*/ 0)
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
(tmp) = RB_LEFT(elm, field); \
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
} else \
(head)->rbh_root = (tmp); \
RB_RIGHT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (/*CONSTCOND*/ 0)
/* Generates prototypes and inline functions */
#define RB_PROTOTYPE(name, type, field, cmp) \
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
attr struct type *name##_RB_FIND(struct name *, struct type *); \
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
attr struct type *name##_RB_NEXT(struct type *); \
attr struct type *name##_RB_PREV(struct type *); \
attr struct type *name##_RB_MINMAX(struct name *, int); \
\
/* Main rb operation.
* Moves node close to the key of elm to top
*/
#define RB_GENERATE(name, type, field, cmp) \
RB_GENERATE_INTERNAL(name, type, field, cmp,)
#define RB_GENERATE_STATIC(name, type, field, cmp) \
RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
attr void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
struct type *parent, *gparent, *tmp; \
while ((parent = RB_PARENT(elm, field)) != NULL && \
RB_COLOR(parent, field) == RB_RED) { \
gparent = RB_PARENT(parent, field); \
if (parent == RB_LEFT(gparent, field)) { \
tmp = RB_RIGHT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field); \
elm = gparent; \
continue; \
} \
if (RB_RIGHT(parent, field) == elm) { \
RB_ROTATE_LEFT(head, parent, tmp, field); \
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
} else { \
tmp = RB_LEFT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field); \
elm = gparent; \
continue; \
} \
if (RB_LEFT(parent, field) == elm) { \
RB_ROTATE_RIGHT(head, parent, tmp, field); \
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_LEFT(head, gparent, tmp, field); \
} \
} \
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
} \
\
attr void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
struct type *elm) \
{ \
struct type *tmp; \
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
elm != RB_ROOT(head)) { \
if (RB_LEFT(parent, field) == elm) { \
tmp = RB_RIGHT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_LEFT(head, parent, tmp, field); \
tmp = RB_RIGHT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
struct type *oleft; \
if ((oleft = RB_LEFT(tmp, field)) \
!= NULL) \
RB_COLOR(oleft, field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_RIGHT(head, tmp, oleft, field); \
tmp = RB_RIGHT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_RIGHT(tmp, field)) \
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
RB_ROTATE_LEFT(head, parent, tmp, field); \
elm = RB_ROOT(head); \
break; \
} \
} else { \
tmp = RB_LEFT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_RIGHT(head, parent, tmp, field); \
tmp = RB_LEFT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
struct type *oright; \
if ((oright = RB_RIGHT(tmp, field)) \
!= NULL) \
RB_COLOR(oright, field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_LEFT(head, tmp, oright, field); \
tmp = RB_LEFT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_LEFT(tmp, field)) \
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
RB_ROTATE_RIGHT(head, parent, tmp, field); \
elm = RB_ROOT(head); \
break; \
} \
} \
} \
if (elm) \
RB_COLOR(elm, field) = RB_BLACK; \
} \
\
attr struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
int color; \
if (RB_LEFT(elm, field) == NULL) \
child = RB_RIGHT(elm, field); \
else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \
else { \
struct type *left; \
elm = RB_RIGHT(elm, field); \
while ((left = RB_LEFT(elm, field)) != NULL) \
elm = left; \
child = RB_RIGHT(elm, field); \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
if (RB_PARENT(elm, field) == old) \
parent = elm; \
(elm)->field = (old)->field; \
if (RB_PARENT(old, field)) { \
if (RB_LEFT(RB_PARENT(old, field), field) == old) \
RB_LEFT(RB_PARENT(old, field), field) = elm; \
else \
RB_RIGHT(RB_PARENT(old, field), field) = elm; \
RB_AUGMENT(RB_PARENT(old, field)); \
} else \
RB_ROOT(head) = elm; \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
if (RB_RIGHT(old, field)) \
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
if (parent) { \
left = parent; \
do { \
RB_AUGMENT(left); \
} while ((left = RB_PARENT(left, field)) != NULL); \
} \
goto color; \
} \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
color: \
if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \
return (old); \
} \
\
/* Inserts a node into the RB tree */ \
attr struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
{ \
struct type *tmp; \
struct type *parent = NULL; \
int comp = 0; \
tmp = RB_ROOT(head); \
while (tmp) { \
parent = tmp; \
comp = (cmp)(elm, parent); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
RB_SET(elm, parent, field); \
if (parent != NULL) { \
if (comp < 0) \
RB_LEFT(parent, field) = elm; \
else \
RB_RIGHT(parent, field) = elm; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = elm; \
name##_RB_INSERT_COLOR(head, elm); \
return (NULL); \
} \
\
/* Finds the node with the same key as elm */ \
attr struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
{ \
struct type *tmp = RB_ROOT(head); \
int comp; \
while (tmp) { \
comp = cmp(elm, tmp); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
return (NULL); \
} \
\
/* Finds the first node greater than or equal to the search key */ \
attr struct type * \
name##_RB_NFIND(struct name *head, struct type *elm) \
{ \
struct type *tmp = RB_ROOT(head); \
struct type *res = NULL; \
int comp; \
while (tmp) { \
comp = cmp(elm, tmp); \
if (comp < 0) { \
res = tmp; \
tmp = RB_LEFT(tmp, field); \
} \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
return (res); \
} \
\
/* ARGSUSED */ \
attr struct type * \
name##_RB_NEXT(struct type *elm) \
{ \
if (RB_RIGHT(elm, field)) { \
elm = RB_RIGHT(elm, field); \
while (RB_LEFT(elm, field)) \
elm = RB_LEFT(elm, field); \
} else { \
if (RB_PARENT(elm, field) && \
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
else { \
while (RB_PARENT(elm, field) && \
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
elm = RB_PARENT(elm, field); \
} \
} \
return (elm); \
} \
\
/* ARGSUSED */ \
attr struct type * \
name##_RB_PREV(struct type *elm) \
{ \
if (RB_LEFT(elm, field)) { \
elm = RB_LEFT(elm, field); \
while (RB_RIGHT(elm, field)) \
elm = RB_RIGHT(elm, field); \
} else { \
if (RB_PARENT(elm, field) && \
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
else { \
while (RB_PARENT(elm, field) && \
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
elm = RB_PARENT(elm, field); \
} \
} \
return (elm); \
} \
\
attr struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
struct type *tmp = RB_ROOT(head); \
struct type *parent = NULL; \
while (tmp) { \
parent = tmp; \
if (val < 0) \
tmp = RB_LEFT(tmp, field); \
else \
tmp = RB_RIGHT(tmp, field); \
} \
return (parent); \
}
#define RB_NEGINF -1
#define RB_INF 1
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
#define RB_PREV(name, x, y) name##_RB_PREV(y)
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
#define RB_FOREACH(x, name, head) \
for ((x) = RB_MIN(name, head); \
(x) != NULL; \
(x) = name##_RB_NEXT(x))
#define RB_FOREACH_FROM(x, name, y) \
for ((x) = (y); \
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
(x) = (y))
#define RB_FOREACH_SAFE(x, name, head, y) \
for ((x) = RB_MIN(name, head); \
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
(x) = (y))
#define RB_FOREACH_REVERSE(x, name, head) \
for ((x) = RB_MAX(name, head); \
(x) != NULL; \
(x) = name##_RB_PREV(x))
#define RB_FOREACH_REVERSE_FROM(x, name, y) \
for ((x) = (y); \
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
(x) = (y))
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
for ((x) = RB_MAX(name, head); \
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
(x) = (y))
#endif /* UV_TREE_H_ */

View File

@ -0,0 +1,507 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_UNIX_H
#define UV_UNIX_H
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
#include <termios.h>
#include <pwd.h>
#if !defined(__MVS__)
#include <semaphore.h>
#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */
#endif
#include <pthread.h>
#include <signal.h>
#include "uv/threadpool.h"
#if defined(__linux__)
# include "uv/linux.h"
#elif defined (__MVS__)
# include "uv/os390.h"
#elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */
# include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */
#elif defined(_AIX)
# include "uv/aix.h"
#elif defined(__sun)
# include "uv/sunos.h"
#elif defined(__APPLE__)
# include "uv/darwin.h"
#elif defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# include "uv/bsd.h"
#elif defined(__CYGWIN__) || \
defined(__MSYS__) || \
defined(__GNU__)
# include "uv/posix.h"
#elif defined(__HAIKU__)
# include "uv/posix.h"
#elif defined(__QNX__)
# include "uv/posix.h"
#endif
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
#endif
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif
#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
#endif
struct uv__io_s;
struct uv_loop_s;
typedef void (*uv__io_cb)(struct uv_loop_s* loop,
struct uv__io_s* w,
unsigned int events);
typedef struct uv__io_s uv__io_t;
struct uv__io_s {
uv__io_cb cb;
void* pending_queue[2];
void* watcher_queue[2];
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
unsigned int events; /* Current event mask. */
int fd;
UV_IO_PRIVATE_PLATFORM_FIELDS
};
#ifndef UV_PLATFORM_SEM_T
# define UV_PLATFORM_SEM_T sem_t
#endif
#ifndef UV_PLATFORM_LOOP_FIELDS
# define UV_PLATFORM_LOOP_FIELDS /* empty */
#endif
#ifndef UV_PLATFORM_FS_EVENT_FIELDS
# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */
#endif
#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS
# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */
#endif
/* Note: May be cast to struct iovec. See writev(2). */
typedef struct uv_buf_t {
char* base;
size_t len;
} uv_buf_t;
typedef int uv_file;
typedef int uv_os_sock_t;
typedef int uv_os_fd_t;
typedef pid_t uv_pid_t;
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t uv_once_t;
typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;
typedef UV_PLATFORM_SEM_T uv_sem_t;
typedef pthread_cond_t uv_cond_t;
typedef pthread_key_t uv_key_t;
/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */
#if defined(_AIX) || \
defined(__OpenBSD__) || \
!defined(PTHREAD_BARRIER_SERIAL_THREAD)
/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */
struct _uv_barrier {
uv_mutex_t mutex;
uv_cond_t cond;
unsigned threshold;
unsigned in;
unsigned out;
};
typedef struct {
struct _uv_barrier* b;
# if defined(PTHREAD_BARRIER_SERIAL_THREAD)
/* TODO(bnoordhuis) Remove padding in v2. */
char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)];
# endif
} uv_barrier_t;
#else
typedef pthread_barrier_t uv_barrier_t;
#endif
/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;
typedef uid_t uv_uid_t;
typedef struct dirent uv__dirent_t;
#define UV_DIR_PRIVATE_FIELDS \
DIR* dir;
#if defined(DT_UNKNOWN)
# define HAVE_DIRENT_TYPES
# if defined(DT_REG)
# define UV__DT_FILE DT_REG
# else
# define UV__DT_FILE -1
# endif
# if defined(DT_DIR)
# define UV__DT_DIR DT_DIR
# else
# define UV__DT_DIR -2
# endif
# if defined(DT_LNK)
# define UV__DT_LINK DT_LNK
# else
# define UV__DT_LINK -3
# endif
# if defined(DT_FIFO)
# define UV__DT_FIFO DT_FIFO
# else
# define UV__DT_FIFO -4
# endif
# if defined(DT_SOCK)
# define UV__DT_SOCKET DT_SOCK
# else
# define UV__DT_SOCKET -5
# endif
# if defined(DT_CHR)
# define UV__DT_CHAR DT_CHR
# else
# define UV__DT_CHAR -6
# endif
# if defined(DT_BLK)
# define UV__DT_BLOCK DT_BLK
# else
# define UV__DT_BLOCK -7
# endif
#endif
/* Platform-specific definitions for uv_dlopen support. */
#define UV_DYNAMIC /* empty */
typedef struct {
void* handle;
char* errmsg;
} uv_lib_t;
#define UV_LOOP_PRIVATE_FIELDS \
unsigned long flags; \
int backend_fd; \
void* pending_queue[2]; \
void* watcher_queue[2]; \
uv__io_t** watchers; \
unsigned int nwatchers; \
unsigned int nfds; \
void* wq[2]; \
uv_mutex_t wq_mutex; \
uv_async_t wq_async; \
uv_rwlock_t cloexec_lock; \
uv_handle_t* closing_handles; \
void* process_handles[2]; \
void* prepare_handles[2]; \
void* check_handles[2]; \
void* idle_handles[2]; \
void* async_handles[2]; \
void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \
uv__io_t async_io_watcher; \
int async_wfd; \
struct { \
void* min; \
unsigned int nelts; \
} timer_heap; \
uint64_t timer_counter; \
uint64_t time; \
int signal_pipefd[2]; \
uv__io_t signal_io_watcher; \
uv_signal_t child_watcher; \
int emfile_fd; \
UV_PLATFORM_LOOP_FIELDS \
#define UV_REQ_TYPE_PRIVATE /* empty */
#define UV_REQ_PRIVATE_FIELDS /* empty */
#define UV_PRIVATE_REQ_TYPES /* empty */
#define UV_WRITE_PRIVATE_FIELDS \
void* queue[2]; \
unsigned int write_index; \
uv_buf_t* bufs; \
unsigned int nbufs; \
int error; \
uv_buf_t bufsml[4]; \
#define UV_CONNECT_PRIVATE_FIELDS \
void* queue[2]; \
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
#define UV_UDP_SEND_PRIVATE_FIELDS \
void* queue[2]; \
struct sockaddr_storage addr; \
unsigned int nbufs; \
uv_buf_t* bufs; \
ssize_t status; \
uv_udp_send_cb send_cb; \
uv_buf_t bufsml[4]; \
#define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* next_closing; \
unsigned int flags; \
#define UV_STREAM_PRIVATE_FIELDS \
uv_connect_t *connect_req; \
uv_shutdown_t *shutdown_req; \
uv__io_t io_watcher; \
void* write_queue[2]; \
void* write_completed_queue[2]; \
uv_connection_cb connection_cb; \
int delayed_error; \
int accepted_fd; \
void* queued_fds; \
UV_STREAM_PRIVATE_PLATFORM_FIELDS \
#define UV_TCP_PRIVATE_FIELDS /* empty */
#define UV_UDP_PRIVATE_FIELDS \
uv_alloc_cb alloc_cb; \
uv_udp_recv_cb recv_cb; \
uv__io_t io_watcher; \
void* write_queue[2]; \
void* write_completed_queue[2]; \
#define UV_PIPE_PRIVATE_FIELDS \
const char* pipe_fname; /* strdup'ed */
#define UV_POLL_PRIVATE_FIELDS \
uv__io_t io_watcher;
#define UV_PREPARE_PRIVATE_FIELDS \
uv_prepare_cb prepare_cb; \
void* queue[2]; \
#define UV_CHECK_PRIVATE_FIELDS \
uv_check_cb check_cb; \
void* queue[2]; \
#define UV_IDLE_PRIVATE_FIELDS \
uv_idle_cb idle_cb; \
void* queue[2]; \
#define UV_ASYNC_PRIVATE_FIELDS \
uv_async_cb async_cb; \
void* queue[2]; \
int pending; \
#define UV_TIMER_PRIVATE_FIELDS \
uv_timer_cb timer_cb; \
void* heap_node[3]; \
uint64_t timeout; \
uint64_t repeat; \
uint64_t start_id;
#define UV_GETADDRINFO_PRIVATE_FIELDS \
struct uv__work work_req; \
uv_getaddrinfo_cb cb; \
struct addrinfo* hints; \
char* hostname; \
char* service; \
struct addrinfo* addrinfo; \
int retcode;
#define UV_GETNAMEINFO_PRIVATE_FIELDS \
struct uv__work work_req; \
uv_getnameinfo_cb getnameinfo_cb; \
struct sockaddr_storage storage; \
int flags; \
char host[NI_MAXHOST]; \
char service[NI_MAXSERV]; \
int retcode;
#define UV_PROCESS_PRIVATE_FIELDS \
void* queue[2]; \
int status; \
#define UV_FS_PRIVATE_FIELDS \
const char *new_path; \
uv_file file; \
int flags; \
mode_t mode; \
unsigned int nbufs; \
uv_buf_t* bufs; \
off_t off; \
uv_uid_t uid; \
uv_gid_t gid; \
double atime; \
double mtime; \
struct uv__work work_req; \
uv_buf_t bufsml[4]; \
#define UV_WORK_PRIVATE_FIELDS \
struct uv__work work_req;
#define UV_TTY_PRIVATE_FIELDS \
struct termios orig_termios; \
int mode;
#define UV_SIGNAL_PRIVATE_FIELDS \
/* RB_ENTRY(uv_signal_s) tree_entry; */ \
struct { \
struct uv_signal_s* rbe_left; \
struct uv_signal_s* rbe_right; \
struct uv_signal_s* rbe_parent; \
int rbe_color; \
} tree_entry; \
/* Use two counters here so we don have to fiddle with atomics. */ \
unsigned int caught_signals; \
unsigned int dispatched_signals;
#define UV_FS_EVENT_PRIVATE_FIELDS \
uv_fs_event_cb cb; \
UV_PLATFORM_FS_EVENT_FIELDS \
/* fs open() flags supported on this platform: */
#if defined(O_APPEND)
# define UV_FS_O_APPEND O_APPEND
#else
# define UV_FS_O_APPEND 0
#endif
#if defined(O_CREAT)
# define UV_FS_O_CREAT O_CREAT
#else
# define UV_FS_O_CREAT 0
#endif
#if defined(__linux__) && defined(__arm__)
# define UV_FS_O_DIRECT 0x10000
#elif defined(__linux__) && defined(__m68k__)
# define UV_FS_O_DIRECT 0x10000
#elif defined(__linux__) && defined(__mips__)
# define UV_FS_O_DIRECT 0x08000
#elif defined(__linux__) && defined(__powerpc__)
# define UV_FS_O_DIRECT 0x20000
#elif defined(__linux__) && defined(__s390x__)
# define UV_FS_O_DIRECT 0x04000
#elif defined(__linux__) && defined(__x86_64__)
# define UV_FS_O_DIRECT 0x04000
#elif defined(O_DIRECT)
# define UV_FS_O_DIRECT O_DIRECT
#else
# define UV_FS_O_DIRECT 0
#endif
#if defined(O_DIRECTORY)
# define UV_FS_O_DIRECTORY O_DIRECTORY
#else
# define UV_FS_O_DIRECTORY 0
#endif
#if defined(O_DSYNC)
# define UV_FS_O_DSYNC O_DSYNC
#else
# define UV_FS_O_DSYNC 0
#endif
#if defined(O_EXCL)
# define UV_FS_O_EXCL O_EXCL
#else
# define UV_FS_O_EXCL 0
#endif
#if defined(O_EXLOCK)
# define UV_FS_O_EXLOCK O_EXLOCK
#else
# define UV_FS_O_EXLOCK 0
#endif
#if defined(O_NOATIME)
# define UV_FS_O_NOATIME O_NOATIME
#else
# define UV_FS_O_NOATIME 0
#endif
#if defined(O_NOCTTY)
# define UV_FS_O_NOCTTY O_NOCTTY
#else
# define UV_FS_O_NOCTTY 0
#endif
#if defined(O_NOFOLLOW)
# define UV_FS_O_NOFOLLOW O_NOFOLLOW
#else
# define UV_FS_O_NOFOLLOW 0
#endif
#if defined(O_NONBLOCK)
# define UV_FS_O_NONBLOCK O_NONBLOCK
#else
# define UV_FS_O_NONBLOCK 0
#endif
#if defined(O_RDONLY)
# define UV_FS_O_RDONLY O_RDONLY
#else
# define UV_FS_O_RDONLY 0
#endif
#if defined(O_RDWR)
# define UV_FS_O_RDWR O_RDWR
#else
# define UV_FS_O_RDWR 0
#endif
#if defined(O_SYMLINK)
# define UV_FS_O_SYMLINK O_SYMLINK
#else
# define UV_FS_O_SYMLINK 0
#endif
#if defined(O_SYNC)
# define UV_FS_O_SYNC O_SYNC
#else
# define UV_FS_O_SYNC 0
#endif
#if defined(O_TRUNC)
# define UV_FS_O_TRUNC O_TRUNC
#else
# define UV_FS_O_TRUNC 0
#endif
#if defined(O_WRONLY)
# define UV_FS_O_WRONLY O_WRONLY
#else
# define UV_FS_O_WRONLY 0
#endif
/* fs open() flags supported on other platforms: */
#define UV_FS_O_FILEMAP 0
#define UV_FS_O_RANDOM 0
#define UV_FS_O_SHORT_LIVED 0
#define UV_FS_O_SEQUENTIAL 0
#define UV_FS_O_TEMPORARY 0
#endif /* UV_UNIX_H */

View File

@ -0,0 +1,43 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_VERSION_H
#define UV_VERSION_H
/*
* Versions with the same major number are ABI stable. API is allowed to
* evolve between minor releases, but only in a backwards compatible way.
* Make sure you update the -soname directives in configure.ac
* whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* not UV_VERSION_PATCH.)
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 41
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH))
#endif /* UV_VERSION_H */

View File

@ -0,0 +1,691 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0600
#endif
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
typedef intptr_t ssize_t;
# define SSIZE_MAX INTPTR_MAX
# define _SSIZE_T_
# define _SSIZE_T_DEFINED
#endif
#include <winsock2.h>
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
typedef struct pollfd {
SOCKET fd;
short events;
short revents;
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
#endif
#ifndef LOCALE_INVARIANT
# define LOCALE_INVARIANT 0x007f
#endif
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <process.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/stat.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#include "uv/tree.h"
#include "uv/threadpool.h"
#define MAX_PIPENAME_LEN 256
#ifndef S_IFLNK
# define S_IFLNK 0xA000
#endif
/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
* the following signals already:
*
* #define SIGINT 2
* #define SIGILL 4
* #define SIGABRT_COMPAT 6
* #define SIGFPE 8
* #define SIGSEGV 11
* #define SIGTERM 15
* #define SIGBREAK 21
* #define SIGABRT 22
*
* The additional signals have values that are common on other Unix
* variants (Linux and Darwin)
*/
#define SIGHUP 1
#define SIGKILL 9
#define SIGWINCH 28
/* Redefine NSIG to take SIGWINCH into consideration */
#if defined(NSIG) && NSIG <= SIGWINCH
# undef NSIG
#endif
#ifndef NSIG
# define NSIG SIGWINCH + 1
#endif
/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like
* platforms. However MinGW doesn't define it, so we do. */
#ifndef SIGABRT_COMPAT
# define SIGABRT_COMPAT 6
#endif
/*
* Guids and typedefs for winsock extension functions
* Mingw32 doesn't have these :-(
*/
#ifndef WSAID_ACCEPTEX
# define WSAID_ACCEPTEX \
{0xb5367df1, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
# define WSAID_CONNECTEX \
{0x25a207b9, 0xddf3, 0x4660, \
{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
# define WSAID_GETACCEPTEXSOCKADDRS \
{0xb5367df2, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
# define WSAID_DISCONNECTEX \
{0x7fda2e11, 0x8630, 0x436f, \
{0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}}
# define WSAID_TRANSMITFILE \
{0xb5367df0, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
typedef BOOL (PASCAL *LPFN_ACCEPTEX)
(SOCKET sListenSocket,
SOCKET sAcceptSocket,
PVOID lpOutputBuffer,
DWORD dwReceiveDataLength,
DWORD dwLocalAddressLength,
DWORD dwRemoteAddressLength,
LPDWORD lpdwBytesReceived,
LPOVERLAPPED lpOverlapped);
typedef BOOL (PASCAL *LPFN_CONNECTEX)
(SOCKET s,
const struct sockaddr* name,
int namelen,
PVOID lpSendBuffer,
DWORD dwSendDataLength,
LPDWORD lpdwBytesSent,
LPOVERLAPPED lpOverlapped);
typedef void (PASCAL *LPFN_GETACCEPTEXSOCKADDRS)
(PVOID lpOutputBuffer,
DWORD dwReceiveDataLength,
DWORD dwLocalAddressLength,
DWORD dwRemoteAddressLength,
LPSOCKADDR* LocalSockaddr,
LPINT LocalSockaddrLength,
LPSOCKADDR* RemoteSockaddr,
LPINT RemoteSockaddrLength);
typedef BOOL (PASCAL *LPFN_DISCONNECTEX)
(SOCKET hSocket,
LPOVERLAPPED lpOverlapped,
DWORD dwFlags,
DWORD reserved);
typedef BOOL (PASCAL *LPFN_TRANSMITFILE)
(SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite,
DWORD nNumberOfBytesPerSend,
LPOVERLAPPED lpOverlapped,
LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
DWORD dwFlags);
typedef PVOID RTL_SRWLOCK;
typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
#endif
typedef int (WSAAPI* LPFN_WSARECV)
(SOCKET socket,
LPWSABUF buffers,
DWORD buffer_count,
LPDWORD bytes,
LPDWORD flags,
LPWSAOVERLAPPED overlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
typedef int (WSAAPI* LPFN_WSARECVFROM)
(SOCKET socket,
LPWSABUF buffers,
DWORD buffer_count,
LPDWORD bytes,
LPDWORD flags,
struct sockaddr* addr,
LPINT addr_len,
LPWSAOVERLAPPED overlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
#ifndef _NTDEF_
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
#ifndef RTL_CONDITION_VARIABLE_INIT
typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE;
#endif
typedef struct _AFD_POLL_HANDLE_INFO {
HANDLE Handle;
ULONG Events;
NTSTATUS Status;
} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
typedef struct _AFD_POLL_INFO {
LARGE_INTEGER Timeout;
ULONG NumberOfHandles;
ULONG Exclusive;
AFD_POLL_HANDLE_INFO Handles[1];
} AFD_POLL_INFO, *PAFD_POLL_INFO;
#define UV_MSAFD_PROVIDER_COUNT 3
/**
* It should be possible to cast uv_buf_t[] to WSABUF[]
* see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
*/
typedef struct uv_buf_t {
ULONG len;
char* base;
} uv_buf_t;
typedef int uv_file;
typedef SOCKET uv_os_sock_t;
typedef HANDLE uv_os_fd_t;
typedef int uv_pid_t;
typedef HANDLE uv_thread_t;
typedef HANDLE uv_sem_t;
typedef CRITICAL_SECTION uv_mutex_t;
/* This condition variable implementation is based on the SetEvent solution
* (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
* We could not use the SignalObjectAndWait solution (section 3.4) because
* it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
* uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
*/
typedef union {
CONDITION_VARIABLE cond_var;
struct {
unsigned int waiters_count;
CRITICAL_SECTION waiters_count_lock;
HANDLE signal_event;
HANDLE broadcast_event;
} unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
} uv_cond_t;
typedef union {
struct {
unsigned int num_readers_;
CRITICAL_SECTION num_readers_lock_;
HANDLE write_semaphore_;
} state_;
/* TODO: remove me in v2.x. */
struct {
SRWLOCK unused_;
} unused1_;
/* TODO: remove me in v2.x. */
struct {
uv_mutex_t unused1_;
uv_mutex_t unused2_;
} unused2_;
} uv_rwlock_t;
typedef struct {
unsigned int n;
unsigned int count;
uv_mutex_t mutex;
uv_sem_t turnstile1;
uv_sem_t turnstile2;
} uv_barrier_t;
typedef struct {
DWORD tls_index;
} uv_key_t;
#define UV_ONCE_INIT { 0, NULL }
typedef struct uv_once_s {
unsigned char ran;
HANDLE event;
} uv_once_t;
/* Platform-specific definitions for uv_spawn support. */
typedef unsigned char uv_uid_t;
typedef unsigned char uv_gid_t;
typedef struct uv__dirent_s {
int d_type;
char d_name[1];
} uv__dirent_t;
#define UV_DIR_PRIVATE_FIELDS \
HANDLE dir_handle; \
WIN32_FIND_DATAW find_data; \
BOOL need_find_call;
#define HAVE_DIRENT_TYPES
#define UV__DT_DIR UV_DIRENT_DIR
#define UV__DT_FILE UV_DIRENT_FILE
#define UV__DT_LINK UV_DIRENT_LINK
#define UV__DT_FIFO UV_DIRENT_FIFO
#define UV__DT_SOCKET UV_DIRENT_SOCKET
#define UV__DT_CHAR UV_DIRENT_CHAR
#define UV__DT_BLOCK UV_DIRENT_BLOCK
/* Platform-specific definitions for uv_dlopen support. */
#define UV_DYNAMIC FAR WINAPI
typedef struct {
HMODULE handle;
char* errmsg;
} uv_lib_t;
#define UV_LOOP_PRIVATE_FIELDS \
/* The loop's I/O completion port */ \
HANDLE iocp; \
/* The current time according to the event loop. in msecs. */ \
uint64_t time; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
uv_req_t* pending_reqs_tail; \
/* Head of a single-linked list of closed handles */ \
uv_handle_t* endgame_handles; \
/* TODO(bnoordhuis) Stop heap-allocating |timer_heap| in libuv v2.x. */ \
void* timer_heap; \
/* Lists of active loop (prepare / check / idle) watchers */ \
uv_prepare_t* prepare_handles; \
uv_check_t* check_handles; \
uv_idle_t* idle_handles; \
/* This pointer will refer to the prepare/check/idle handle whose */ \
/* callback is scheduled to be called next. This is needed to allow */ \
/* safe removal from one of the lists above while that list being */ \
/* iterated over. */ \
uv_prepare_t* next_prepare_handle; \
uv_check_t* next_check_handle; \
uv_idle_t* next_idle_handle; \
/* This handle holds the peer sockets for the fast variant of uv_poll_t */ \
SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \
/* Counter to keep track of active tcp streams */ \
unsigned int active_tcp_streams; \
/* Counter to keep track of active udp streams */ \
unsigned int active_udp_streams; \
/* Counter to started timer */ \
uint64_t timer_counter; \
/* Threadpool */ \
void* wq[2]; \
uv_mutex_t wq_mutex; \
uv_async_t wq_async;
#define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \
UV_ACCEPT, \
UV_FS_EVENT_REQ, \
UV_POLL_REQ, \
UV_PROCESS_EXIT, \
UV_READ, \
UV_UDP_RECV, \
UV_WAKEUP, \
UV_SIGNAL_REQ,
#define UV_REQ_PRIVATE_FIELDS \
union { \
/* Used by I/O operations */ \
struct { \
OVERLAPPED overlapped; \
size_t queued_bytes; \
} io; \
} u; \
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
int coalesced; \
uv_buf_t write_buffer; \
HANDLE event_handle; \
HANDLE wait_handle;
#define UV_CONNECT_PRIVATE_FIELDS \
/* empty */
#define UV_SHUTDOWN_PRIVATE_FIELDS \
/* empty */
#define UV_UDP_SEND_PRIVATE_FIELDS \
/* empty */
#define UV_PRIVATE_REQ_TYPES \
typedef struct uv_pipe_accept_s { \
UV_REQ_FIELDS \
HANDLE pipeHandle; \
struct uv_pipe_accept_s* next_pending; \
} uv_pipe_accept_t; \
\
typedef struct uv_tcp_accept_s { \
UV_REQ_FIELDS \
SOCKET accept_socket; \
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
HANDLE event_handle; \
HANDLE wait_handle; \
struct uv_tcp_accept_s* next_pending; \
} uv_tcp_accept_t; \
\
typedef struct uv_read_s { \
UV_REQ_FIELDS \
HANDLE event_handle; \
HANDLE wait_handle; \
} uv_read_t;
#define uv_stream_connection_fields \
unsigned int write_reqs_pending; \
uv_shutdown_t* shutdown_req;
#define uv_stream_server_fields \
uv_connection_cb connection_cb;
#define UV_STREAM_PRIVATE_FIELDS \
unsigned int reqs_pending; \
int activecnt; \
uv_read_t read_req; \
union { \
struct { uv_stream_connection_fields } conn; \
struct { uv_stream_server_fields } serv; \
} stream;
#define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \
unsigned int processed_accepts; \
uv_tcp_accept_t* pending_accepts; \
LPFN_ACCEPTEX func_acceptex;
#define uv_tcp_connection_fields \
uv_buf_t read_buffer; \
LPFN_CONNECTEX func_connectex;
#define UV_TCP_PRIVATE_FIELDS \
SOCKET socket; \
int delayed_error; \
union { \
struct { uv_tcp_server_fields } serv; \
struct { uv_tcp_connection_fields } conn; \
} tcp;
#define UV_UDP_PRIVATE_FIELDS \
SOCKET socket; \
unsigned int reqs_pending; \
int activecnt; \
uv_req_t recv_req; \
uv_buf_t recv_buffer; \
struct sockaddr_storage recv_from; \
int recv_from_len; \
uv_udp_recv_cb recv_cb; \
uv_alloc_cb alloc_cb; \
LPFN_WSARECV func_wsarecv; \
LPFN_WSARECVFROM func_wsarecvfrom;
#define uv_pipe_server_fields \
int pending_instances; \
uv_pipe_accept_t* accept_reqs; \
uv_pipe_accept_t* pending_accepts;
#define uv_pipe_connection_fields \
uv_timer_t* eof_timer; \
uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
DWORD ipc_remote_pid; \
union { \
uint32_t payload_remaining; \
uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
} ipc_data_frame; \
void* ipc_xfer_queue[2]; \
int ipc_xfer_queue_length; \
uv_write_t* non_overlapped_writes_tail; \
CRITICAL_SECTION readfile_thread_lock; \
volatile HANDLE readfile_thread_handle;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
WCHAR* name; \
union { \
struct { uv_pipe_server_fields } serv; \
struct { uv_pipe_connection_fields } conn; \
} pipe;
/* TODO: put the parser states in an union - TTY handles are always half-duplex
* so read-state can safely overlap write-state. */
#define UV_TTY_PRIVATE_FIELDS \
HANDLE handle; \
union { \
struct { \
/* Used for readable TTY handles */ \
/* TODO: remove me in v2.x. */ \
HANDLE unused_; \
uv_buf_t read_line_buffer; \
HANDLE read_raw_wait; \
/* Fields used for translating win keystrokes into vt100 characters */ \
char last_key[8]; \
unsigned char last_key_offset; \
unsigned char last_key_len; \
WCHAR last_utf16_high_surrogate; \
INPUT_RECORD last_input_record; \
} rd; \
struct { \
/* Used for writable TTY handles */ \
/* utf8-to-utf16 conversion state */ \
unsigned int utf8_codepoint; \
unsigned char utf8_bytes_left; \
/* eol conversion state */ \
unsigned char previous_eol; \
/* ansi parser state */ \
unsigned short ansi_parser_state; \
unsigned char ansi_csi_argc; \
unsigned short ansi_csi_argv[4]; \
COORD saved_position; \
WORD saved_attributes; \
} wr; \
} tty;
#define UV_POLL_PRIVATE_FIELDS \
SOCKET socket; \
/* Used in fast mode */ \
SOCKET peer_socket; \
AFD_POLL_INFO afd_poll_info_1; \
AFD_POLL_INFO afd_poll_info_2; \
/* Used in fast and slow mode. */ \
uv_req_t poll_req_1; \
uv_req_t poll_req_2; \
unsigned char submitted_events_1; \
unsigned char submitted_events_2; \
unsigned char mask_events_1; \
unsigned char mask_events_2; \
unsigned char events;
#define UV_TIMER_PRIVATE_FIELDS \
void* heap_node[3]; \
int unused; \
uint64_t timeout; \
uint64_t repeat; \
uint64_t start_id; \
uv_timer_cb timer_cb;
#define UV_ASYNC_PRIVATE_FIELDS \
struct uv_req_s async_req; \
uv_async_cb async_cb; \
/* char to avoid alignment issues */ \
char volatile async_sent;
#define UV_PREPARE_PRIVATE_FIELDS \
uv_prepare_t* prepare_prev; \
uv_prepare_t* prepare_next; \
uv_prepare_cb prepare_cb;
#define UV_CHECK_PRIVATE_FIELDS \
uv_check_t* check_prev; \
uv_check_t* check_next; \
uv_check_cb check_cb;
#define UV_IDLE_PRIVATE_FIELDS \
uv_idle_t* idle_prev; \
uv_idle_t* idle_next; \
uv_idle_cb idle_cb;
#define UV_HANDLE_PRIVATE_FIELDS \
uv_handle_t* endgame_next; \
unsigned int flags;
#define UV_GETADDRINFO_PRIVATE_FIELDS \
struct uv__work work_req; \
uv_getaddrinfo_cb getaddrinfo_cb; \
void* alloc; \
WCHAR* node; \
WCHAR* service; \
/* The addrinfoW field is used to store a pointer to the hints, and */ \
/* later on to store the result of GetAddrInfoW. The final result will */ \
/* be converted to struct addrinfo* and stored in the addrinfo field. */ \
struct addrinfoW* addrinfow; \
struct addrinfo* addrinfo; \
int retcode;
#define UV_GETNAMEINFO_PRIVATE_FIELDS \
struct uv__work work_req; \
uv_getnameinfo_cb getnameinfo_cb; \
struct sockaddr_storage storage; \
int flags; \
char host[NI_MAXHOST]; \
char service[NI_MAXSERV]; \
int retcode;
#define UV_PROCESS_PRIVATE_FIELDS \
struct uv_process_exit_s { \
UV_REQ_FIELDS \
} exit_req; \
BYTE* child_stdio_buffer; \
int exit_signal; \
HANDLE wait_handle; \
HANDLE process_handle; \
volatile char exit_cb_pending;
#define UV_FS_PRIVATE_FIELDS \
struct uv__work work_req; \
int flags; \
DWORD sys_errno_; \
union { \
/* TODO: remove me in 0.9. */ \
WCHAR* pathw; \
int fd; \
} file; \
union { \
struct { \
int mode; \
WCHAR* new_pathw; \
int file_flags; \
int fd_out; \
unsigned int nbufs; \
uv_buf_t* bufs; \
int64_t offset; \
uv_buf_t bufsml[4]; \
} info; \
struct { \
double atime; \
double mtime; \
} time; \
} fs;
#define UV_WORK_PRIVATE_FIELDS \
struct uv__work work_req;
#define UV_FS_EVENT_PRIVATE_FIELDS \
struct uv_fs_event_req_s { \
UV_REQ_FIELDS \
} req; \
HANDLE dir_handle; \
int req_pending; \
uv_fs_event_cb cb; \
WCHAR* filew; \
WCHAR* short_filew; \
WCHAR* dirw; \
char* buffer;
#define UV_SIGNAL_PRIVATE_FIELDS \
RB_ENTRY(uv_signal_s) tree_entry; \
struct uv_req_s signal_req; \
unsigned long pending_signum;
#ifndef F_OK
#define F_OK 0
#endif
#ifndef R_OK
#define R_OK 4
#endif
#ifndef W_OK
#define W_OK 2
#endif
#ifndef X_OK
#define X_OK 1
#endif
/* fs open() flags supported on this platform: */
#define UV_FS_O_APPEND _O_APPEND
#define UV_FS_O_CREAT _O_CREAT
#define UV_FS_O_EXCL _O_EXCL
#define UV_FS_O_FILEMAP 0x20000000
#define UV_FS_O_RANDOM _O_RANDOM
#define UV_FS_O_RDONLY _O_RDONLY
#define UV_FS_O_RDWR _O_RDWR
#define UV_FS_O_SEQUENTIAL _O_SEQUENTIAL
#define UV_FS_O_SHORT_LIVED _O_SHORT_LIVED
#define UV_FS_O_TEMPORARY _O_TEMPORARY
#define UV_FS_O_TRUNC _O_TRUNC
#define UV_FS_O_WRONLY _O_WRONLY
/* fs open() flags supported on other platforms (or mapped on this platform): */
#define UV_FS_O_DIRECT 0x02000000 /* FILE_FLAG_NO_BUFFERING */
#define UV_FS_O_DIRECTORY 0
#define UV_FS_O_DSYNC 0x04000000 /* FILE_FLAG_WRITE_THROUGH */
#define UV_FS_O_EXLOCK 0x10000000 /* EXCLUSIVE SHARING MODE */
#define UV_FS_O_NOATIME 0
#define UV_FS_O_NOCTTY 0
#define UV_FS_O_NOFOLLOW 0
#define UV_FS_O_NONBLOCK 0
#define UV_FS_O_SYMLINK 0
#define UV_FS_O_SYNC 0x08000000 /* FILE_FLAG_WRITE_THROUGH */

View File

@ -0,0 +1,503 @@
// Copyright 2010 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Main decoding functions for WebP images.
//
// Author: Skal (pascal.massimino@gmail.com)
#ifndef WEBP_WEBP_DECODE_H_
#define WEBP_WEBP_DECODE_H_
#include "./types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WEBP_DECODER_ABI_VERSION 0x0209 // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum VP8StatusCode VP8StatusCode;
// typedef enum WEBP_CSP_MODE WEBP_CSP_MODE;
typedef struct WebPRGBABuffer WebPRGBABuffer;
typedef struct WebPYUVABuffer WebPYUVABuffer;
typedef struct WebPDecBuffer WebPDecBuffer;
typedef struct WebPIDecoder WebPIDecoder;
typedef struct WebPBitstreamFeatures WebPBitstreamFeatures;
typedef struct WebPDecoderOptions WebPDecoderOptions;
typedef struct WebPDecoderConfig WebPDecoderConfig;
// Return the decoder's version number, packed in hexadecimal using 8bits for
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WEBP_EXTERN int WebPGetDecoderVersion(void);
// Retrieve basic header information: width, height.
// This function will also validate the header, returning true on success,
// false otherwise. '*width' and '*height' are only valid on successful return.
// Pointers 'width' and 'height' can be passed NULL if deemed irrelevant.
// Note: The following chunk sequences (before the raw VP8/VP8L data) are
// considered valid by this function:
// RIFF + VP8(L)
// RIFF + VP8X + (optional chunks) + VP8(L)
// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size,
int* width, int* height);
// Decodes WebP images pointed to by 'data' and returns RGBA samples, along
// with the dimensions in *width and *height. The ordering of samples in
// memory is R, G, B, A, R, G, B, A... in scan order (endian-independent).
// The returned pointer should be deleted calling WebPFree().
// Returns NULL in case of error.
WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
int* width, int* height);
// Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data.
WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
int* width, int* height);
// Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data.
WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
int* width, int* height);
// Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data.
// If the bitstream contains transparency, it is ignored.
WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
int* width, int* height);
// Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data.
WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
int* width, int* height);
// Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer
// returned is the Y samples buffer. Upon return, *u and *v will point to
// the U and V chroma data. These U and V buffers need NOT be passed to
// WebPFree(), unlike the returned Y luma one. The dimension of the U and V
// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
// have a common stride returned as '*uv_stride'.
// Return NULL in case of error.
// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
int* width, int* height,
uint8_t** u, uint8_t** v,
int* stride, int* uv_stride);
// These five functions are variants of the above ones, that decode the image
// directly into a pre-allocated buffer 'output_buffer'. The maximum storage
// available in this buffer is indicated by 'output_buffer_size'. If this
// storage is not sufficient (or an error occurred), NULL is returned.
// Otherwise, output_buffer is returned, for convenience.
// The parameter 'output_stride' specifies the distance (in bytes)
// between scanlines. Hence, output_buffer_size is expected to be at least
// output_stride x picture-height.
WEBP_EXTERN uint8_t* WebPDecodeRGBAInto(
const uint8_t* data, size_t data_size,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
WEBP_EXTERN uint8_t* WebPDecodeARGBInto(
const uint8_t* data, size_t data_size,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
WEBP_EXTERN uint8_t* WebPDecodeBGRAInto(
const uint8_t* data, size_t data_size,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
// RGB and BGR variants. Here too the transparency information, if present,
// will be dropped and ignored.
WEBP_EXTERN uint8_t* WebPDecodeRGBInto(
const uint8_t* data, size_t data_size,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
WEBP_EXTERN uint8_t* WebPDecodeBGRInto(
const uint8_t* data, size_t data_size,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
// WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly
// into pre-allocated luma/chroma plane buffers. This function requires the
// strides to be passed: one for the luma plane and one for each of the
// chroma ones. The size of each plane buffer is passed as 'luma_size',
// 'u_size' and 'v_size' respectively.
// Pointer to the luma plane ('*luma') is returned or NULL if an error occurred
// during decoding (or because some buffers were found to be too small).
WEBP_EXTERN uint8_t* WebPDecodeYUVInto(
const uint8_t* data, size_t data_size,
uint8_t* luma, size_t luma_size, int luma_stride,
uint8_t* u, size_t u_size, int u_stride,
uint8_t* v, size_t v_size, int v_stride);
//------------------------------------------------------------------------------
// Output colorspaces and buffer
// Colorspaces
// Note: the naming describes the byte-ordering of packed samples in memory.
// For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,...
// Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels.
// RGBA-4444 and RGB-565 colorspaces are represented by following byte-order:
// RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ...
// RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ...
// In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for
// these two modes:
// RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ...
// RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ...
typedef enum WEBP_CSP_MODE {
MODE_RGB = 0, MODE_RGBA = 1,
MODE_BGR = 2, MODE_BGRA = 3,
MODE_ARGB = 4, MODE_RGBA_4444 = 5,
MODE_RGB_565 = 6,
// RGB-premultiplied transparent modes (alpha value is preserved)
MODE_rgbA = 7,
MODE_bgrA = 8,
MODE_Argb = 9,
MODE_rgbA_4444 = 10,
// YUV modes must come after RGB ones.
MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0
MODE_LAST = 13
} WEBP_CSP_MODE;
// Some useful macros:
static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) {
return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb ||
mode == MODE_rgbA_4444);
}
static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) {
return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB ||
mode == MODE_RGBA_4444 || mode == MODE_YUVA ||
WebPIsPremultipliedMode(mode));
}
static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) {
return (mode < MODE_YUV);
}
//------------------------------------------------------------------------------
// WebPDecBuffer: Generic structure for describing the output sample buffer.
struct WebPRGBABuffer { // view as RGBA
uint8_t* rgba; // pointer to RGBA samples
int stride; // stride in bytes from one scanline to the next.
size_t size; // total size of the *rgba buffer.
};
struct WebPYUVABuffer { // view as YUVA
uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples
int y_stride; // luma stride
int u_stride, v_stride; // chroma strides
int a_stride; // alpha stride
size_t y_size; // luma plane size
size_t u_size, v_size; // chroma planes size
size_t a_size; // alpha-plane size
};
// Output buffer
struct WebPDecBuffer {
WEBP_CSP_MODE colorspace; // Colorspace.
int width, height; // Dimensions.
int is_external_memory; // If non-zero, 'internal_memory' pointer is not
// used. If value is '2' or more, the external
// memory is considered 'slow' and multiple
// read/write will be avoided.
union {
WebPRGBABuffer RGBA;
WebPYUVABuffer YUVA;
} u; // Nameless union of buffer parameters.
uint32_t pad[4]; // padding for later use
uint8_t* private_memory; // Internally allocated memory (only when
// is_external_memory is 0). Should not be used
// externally, but accessed via the buffer union.
};
// Internal, version-checked, entry point
WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int);
// Initialize the structure as empty. Must be called before any other use.
// Returns false in case of version mismatch
static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) {
return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION);
}
// Free any memory associated with the buffer. Must always be called last.
// Note: doesn't free the 'buffer' structure itself.
WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer);
//------------------------------------------------------------------------------
// Enumeration of the status codes
typedef enum VP8StatusCode {
VP8_STATUS_OK = 0,
VP8_STATUS_OUT_OF_MEMORY,
VP8_STATUS_INVALID_PARAM,
VP8_STATUS_BITSTREAM_ERROR,
VP8_STATUS_UNSUPPORTED_FEATURE,
VP8_STATUS_SUSPENDED,
VP8_STATUS_USER_ABORT,
VP8_STATUS_NOT_ENOUGH_DATA
} VP8StatusCode;
//------------------------------------------------------------------------------
// Incremental decoding
//
// This API allows streamlined decoding of partial data.
// Picture can be incrementally decoded as data become available thanks to the
// WebPIDecoder object. This object can be left in a SUSPENDED state if the
// picture is only partially decoded, pending additional input.
// Code example:
//
// WebPInitDecBuffer(&output_buffer);
// output_buffer.colorspace = mode;
// ...
// WebPIDecoder* idec = WebPINewDecoder(&output_buffer);
// while (additional_data_is_available) {
// // ... (get additional data in some new_data[] buffer)
// status = WebPIAppend(idec, new_data, new_data_size);
// if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
// break; // an error occurred.
// }
//
// // The above call decodes the current available buffer.
// // Part of the image can now be refreshed by calling
// // WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
// }
// WebPIDelete(idec);
// Creates a new incremental decoder with the supplied buffer parameter.
// This output_buffer can be passed NULL, in which case a default output buffer
// is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer'
// is kept, which means that the lifespan of 'output_buffer' must be larger than
// that of the returned WebPIDecoder object.
// The supplied 'output_buffer' content MUST NOT be changed between calls to
// WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is
// not set to 0. In such a case, it is allowed to modify the pointers, size and
// stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain
// within valid bounds.
// All other fields of WebPDecBuffer MUST remain constant between calls.
// Returns NULL if the allocation failed.
WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer);
// This function allocates and initializes an incremental-decoder object, which
// will output the RGB/A samples specified by 'csp' into a preallocated
// buffer 'output_buffer'. The size of this buffer is at least
// 'output_buffer_size' and the stride (distance in bytes between two scanlines)
// is specified by 'output_stride'.
// Additionally, output_buffer can be passed NULL in which case the output
// buffer will be allocated automatically when the decoding starts. The
// colorspace 'csp' is taken into account for allocating this buffer. All other
// parameters are ignored.
// Returns NULL if the allocation failed, or if some parameters are invalid.
WEBP_EXTERN WebPIDecoder* WebPINewRGB(
WEBP_CSP_MODE csp,
uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
// This function allocates and initializes an incremental-decoder object, which
// will output the raw luma/chroma samples into a preallocated planes if
// supplied. The luma plane is specified by its pointer 'luma', its size
// 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane
// is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v
// plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer
// can be pass NULL in case one is not interested in the transparency plane.
// Conversely, 'luma' can be passed NULL if no preallocated planes are supplied.
// In this case, the output buffer will be automatically allocated (using
// MODE_YUVA) when decoding starts. All parameters are then ignored.
// Returns NULL if the allocation failed or if a parameter is invalid.
WEBP_EXTERN WebPIDecoder* WebPINewYUVA(
uint8_t* luma, size_t luma_size, int luma_stride,
uint8_t* u, size_t u_size, int u_stride,
uint8_t* v, size_t v_size, int v_stride,
uint8_t* a, size_t a_size, int a_stride);
// Deprecated version of the above, without the alpha plane.
// Kept for backward compatibility.
WEBP_EXTERN WebPIDecoder* WebPINewYUV(
uint8_t* luma, size_t luma_size, int luma_stride,
uint8_t* u, size_t u_size, int u_stride,
uint8_t* v, size_t v_size, int v_stride);
// Deletes the WebPIDecoder object and associated memory. Must always be called
// if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded.
WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec);
// Copies and decodes the next available data. Returns VP8_STATUS_OK when
// the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more
// data is expected. Returns error in other cases.
WEBP_EXTERN VP8StatusCode WebPIAppend(
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
// A variant of the above function to be used when data buffer contains
// partial data from the beginning. In this case data buffer is not copied
// to the internal memory.
// Note that the value of the 'data' pointer can change between calls to
// WebPIUpdate, for instance when the data buffer is resized to fit larger data.
WEBP_EXTERN VP8StatusCode WebPIUpdate(
WebPIDecoder* idec, const uint8_t* data, size_t data_size);
// Returns the RGB/A image decoded so far. Returns NULL if output params
// are not initialized yet. The RGB/A output type corresponds to the colorspace
// specified during call to WebPINewDecoder() or WebPINewRGB().
// *last_y is the index of last decoded row in raster scan order. Some pointers
// (*last_y, *width etc.) can be NULL if corresponding information is not
// needed. The values in these pointers are only valid on successful (non-NULL)
// return.
WEBP_EXTERN uint8_t* WebPIDecGetRGB(
const WebPIDecoder* idec, int* last_y,
int* width, int* height, int* stride);
// Same as above function to get a YUVA image. Returns pointer to the luma
// plane or NULL in case of error. If there is no alpha information
// the alpha pointer '*a' will be returned NULL.
WEBP_EXTERN uint8_t* WebPIDecGetYUVA(
const WebPIDecoder* idec, int* last_y,
uint8_t** u, uint8_t** v, uint8_t** a,
int* width, int* height, int* stride, int* uv_stride, int* a_stride);
// Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the
// alpha information (if present). Kept for backward compatibility.
static WEBP_INLINE uint8_t* WebPIDecGetYUV(
const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v,
int* width, int* height, int* stride, int* uv_stride) {
return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height,
stride, uv_stride, NULL);
}
// Generic call to retrieve information about the displayable area.
// If non NULL, the left/right/width/height pointers are filled with the visible
// rectangular area so far.
// Returns NULL in case the incremental decoder object is in an invalid state.
// Otherwise returns the pointer to the internal representation. This structure
// is read-only, tied to WebPIDecoder's lifespan and should not be modified.
WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea(
const WebPIDecoder* idec, int* left, int* top, int* width, int* height);
//------------------------------------------------------------------------------
// Advanced decoding parametrization
//
// Code sample for using the advanced decoding API
/*
// A) Init a configuration object
WebPDecoderConfig config;
CHECK(WebPInitDecoderConfig(&config));
// B) optional: retrieve the bitstream's features.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
// C) Adjust 'config', if needed
config.no_fancy_upsampling = 1;
config.output.colorspace = MODE_BGRA;
// etc.
// Note that you can also make config.output point to an externally
// supplied memory buffer, provided it's big enough to store the decoded
// picture. Otherwise, config.output will just be used to allocate memory
// and store the decoded picture.
// D) Decode!
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
// E) Decoded image is now in config.output (and config.output.u.RGBA)
// F) Reclaim memory allocated in config's object. It's safe to call
// this function even if the memory is external and wasn't allocated
// by WebPDecode().
WebPFreeDecBuffer(&config.output);
*/
// Features gathered from the bitstream
struct WebPBitstreamFeatures {
int width; // Width in pixels, as read from the bitstream.
int height; // Height in pixels, as read from the bitstream.
int has_alpha; // True if the bitstream contains an alpha channel.
int has_animation; // True if the bitstream is an animation.
int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
uint32_t pad[5]; // padding for later use
};
// Internal, version-checked, entry point
WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal(
const uint8_t*, size_t, WebPBitstreamFeatures*, int);
// Retrieve features from the bitstream. The *features structure is filled
// with information gathered from the bitstream.
// Returns VP8_STATUS_OK when the features are successfully retrieved. Returns
// VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the
// features from headers. Returns error in other cases.
// Note: The following chunk sequences (before the raw VP8/VP8L data) are
// considered valid by this function:
// RIFF + VP8(L)
// RIFF + VP8X + (optional chunks) + VP8(L)
// ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
// VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
static WEBP_INLINE VP8StatusCode WebPGetFeatures(
const uint8_t* data, size_t data_size,
WebPBitstreamFeatures* features) {
return WebPGetFeaturesInternal(data, data_size, features,
WEBP_DECODER_ABI_VERSION);
}
// Decoding options
struct WebPDecoderOptions {
int bypass_filtering; // if true, skip the in-loop filtering
int no_fancy_upsampling; // if true, use faster pointwise upsampler
int use_cropping; // if true, cropping is applied _first_
int crop_left, crop_top; // top-left position for cropping.
// Will be snapped to even values.
int crop_width, crop_height; // dimension of the cropping area
int use_scaling; // if true, scaling is applied _afterward_
int scaled_width, scaled_height; // final resolution
int use_threads; // if true, use multi-threaded decoding
int dithering_strength; // dithering strength (0=Off, 100=full)
int flip; // if true, flip output vertically
int alpha_dithering_strength; // alpha dithering strength in [0..100]
uint32_t pad[5]; // padding for later use
};
// Main object storing the configuration for advanced decoding.
struct WebPDecoderConfig {
WebPBitstreamFeatures input; // Immutable bitstream features (optional)
WebPDecBuffer output; // Output buffer (can point to external mem)
WebPDecoderOptions options; // Decoding options
};
// Internal, version-checked, entry point
WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int);
// Initialize the configuration as empty. This function must always be
// called first, unless WebPGetFeatures() is to be called.
// Returns false in case of mismatched version.
static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) {
return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION);
}
// Instantiate a new incremental decoder object with the requested
// configuration. The bitstream can be passed using 'data' and 'data_size'
// parameter, in which case the features will be parsed and stored into
// config->input. Otherwise, 'data' can be NULL and no parsing will occur.
// Note that 'config' can be NULL too, in which case a default configuration
// is used. If 'config' is not NULL, it must outlive the WebPIDecoder object
// as some references to its fields will be used. No internal copy of 'config'
// is made.
// The return WebPIDecoder object must always be deleted calling WebPIDelete().
// Returns NULL in case of error (and config->status will then reflect
// the error condition, if available).
WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size,
WebPDecoderConfig* config);
// Non-incremental version. This version decodes the full data at once, taking
// 'config' into account. Returns decoding status (which should be VP8_STATUS_OK
// if the decoding was successful). Note that 'config' cannot be NULL.
WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
WebPDecoderConfig* config);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_DECODE_H_

View File

@ -0,0 +1,363 @@
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Demux API.
// Enables extraction of image and extended format data from WebP files.
// Code Example: Demuxing WebP data to extract all the frames, ICC profile
// and EXIF/XMP metadata.
/*
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
// ... (Get information about the features present in the WebP file).
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
// ... (Iterate over all frames).
WebPIterator iter;
if (WebPDemuxGetFrame(demux, 1, &iter)) {
do {
// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
// ... and get other frame properties like width, height, offsets etc.
// ... see 'struct WebPIterator' below for more info).
} while (WebPDemuxNextFrame(&iter));
WebPDemuxReleaseIterator(&iter);
}
// ... (Extract metadata).
WebPChunkIterator chunk_iter;
if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
// ... (Consume the ICC profile in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
// ... (Consume the XMP metadata in 'chunk_iter.chunk').
WebPDemuxReleaseChunkIterator(&chunk_iter);
WebPDemuxDelete(demux);
*/
#ifndef WEBP_WEBP_DEMUX_H_
#define WEBP_WEBP_DEMUX_H_
#include "./decode.h" // for WEBP_CSP_MODE
#include "./mux_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum WebPDemuxState WebPDemuxState;
// typedef enum WebPFormatFeature WebPFormatFeature;
typedef struct WebPDemuxer WebPDemuxer;
typedef struct WebPIterator WebPIterator;
typedef struct WebPChunkIterator WebPChunkIterator;
typedef struct WebPAnimInfo WebPAnimInfo;
typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions;
//------------------------------------------------------------------------------
// Returns the version number of the demux library, packed in hexadecimal using
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WEBP_EXTERN int WebPGetDemuxVersion(void);
//------------------------------------------------------------------------------
// Life of a Demux object
typedef enum WebPDemuxState {
WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing.
WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header.
WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete,
// data may be available.
WEBP_DEMUX_DONE = 2 // Entire file has been parsed.
} WebPDemuxState;
// Internal, version-checked, entry point
WEBP_EXTERN WebPDemuxer* WebPDemuxInternal(
const WebPData*, int, WebPDemuxState*, int);
// Parses the full WebP file given by 'data'. For single images the WebP file
// header alone or the file header and the chunk header may be absent.
// Returns a WebPDemuxer object on successful parse, NULL otherwise.
static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) {
return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION);
}
// Parses the possibly incomplete WebP file given by 'data'.
// If 'state' is non-NULL it will be set to indicate the status of the demuxer.
// Returns NULL in case of error or if there isn't enough data to start parsing;
// and a WebPDemuxer object on successful parse.
// Note that WebPDemuxer keeps internal pointers to 'data' memory segment.
// If this data is volatile, the demuxer object should be deleted (by calling
// WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data.
// This is usually an inexpensive operation.
static WEBP_INLINE WebPDemuxer* WebPDemuxPartial(
const WebPData* data, WebPDemuxState* state) {
return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION);
}
// Frees memory associated with 'dmux'.
WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux);
//------------------------------------------------------------------------------
// Data/information extraction.
typedef enum WebPFormatFeature {
WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags
// corresponding to the 'VP8X' chunk (if present).
WEBP_FF_CANVAS_WIDTH,
WEBP_FF_CANVAS_HEIGHT,
WEBP_FF_LOOP_COUNT, // only relevant for animated file
WEBP_FF_BACKGROUND_COLOR, // idem.
WEBP_FF_FRAME_COUNT // Number of frames present in the demux object.
// In case of a partial demux, this is the number
// of frames seen so far, with the last frame
// possibly being partial.
} WebPFormatFeature;
// Get the 'feature' value from the 'dmux'.
// NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial()
// returned a state > WEBP_DEMUX_PARSING_HEADER.
// If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise
// combination of WebPFeatureFlags values.
// If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned
// value is only meaningful if the bitstream is animated.
WEBP_EXTERN uint32_t WebPDemuxGetI(
const WebPDemuxer* dmux, WebPFormatFeature feature);
//------------------------------------------------------------------------------
// Frame iteration.
struct WebPIterator {
int frame_num;
int num_frames; // equivalent to WEBP_FF_FRAME_COUNT.
int x_offset, y_offset; // offset relative to the canvas.
int width, height; // dimensions of this frame.
int duration; // display duration in milliseconds.
WebPMuxAnimDispose dispose_method; // dispose method for the frame.
int complete; // true if 'fragment' contains a full frame. partial images
// may still be decoded with the WebP incremental decoder.
WebPData fragment; // The frame given by 'frame_num'. Note for historical
// reasons this is called a fragment.
int has_alpha; // True if the frame contains transparency.
WebPMuxAnimBlend blend_method; // Blend operation for the frame.
uint32_t pad[2]; // padding for later use.
void* private_; // for internal use only.
};
// Retrieves frame 'frame_number' from 'dmux'.
// 'iter->fragment' points to the frame on return from this function.
// Setting 'frame_number' equal to 0 will return the last frame of the image.
// Returns false if 'dmux' is NULL or frame 'frame_number' is not present.
// Call WebPDemuxReleaseIterator() when use of the iterator is complete.
// NOTE: 'dmux' must persist for the lifetime of 'iter'.
WEBP_EXTERN int WebPDemuxGetFrame(
const WebPDemuxer* dmux, int frame_number, WebPIterator* iter);
// Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or
// previous ('iter->frame_num' - 1) frame. These functions do not loop.
// Returns true on success, false otherwise.
WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter);
WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter);
// Releases any memory associated with 'iter'.
// Must be called before any subsequent calls to WebPDemuxGetChunk() on the same
// iter. Also, must be called before destroying the associated WebPDemuxer with
// WebPDemuxDelete().
WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter);
//------------------------------------------------------------------------------
// Chunk iteration.
struct WebPChunkIterator {
// The current and total number of chunks with the fourcc given to
// WebPDemuxGetChunk().
int chunk_num;
int num_chunks;
WebPData chunk; // The payload of the chunk.
uint32_t pad[6]; // padding for later use
void* private_;
};
// Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from
// 'dmux'.
// 'fourcc' is a character array containing the fourcc of the chunk to return,
// e.g., "ICCP", "XMP ", "EXIF", etc.
// Setting 'chunk_number' equal to 0 will return the last chunk in a set.
// Returns true if the chunk is found, false otherwise. Image related chunk
// payloads are accessed through WebPDemuxGetFrame() and related functions.
// Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete.
// NOTE: 'dmux' must persist for the lifetime of the iterator.
WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux,
const char fourcc[4], int chunk_number,
WebPChunkIterator* iter);
// Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous
// ('iter->chunk_num' - 1) chunk. These functions do not loop.
// Returns true on success, false otherwise.
WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter);
WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter);
// Releases any memory associated with 'iter'.
// Must be called before destroying the associated WebPDemuxer with
// WebPDemuxDelete().
WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter);
//------------------------------------------------------------------------------
// WebPAnimDecoder API
//
// This API allows decoding (possibly) animated WebP images.
//
// Code Example:
/*
WebPAnimDecoderOptions dec_options;
WebPAnimDecoderOptionsInit(&dec_options);
// Tune 'dec_options' as needed.
WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
WebPAnimInfo anim_info;
WebPAnimDecoderGetInfo(dec, &anim_info);
for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
while (WebPAnimDecoderHasMoreFrames(dec)) {
uint8_t* buf;
int timestamp;
WebPAnimDecoderGetNext(dec, &buf, &timestamp);
// ... (Render 'buf' based on 'timestamp').
// ... (Do NOT free 'buf', as it is owned by 'dec').
}
WebPAnimDecoderReset(dec);
}
const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
WebPAnimDecoderDelete(dec);
*/
typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object.
// Global options.
struct WebPAnimDecoderOptions {
// Output colorspace. Only the following modes are supported:
// MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA.
WEBP_CSP_MODE color_mode;
int use_threads; // If true, use multi-threaded decoding.
uint32_t padding[7]; // Padding for later use.
};
// Internal, version-checked, entry point.
WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal(
WebPAnimDecoderOptions*, int);
// Should always be called, to initialize a fresh WebPAnimDecoderOptions
// structure before modification. Returns false in case of version mismatch.
// WebPAnimDecoderOptionsInit() must have succeeded before using the
// 'dec_options' object.
static WEBP_INLINE int WebPAnimDecoderOptionsInit(
WebPAnimDecoderOptions* dec_options) {
return WebPAnimDecoderOptionsInitInternal(dec_options,
WEBP_DEMUX_ABI_VERSION);
}
// Internal, version-checked, entry point.
WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal(
const WebPData*, const WebPAnimDecoderOptions*, int);
// Creates and initializes a WebPAnimDecoder object.
// Parameters:
// webp_data - (in) WebP bitstream. This should remain unchanged during the
// lifetime of the output WebPAnimDecoder object.
// dec_options - (in) decoding options. Can be passed NULL to choose
// reasonable defaults (in particular, color mode MODE_RGBA
// will be picked).
// Returns:
// A pointer to the newly created WebPAnimDecoder object, or NULL in case of
// parsing error, invalid option or memory error.
static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew(
const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) {
return WebPAnimDecoderNewInternal(webp_data, dec_options,
WEBP_DEMUX_ABI_VERSION);
}
// Global information about the animation..
struct WebPAnimInfo {
uint32_t canvas_width;
uint32_t canvas_height;
uint32_t loop_count;
uint32_t bgcolor;
uint32_t frame_count;
uint32_t pad[4]; // padding for later use
};
// Get global information about the animation.
// Parameters:
// dec - (in) decoder instance to get information from.
// info - (out) global information fetched from the animation.
// Returns:
// True on success.
WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec,
WebPAnimInfo* info);
// Fetch the next frame from 'dec' based on options supplied to
// WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size
// 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The
// returned buffer 'buf' is valid only until the next call to
// WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete().
// Parameters:
// dec - (in/out) decoder instance from which the next frame is to be fetched.
// buf - (out) decoded frame.
// timestamp - (out) timestamp of the frame in milliseconds.
// Returns:
// False if any of the arguments are NULL, or if there is a parsing or
// decoding error, or if there are no more frames. Otherwise, returns true.
WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
uint8_t** buf, int* timestamp);
// Check if there are more frames left to decode.
// Parameters:
// dec - (in) decoder instance to be checked.
// Returns:
// True if 'dec' is not NULL and some frames are yet to be decoded.
// Otherwise, returns false.
WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec);
// Resets the WebPAnimDecoder object, so that next call to
// WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be
// helpful when all frames need to be decoded multiple times (e.g.
// info.loop_count times) without destroying and recreating the 'dec' object.
// Parameters:
// dec - (in/out) decoder instance to be reset
WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec);
// Grab the internal demuxer object.
// Getting the demuxer object can be useful if one wants to use operations only
// available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned
// demuxer object is owned by 'dec' and is valid only until the next call to
// WebPAnimDecoderDelete().
//
// Parameters:
// dec - (in) decoder instance from which the demuxer object is to be fetched.
WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer(
const WebPAnimDecoder* dec);
// Deletes the WebPAnimDecoder object.
// Parameters:
// dec - (in/out) decoder instance to be deleted
WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_DEMUX_H_

View File

@ -0,0 +1,552 @@
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// WebP encoder: main interface
//
// Author: Skal (pascal.massimino@gmail.com)
#ifndef WEBP_WEBP_ENCODE_H_
#define WEBP_WEBP_ENCODE_H_
#include "./types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum WebPImageHint WebPImageHint;
// typedef enum WebPEncCSP WebPEncCSP;
// typedef enum WebPPreset WebPPreset;
// typedef enum WebPEncodingError WebPEncodingError;
typedef struct WebPConfig WebPConfig;
typedef struct WebPPicture WebPPicture; // main structure for I/O
typedef struct WebPAuxStats WebPAuxStats;
typedef struct WebPMemoryWriter WebPMemoryWriter;
// Return the encoder's version number, packed in hexadecimal using 8bits for
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WEBP_EXTERN int WebPGetEncoderVersion(void);
//------------------------------------------------------------------------------
// One-stop-shop call! No questions asked:
// Returns the size of the compressed data (pointed to by *output), or 0 if
// an error occurred. The compressed data must be released by the caller
// using the call 'WebPFree(*output)'.
// These functions compress using the lossy format, and the quality_factor
// can go from 0 (smaller output, lower quality) to 100 (best quality,
// larger output).
WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb,
int width, int height, int stride,
float quality_factor, uint8_t** output);
WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr,
int width, int height, int stride,
float quality_factor, uint8_t** output);
WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba,
int width, int height, int stride,
float quality_factor, uint8_t** output);
WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra,
int width, int height, int stride,
float quality_factor, uint8_t** output);
// These functions are the equivalent of the above, but compressing in a
// lossless manner. Files are usually larger than lossy format, but will
// not suffer any compression loss.
// Note these functions, like the lossy versions, use the library's default
// settings. For lossless this means 'exact' is disabled. RGB values in
// transparent areas will be modified to improve compression. To avoid this,
// use WebPEncode() and set WebPConfig::exact to 1.
WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
int width, int height, int stride,
uint8_t** output);
WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr,
int width, int height, int stride,
uint8_t** output);
WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba,
int width, int height, int stride,
uint8_t** output);
WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra,
int width, int height, int stride,
uint8_t** output);
//------------------------------------------------------------------------------
// Coding parameters
// Image characteristics hint for the underlying encoder.
typedef enum WebPImageHint {
WEBP_HINT_DEFAULT = 0, // default preset.
WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot
WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting
WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc).
WEBP_HINT_LAST
} WebPImageHint;
// Compression parameters.
struct WebPConfig {
int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
float quality; // between 0 and 100. For lossy, 0 gives the smallest
// size and 100 the largest. For lossless, this
// parameter is the amount of effort put into the
// compression: 0 is the fastest but gives larger
// files compared to the slowest, but best, 100.
int method; // quality/speed trade-off (0=fast, 6=slower-better)
WebPImageHint image_hint; // Hint for image type (lossless only for now).
int target_size; // if non-zero, set the desired target size in bytes.
// Takes precedence over the 'compression' parameter.
float target_PSNR; // if non-zero, specifies the minimal distortion to
// try to achieve. Takes precedence over target_size.
int segments; // maximum number of segments to use, in [1..4]
int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
int filter_strength; // range: [0 = off .. 100 = strongest]
int filter_sharpness; // range: [0 = off .. 7 = least sharp]
int filter_type; // filtering type: 0 = simple, 1 = strong (only used
// if filter_strength > 0 or autofilter > 0)
int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
// 1 = compressed with WebP lossless). Default is 1.
int alpha_filtering; // Predictive filtering method for alpha plane.
// 0: none, 1: fast, 2: best. Default if 1.
int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
// Default is 100.
int pass; // number of entropy-analysis passes (in [1..10]).
int show_compressed; // if true, export the compressed picture back.
// In-loop filtering is not applied.
int preprocessing; // preprocessing filter:
// 0=none, 1=segment-smooth, 2=pseudo-random dithering
int partitions; // log2(number of token partitions) in [0..3]. Default
// is set to 0 for easier progressive decoding.
int partition_limit; // quality degradation allowed to fit the 512k limit
// on prediction modes coding (0: no degradation,
// 100: maximum possible degradation).
int emulate_jpeg_size; // If true, compression parameters will be remapped
// to better match the expected output size from
// JPEG compression. Generally, the output size will
// be similar but the degradation will be lower.
int thread_level; // If non-zero, try and use multi-threaded encoding.
int low_memory; // If set, reduce memory usage (but increase CPU use).
int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off
// (default)].
int exact; // if non-zero, preserve the exact RGB values under
// transparent area. Otherwise, discard this invisible
// RGB information for better compression. The default
// value is 0.
int use_delta_palette; // reserved for future lossless feature
int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
int qmin; // minimum permissible quality factor
int qmax; // maximum permissible quality factor
};
// Enumerate some predefined settings for WebPConfig, depending on the type
// of source picture. These presets are used when calling WebPConfigPreset().
typedef enum WebPPreset {
WEBP_PRESET_DEFAULT = 0, // default preset.
WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot
WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting
WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details
WEBP_PRESET_ICON, // small-sized colorful images
WEBP_PRESET_TEXT // text-like
} WebPPreset;
// Internal, version-checked, entry point
WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int);
// Should always be called, to initialize a fresh WebPConfig structure before
// modification. Returns false in case of version mismatch. WebPConfigInit()
// must have succeeded before using the 'config' object.
// Note that the default values are lossless=0 and quality=75.
static WEBP_INLINE int WebPConfigInit(WebPConfig* config) {
return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f,
WEBP_ENCODER_ABI_VERSION);
}
// This function will initialize the configuration according to a predefined
// set of parameters (referred to by 'preset') and a given quality factor.
// This function can be called as a replacement to WebPConfigInit(). Will
// return false in case of error.
static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
WebPPreset preset, float quality) {
return WebPConfigInitInternal(config, preset, quality,
WEBP_ENCODER_ABI_VERSION);
}
// Activate the lossless compression mode with the desired efficiency level
// between 0 (fastest, lowest compression) and 9 (slower, best compression).
// A good default level is '6', providing a fair tradeoff between compression
// speed and final compressed size.
// This function will overwrite several fields from config: 'method', 'quality'
// and 'lossless'. Returns false in case of parameter error.
WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level);
// Returns true if 'config' is non-NULL and all configuration parameters are
// within their valid ranges.
WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config);
//------------------------------------------------------------------------------
// Input / Output
// Structure for storing auxiliary statistics.
struct WebPAuxStats {
int coded_size; // final size
float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha
int block_count[3]; // number of intra4/intra16/skipped macroblocks
int header_bytes[2]; // approximate number of bytes spent for header
// and mode-partition #0
int residual_bytes[3][4]; // approximate number of bytes spent for
// DC/AC/uv coefficients for each (0..3) segments.
int segment_size[4]; // number of macroblocks in each segments
int segment_quant[4]; // quantizer values for each segments
int segment_level[4]; // filtering strength for each segments [0..63]
int alpha_data_size; // size of the transparency data
int layer_data_size; // size of the enhancement layer data
// lossless encoder statistics
uint32_t lossless_features; // bit0:predictor bit1:cross-color transform
// bit2:subtract-green bit3:color indexing
int histogram_bits; // number of precision bits of histogram
int transform_bits; // precision bits for transform
int cache_bits; // number of bits for color cache lookup
int palette_size; // number of color in palette, if used
int lossless_size; // final lossless size
int lossless_hdr_size; // lossless header (transform, huffman etc) size
int lossless_data_size; // lossless image data size
uint32_t pad[2]; // padding for later use
};
// Signature for output function. Should return true if writing was successful.
// data/data_size is the segment of data to write, and 'picture' is for
// reference (and so one can make use of picture->custom_ptr).
typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size,
const WebPPicture* picture);
// WebPMemoryWrite: a special WebPWriterFunction that writes to memory using
// the following WebPMemoryWriter object (to be set as a custom_ptr).
struct WebPMemoryWriter {
uint8_t* mem; // final buffer (of size 'max_size', larger than 'size').
size_t size; // final size
size_t max_size; // total capacity
uint32_t pad[1]; // padding for later use
};
// The following must be called first before any use.
WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer);
// The following must be called to deallocate writer->mem memory. The 'writer'
// object itself is not deallocated.
WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer);
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
// completion, writer.mem and writer.size will hold the coded data.
// writer.mem must be freed by calling WebPMemoryWriterClear.
WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size,
const WebPPicture* picture);
// Progress hook, called from time to time to report progress. It can return
// false to request an abort of the encoding process, or true otherwise if
// everything is OK.
typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture);
// Color spaces.
typedef enum WebPEncCSP {
// chroma sampling
WEBP_YUV420 = 0, // 4:2:0
WEBP_YUV420A = 4, // alpha channel variant
WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors
WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present
} WebPEncCSP;
// Encoding error conditions.
typedef enum WebPEncodingError {
VP8_ENC_OK = 0,
VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects
VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits
VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL
VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid
VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height
VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k
VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M
VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes
VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G
VP8_ENC_ERROR_USER_ABORT, // abort request by user
VP8_ENC_ERROR_LAST // list terminator. always last.
} WebPEncodingError;
// maximum width/height allowed (inclusive), in pixels
#define WEBP_MAX_DIMENSION 16383
// Main exchange structure (input samples, output bytes, statistics)
//
// Once WebPPictureInit() has been called, it's ok to make all the INPUT fields
// (use_argb, y/u/v, argb, ...) point to user-owned data, even if
// WebPPictureAlloc() has been called. Depending on the value use_argb,
// it's guaranteed that either *argb or *y/*u/*v content will be kept untouched.
struct WebPPicture {
// INPUT
//////////////
// Main flag for encoder selecting between ARGB or YUV input.
// It is recommended to use ARGB input (*argb, argb_stride) for lossless
// compression, and YUV input (*y, *u, *v, etc.) for lossy compression
// since these are the respective native colorspace for these formats.
int use_argb;
// YUV input (mostly used for input to lossy compression)
WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr).
int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
uint8_t* y, *u, *v; // pointers to luma/chroma planes.
int y_stride, uv_stride; // luma/chroma strides.
uint8_t* a; // pointer to the alpha plane
int a_stride; // stride of the alpha plane
uint32_t pad1[2]; // padding for later use
// ARGB input (mostly used for input to lossless compression)
uint32_t* argb; // Pointer to argb (32 bit) plane.
int argb_stride; // This is stride in pixels units, not bytes.
uint32_t pad2[3]; // padding for later use
// OUTPUT
///////////////
// Byte-emission hook, to store compressed bytes as they are ready.
WebPWriterFunction writer; // can be NULL
void* custom_ptr; // can be used by the writer.
// map for extra information (only for lossy compression mode)
int extra_info_type; // 1: intra type, 2: segment, 3: quant
// 4: intra-16 prediction mode,
// 5: chroma prediction mode,
// 6: bit cost, 7: distortion
uint8_t* extra_info; // if not NULL, points to an array of size
// ((width + 15) / 16) * ((height + 15) / 16) that
// will be filled with a macroblock map, depending
// on extra_info_type.
// STATS AND REPORTS
///////////////////////////
// Pointer to side statistics (updated only if not NULL)
WebPAuxStats* stats;
// Error code for the latest error encountered during encoding
WebPEncodingError error_code;
// If not NULL, report progress during encoding.
WebPProgressHook progress_hook;
void* user_data; // this field is free to be set to any value and
// used during callbacks (like progress-report e.g.).
uint32_t pad3[3]; // padding for later use
// Unused for now
uint8_t* pad4, *pad5;
uint32_t pad6[8]; // padding for later use
// PRIVATE FIELDS
////////////////////
void* memory_; // row chunk of memory for yuva planes
void* memory_argb_; // and for argb too.
void* pad7[2]; // padding for later use
};
// Internal, version-checked, entry point
WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int);
// Should always be called, to initialize the structure. Returns false in case
// of version mismatch. WebPPictureInit() must have succeeded before using the
// 'picture' object.
// Note that, by default, use_argb is false and colorspace is WEBP_YUV420.
static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) {
return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION);
}
//------------------------------------------------------------------------------
// WebPPicture utils
// Convenience allocation / deallocation based on picture->width/height:
// Allocate y/u/v buffers as per colorspace/width/height specification.
// Note! This function will free the previous buffer if needed.
// Returns false in case of memory error.
WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture);
// Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*().
// Note that this function does _not_ free the memory used by the 'picture'
// object itself.
// Besides memory (which is reclaimed) all other fields of 'picture' are
// preserved.
WEBP_EXTERN void WebPPictureFree(WebPPicture* picture);
// Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst
// will fully own the copied pixels (this is not a view). The 'dst' picture need
// not be initialized as its content is overwritten.
// Returns false in case of memory allocation error.
WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst);
// Compute the single distortion for packed planes of samples.
// 'src' will be compared to 'ref', and the raw distortion stored into
// '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be
// stored in '*result'.
// 'x_step' is the horizontal stride (in bytes) between samples.
// 'src/ref_stride' is the byte distance between rows.
// Returns false in case of error (bad parameter, memory allocation error, ...).
WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride,
const uint8_t* ref, size_t ref_stride,
int width, int height,
size_t x_step,
int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
float* distortion, float* result);
// Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results
// are in dB, stored in result[] in the B/G/R/A/All order. The distortion is
// always performed using ARGB samples. Hence if the input is YUV(A), the
// picture will be internally converted to ARGB (just for the measurement).
// Warning: this function is rather CPU-intensive.
WEBP_EXTERN int WebPPictureDistortion(
const WebPPicture* src, const WebPPicture* ref,
int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM
float result[5]);
// self-crops a picture to the rectangle defined by top/left/width/height.
// Returns false in case of memory allocation error, or if the rectangle is
// outside of the source picture.
// The rectangle for the view is defined by the top-left corner pixel
// coordinates (left, top) as well as its width and height. This rectangle
// must be fully be comprised inside the 'src' source picture. If the source
// picture uses the YUV420 colorspace, the top and left coordinates will be
// snapped to even values.
WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture,
int left, int top, int width, int height);
// Extracts a view from 'src' picture into 'dst'. The rectangle for the view
// is defined by the top-left corner pixel coordinates (left, top) as well
// as its width and height. This rectangle must be fully be comprised inside
// the 'src' source picture. If the source picture uses the YUV420 colorspace,
// the top and left coordinates will be snapped to even values.
// Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed
// ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so,
// the original dimension will be lost). Picture 'dst' need not be initialized
// with WebPPictureInit() if it is different from 'src', since its content will
// be overwritten.
// Returns false in case of memory allocation error or invalid parameters.
WEBP_EXTERN int WebPPictureView(const WebPPicture* src,
int left, int top, int width, int height,
WebPPicture* dst);
// Returns true if the 'picture' is actually a view and therefore does
// not own the memory for pixels.
WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture);
// Rescale a picture to new dimension width x height.
// If either 'width' or 'height' (but not both) is 0 the corresponding
// dimension will be calculated preserving the aspect ratio.
// No gamma correction is applied.
// Returns false in case of error (invalid parameter or insufficient memory).
WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height);
// Colorspace conversion function to import RGB samples.
// Previous buffer will be free'd, if any.
// *rgb buffer should have a size of at least height * rgb_stride.
// Returns false in case of memory error.
WEBP_EXTERN int WebPPictureImportRGB(
WebPPicture* picture, const uint8_t* rgb, int rgb_stride);
// Same, but for RGBA buffer.
WEBP_EXTERN int WebPPictureImportRGBA(
WebPPicture* picture, const uint8_t* rgba, int rgba_stride);
// Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format
// input buffer ignoring the alpha channel. Avoids needing to copy the data
// to a temporary 24-bit RGB buffer to import the RGB only.
WEBP_EXTERN int WebPPictureImportRGBX(
WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride);
// Variants of the above, but taking BGR(A|X) input.
WEBP_EXTERN int WebPPictureImportBGR(
WebPPicture* picture, const uint8_t* bgr, int bgr_stride);
WEBP_EXTERN int WebPPictureImportBGRA(
WebPPicture* picture, const uint8_t* bgra, int bgra_stride);
WEBP_EXTERN int WebPPictureImportBGRX(
WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride);
// Converts picture->argb data to the YUV420A format. The 'colorspace'
// parameter is deprecated and should be equal to WEBP_YUV420.
// Upon return, picture->use_argb is set to false. The presence of real
// non-opaque transparent values is detected, and 'colorspace' will be
// adjusted accordingly. Note that this method is lossy.
// Returns false in case of error.
WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture,
WebPEncCSP /*colorspace = WEBP_YUV420*/);
// Same as WebPPictureARGBToYUVA(), but the conversion is done using
// pseudo-random dithering with a strength 'dithering' between
// 0.0 (no dithering) and 1.0 (maximum dithering). This is useful
// for photographic picture.
WEBP_EXTERN int WebPPictureARGBToYUVADithered(
WebPPicture* picture, WebPEncCSP colorspace, float dithering);
// Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion.
// Downsampling is handled with extra care in case of color clipping. This
// method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better
// and sharper YUV representation.
// Returns false in case of error.
WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture);
// kept for backward compatibility:
WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture);
// Converts picture->yuv to picture->argb and sets picture->use_argb to true.
// The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to
// ARGB incurs a small loss too.
// Note that the use of this colorspace is discouraged if one has access to the
// raw ARGB samples, since using YUV420 is comparatively lossy.
// Returns false in case of error.
WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture);
// Helper function: given a width x height plane of RGBA or YUV(A) samples
// clean-up or smoothen the YUV or RGB samples under fully transparent area,
// to help compressibility (no guarantee, though).
WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture);
// Scan the picture 'picture' for the presence of non fully opaque alpha values.
// Returns true in such case. Otherwise returns false (indicating that the
// alpha plane can be ignored altogether e.g.).
WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture);
// Remove the transparency information (if present) by blending the color with
// the background color 'background_rgb' (specified as 24bit RGB triplet).
// After this call, all alpha values are reset to 0xff.
WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb);
//------------------------------------------------------------------------------
// Main call
// Main encoding call, after config and picture have been initialized.
// 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION),
// and the 'config' object must be a valid one.
// Returns false in case of error, true otherwise.
// In case of error, picture->error_code is updated accordingly.
// 'picture' can hold the source samples in both YUV(A) or ARGB input, depending
// on the value of 'picture->use_argb'. It is highly recommended to use
// the former for lossy encoding, and the latter for lossless encoding
// (when config.lossless is true). Automatic conversion from one format to
// another is provided but they both incur some loss.
WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture);
//------------------------------------------------------------------------------
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_ENCODE_H_

View File

@ -0,0 +1,530 @@
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// RIFF container manipulation and encoding for WebP images.
//
// Authors: Urvang (urvang@google.com)
// Vikas (vikasa@google.com)
#ifndef WEBP_WEBP_MUX_H_
#define WEBP_WEBP_MUX_H_
#include "./mux_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b)
//------------------------------------------------------------------------------
// Mux API
//
// This API allows manipulation of WebP container images containing features
// like color profile, metadata, animation.
//
// Code Example#1: Create a WebPMux object with image data, color profile and
// XMP metadata.
/*
int copy_data = 0;
WebPMux* mux = WebPMuxNew();
// ... (Prepare image data).
WebPMuxSetImage(mux, &image, copy_data);
// ... (Prepare ICCP color profile data).
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
// ... (Prepare XMP metadata).
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
// Get data from mux in WebP RIFF format.
WebPMuxAssemble(mux, &output_data);
WebPMuxDelete(mux);
// ... (Consume output_data; e.g. write output_data.bytes to file).
WebPDataClear(&output_data);
*/
// Code Example#2: Get image and color profile data from a WebP file.
/*
int copy_data = 0;
// ... (Read data from file).
WebPMux* mux = WebPMuxCreate(&data, copy_data);
WebPMuxGetFrame(mux, 1, &image);
// ... (Consume image; e.g. call WebPDecode() to decode the data).
WebPMuxGetChunk(mux, "ICCP", &icc_profile);
// ... (Consume icc_data).
WebPMuxDelete(mux);
WebPFree(data);
*/
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum WebPMuxError WebPMuxError;
// typedef enum WebPChunkId WebPChunkId;
typedef struct WebPMux WebPMux; // main opaque object.
typedef struct WebPMuxFrameInfo WebPMuxFrameInfo;
typedef struct WebPMuxAnimParams WebPMuxAnimParams;
typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions;
// Error codes
typedef enum WebPMuxError {
WEBP_MUX_OK = 1,
WEBP_MUX_NOT_FOUND = 0,
WEBP_MUX_INVALID_ARGUMENT = -1,
WEBP_MUX_BAD_DATA = -2,
WEBP_MUX_MEMORY_ERROR = -3,
WEBP_MUX_NOT_ENOUGH_DATA = -4
} WebPMuxError;
// IDs for different types of chunks.
typedef enum WebPChunkId {
WEBP_CHUNK_VP8X, // VP8X
WEBP_CHUNK_ICCP, // ICCP
WEBP_CHUNK_ANIM, // ANIM
WEBP_CHUNK_ANMF, // ANMF
WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM)
WEBP_CHUNK_ALPHA, // ALPH
WEBP_CHUNK_IMAGE, // VP8/VP8L
WEBP_CHUNK_EXIF, // EXIF
WEBP_CHUNK_XMP, // XMP
WEBP_CHUNK_UNKNOWN, // Other chunks.
WEBP_CHUNK_NIL
} WebPChunkId;
//------------------------------------------------------------------------------
// Returns the version number of the mux library, packed in hexadecimal using
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
WEBP_EXTERN int WebPGetMuxVersion(void);
//------------------------------------------------------------------------------
// Life of a Mux object
// Internal, version-checked, entry point
WEBP_EXTERN WebPMux* WebPNewInternal(int);
// Creates an empty mux object.
// Returns:
// A pointer to the newly created empty mux object.
// Or NULL in case of memory error.
static WEBP_INLINE WebPMux* WebPMuxNew(void) {
return WebPNewInternal(WEBP_MUX_ABI_VERSION);
}
// Deletes the mux object.
// Parameters:
// mux - (in/out) object to be deleted
WEBP_EXTERN void WebPMuxDelete(WebPMux* mux);
//------------------------------------------------------------------------------
// Mux creation.
// Internal, version-checked, entry point
WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int);
// Creates a mux object from raw data given in WebP RIFF format.
// Parameters:
// bitstream - (in) the bitstream data in WebP RIFF format
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
// object and value 0 indicates data will NOT be copied.
// Returns:
// A pointer to the mux object created from given data - on success.
// NULL - In case of invalid data or memory error.
static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream,
int copy_data) {
return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION);
}
//------------------------------------------------------------------------------
// Non-image chunks.
// Note: Only non-image related chunks should be managed through chunk APIs.
// (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH").
// To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(),
// WebPMuxGetFrame() and WebPMuxDeleteFrame().
// Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object.
// Any existing chunk(s) with the same id will be removed.
// Parameters:
// mux - (in/out) object to which the chunk is to be added
// fourcc - (in) a character array containing the fourcc of the given chunk;
// e.g., "ICCP", "XMP ", "EXIF" etc.
// chunk_data - (in) the chunk data to be added
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
// object and value 0 indicates data will NOT be copied.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
// or if fourcc corresponds to an image chunk.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxSetChunk(
WebPMux* mux, const char fourcc[4], const WebPData* chunk_data,
int copy_data);
// Gets a reference to the data of the chunk with id 'fourcc' in the mux object.
// The caller should NOT free the returned data.
// Parameters:
// mux - (in) object from which the chunk data is to be fetched
// fourcc - (in) a character array containing the fourcc of the chunk;
// e.g., "ICCP", "XMP ", "EXIF" etc.
// chunk_data - (out) returned chunk data
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL
// or if fourcc corresponds to an image chunk.
// WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxGetChunk(
const WebPMux* mux, const char fourcc[4], WebPData* chunk_data);
// Deletes the chunk with the given 'fourcc' from the mux object.
// Parameters:
// mux - (in/out) object from which the chunk is to be deleted
// fourcc - (in) a character array containing the fourcc of the chunk;
// e.g., "ICCP", "XMP ", "EXIF" etc.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL
// or if fourcc corresponds to an image chunk.
// WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxDeleteChunk(
WebPMux* mux, const char fourcc[4]);
//------------------------------------------------------------------------------
// Images.
// Encapsulates data about a single frame.
struct WebPMuxFrameInfo {
WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream
// or a single-image WebP file.
int x_offset; // x-offset of the frame.
int y_offset; // y-offset of the frame.
int duration; // duration of the frame (in milliseconds).
WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF
// or WEBP_CHUNK_IMAGE
WebPMuxAnimDispose dispose_method; // Disposal method for the frame.
WebPMuxAnimBlend blend_method; // Blend operation for the frame.
uint32_t pad[1]; // padding for later use
};
// Sets the (non-animated) image in the mux object.
// Note: Any existing images (including frames) will be removed.
// Parameters:
// mux - (in/out) object in which the image is to be set
// bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image
// WebP file (non-animated)
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
// object and value 0 indicates data will NOT be copied.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxSetImage(
WebPMux* mux, const WebPData* bitstream, int copy_data);
// Adds a frame at the end of the mux object.
// Notes: (1) frame.id should be WEBP_CHUNK_ANMF
// (2) For setting a non-animated image, use WebPMuxSetImage() instead.
// (3) Type of frame being pushed must be same as the frames in mux.
// (4) As WebP only supports even offsets, any odd offset will be snapped
// to an even location using: offset &= ~1
// Parameters:
// mux - (in/out) object to which the frame is to be added
// frame - (in) frame data.
// copy_data - (in) value 1 indicates given data WILL be copied to the mux
// object and value 0 indicates data will NOT be copied.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL
// or if content of 'frame' is invalid.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxPushFrame(
WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
// Gets the nth frame from the mux object.
// The content of 'frame->bitstream' is allocated using WebPMalloc(), and NOT
// owned by the 'mux' object. It MUST be deallocated by the caller by calling
// WebPDataClear().
// nth=0 has a special meaning - last position.
// Parameters:
// mux - (in) object from which the info is to be fetched
// nth - (in) index of the frame in the mux object
// frame - (out) data of the returned frame
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL.
// WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object.
// WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxGetFrame(
const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame);
// Deletes a frame from the mux object.
// nth=0 has a special meaning - last position.
// Parameters:
// mux - (in/out) object from which a frame is to be deleted
// nth - (in) The position from which the frame is to be deleted
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL.
// WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object
// before deletion.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth);
//------------------------------------------------------------------------------
// Animation.
// Animation parameters.
struct WebPMuxAnimParams {
uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as:
// Bits 00 to 07: Alpha.
// Bits 08 to 15: Red.
// Bits 16 to 23: Green.
// Bits 24 to 31: Blue.
int loop_count; // Number of times to repeat the animation [0 = infinite].
};
// Sets the animation parameters in the mux object. Any existing ANIM chunks
// will be removed.
// Parameters:
// mux - (in/out) object in which ANIM chunk is to be set/added
// params - (in) animation parameters.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxSetAnimationParams(
WebPMux* mux, const WebPMuxAnimParams* params);
// Gets the animation parameters from the mux object.
// Parameters:
// mux - (in) object from which the animation parameters to be fetched
// params - (out) animation parameters extracted from the ANIM chunk
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL.
// WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxGetAnimationParams(
const WebPMux* mux, WebPMuxAnimParams* params);
//------------------------------------------------------------------------------
// Misc Utilities.
// Sets the canvas size for the mux object. The width and height can be
// specified explicitly or left as zero (0, 0).
// * When width and height are specified explicitly, then this frame bound is
// enforced during subsequent calls to WebPMuxAssemble() and an error is
// reported if any animated frame does not completely fit within the canvas.
// * When unspecified (0, 0), the constructed canvas will get the frame bounds
// from the bounding-box over all frames after calling WebPMuxAssemble().
// Parameters:
// mux - (in) object to which the canvas size is to be set
// width - (in) canvas width
// height - (in) canvas height
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or
// width or height are invalid or out of bounds
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux,
int width, int height);
// Gets the canvas size from the mux object.
// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
// That is, the mux object hasn't been modified since the last call to
// WebPMuxAssemble() or WebPMuxCreate().
// Parameters:
// mux - (in) object from which the canvas size is to be fetched
// width - (out) canvas width
// height - (out) canvas height
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL.
// WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux,
int* width, int* height);
// Gets the feature flags from the mux object.
// Note: This method assumes that the VP8X chunk, if present, is up-to-date.
// That is, the mux object hasn't been modified since the last call to
// WebPMuxAssemble() or WebPMuxCreate().
// Parameters:
// mux - (in) object from which the features are to be fetched
// flags - (out) the flags specifying which features are present in the
// mux object. This will be an OR of various flag values.
// Enum 'WebPFeatureFlags' can be used to test individual flag values.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL.
// WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxGetFeatures(const WebPMux* mux,
uint32_t* flags);
// Gets number of chunks with the given 'id' in the mux object.
// Parameters:
// mux - (in) object from which the info is to be fetched
// id - (in) chunk id specifying the type of chunk
// num_elements - (out) number of chunks with the given chunk id
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxNumChunks(const WebPMux* mux,
WebPChunkId id, int* num_elements);
// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
// This function also validates the mux object.
// Note: The content of 'assembled_data' will be ignored and overwritten.
// Also, the content of 'assembled_data' is allocated using WebPMalloc(), and
// NOT owned by the 'mux' object. It MUST be deallocated by the caller by
// calling WebPDataClear(). It's always safe to call WebPDataClear() upon
// return, even in case of error.
// Parameters:
// mux - (in/out) object whose chunks are to be assembled
// assembled_data - (out) assembled WebP data
// Returns:
// WEBP_MUX_BAD_DATA - if mux object is invalid.
// WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN WebPMuxError WebPMuxAssemble(WebPMux* mux,
WebPData* assembled_data);
//------------------------------------------------------------------------------
// WebPAnimEncoder API
//
// This API allows encoding (possibly) animated WebP images.
//
// Code Example:
/*
WebPAnimEncoderOptions enc_options;
WebPAnimEncoderOptionsInit(&enc_options);
// Tune 'enc_options' as needed.
WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
while(<there are more frames>) {
WebPConfig config;
WebPConfigInit(&config);
// Tune 'config' as needed.
WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config);
}
WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL);
WebPAnimEncoderAssemble(enc, webp_data);
WebPAnimEncoderDelete(enc);
// Write the 'webp_data' to a file, or re-mux it further.
*/
typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object.
// Forward declarations. Defined in encode.h.
struct WebPPicture;
struct WebPConfig;
// Global options.
struct WebPAnimEncoderOptions {
WebPMuxAnimParams anim_params; // Animation parameters.
int minimize_size; // If true, minimize the output size (slow). Implicitly
// disables key-frame insertion.
int kmin;
int kmax; // Minimum and maximum distance between consecutive key
// frames in the output. The library may insert some key
// frames as needed to satisfy this criteria.
// Note that these conditions should hold: kmax > kmin
// and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then
// key-frame insertion is disabled; and if kmax == 1,
// then all frames will be key-frames (kmin value does
// not matter for these special cases).
int allow_mixed; // If true, use mixed compression mode; may choose
// either lossy and lossless for each frame.
int verbose; // If true, print info and warning messages to stderr.
uint32_t padding[4]; // Padding for later use.
};
// Internal, version-checked, entry point.
WEBP_EXTERN int WebPAnimEncoderOptionsInitInternal(
WebPAnimEncoderOptions*, int);
// Should always be called, to initialize a fresh WebPAnimEncoderOptions
// structure before modification. Returns false in case of version mismatch.
// WebPAnimEncoderOptionsInit() must have succeeded before using the
// 'enc_options' object.
static WEBP_INLINE int WebPAnimEncoderOptionsInit(
WebPAnimEncoderOptions* enc_options) {
return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION);
}
// Internal, version-checked, entry point.
WEBP_EXTERN WebPAnimEncoder* WebPAnimEncoderNewInternal(
int, int, const WebPAnimEncoderOptions*, int);
// Creates and initializes a WebPAnimEncoder object.
// Parameters:
// width/height - (in) canvas width and height of the animation.
// enc_options - (in) encoding options; can be passed NULL to pick
// reasonable defaults.
// Returns:
// A pointer to the newly created WebPAnimEncoder object.
// Or NULL in case of memory error.
static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew(
int width, int height, const WebPAnimEncoderOptions* enc_options) {
return WebPAnimEncoderNewInternal(width, height, enc_options,
WEBP_MUX_ABI_VERSION);
}
// Optimize the given frame for WebP, encode it and add it to the
// WebPAnimEncoder object.
// The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which
// indicates that no more frames are to be added. This call is also used to
// determine the duration of the last frame.
// Parameters:
// enc - (in/out) object to which the frame is to be added.
// frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A)
// format, it will be converted to ARGB, which incurs a small loss.
// timestamp_ms - (in) timestamp of this frame in milliseconds.
// Duration of a frame would be calculated as
// "timestamp of next frame - timestamp of this frame".
// Hence, timestamps should be in non-decreasing order.
// config - (in) encoding options; can be passed NULL to pick
// reasonable defaults.
// Returns:
// On error, returns false and frame->error_code is set appropriately.
// Otherwise, returns true.
WEBP_EXTERN int WebPAnimEncoderAdd(
WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms,
const struct WebPConfig* config);
// Assemble all frames added so far into a WebP bitstream.
// This call should be preceded by a call to 'WebPAnimEncoderAdd' with
// frame = NULL; if not, the duration of the last frame will be internally
// estimated.
// Parameters:
// enc - (in/out) object from which the frames are to be assembled.
// webp_data - (out) generated WebP bitstream.
// Returns:
// True on success.
WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc,
WebPData* webp_data);
// Get error string corresponding to the most recent call using 'enc'. The
// returned string is owned by 'enc' and is valid only until the next call to
// WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete().
// Parameters:
// enc - (in/out) object from which the error string is to be fetched.
// Returns:
// NULL if 'enc' is NULL. Otherwise, returns the error string if the last call
// to 'enc' had an error, or an empty string if the last call was a success.
WEBP_EXTERN const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc);
// Deletes the WebPAnimEncoder object.
// Parameters:
// enc - (in/out) object to be deleted
WEBP_EXTERN void WebPAnimEncoderDelete(WebPAnimEncoder* enc);
//------------------------------------------------------------------------------
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_MUX_H_

View File

@ -0,0 +1,98 @@
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Data-types common to the mux and demux libraries.
//
// Author: Urvang (urvang@google.com)
#ifndef WEBP_WEBP_MUX_TYPES_H_
#define WEBP_WEBP_MUX_TYPES_H_
#include <string.h> // memset()
#include "./types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
// typedef enum WebPFeatureFlags WebPFeatureFlags;
// typedef enum WebPMuxAnimDispose WebPMuxAnimDispose;
// typedef enum WebPMuxAnimBlend WebPMuxAnimBlend;
typedef struct WebPData WebPData;
// VP8X Feature Flags.
typedef enum WebPFeatureFlags {
ANIMATION_FLAG = 0x00000002,
XMP_FLAG = 0x00000004,
EXIF_FLAG = 0x00000008,
ALPHA_FLAG = 0x00000010,
ICCP_FLAG = 0x00000020,
ALL_VALID_FLAGS = 0x0000003e
} WebPFeatureFlags;
// Dispose method (animation only). Indicates how the area used by the current
// frame is to be treated before rendering the next frame on the canvas.
typedef enum WebPMuxAnimDispose {
WEBP_MUX_DISPOSE_NONE, // Do not dispose.
WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color.
} WebPMuxAnimDispose;
// Blend operation (animation only). Indicates how transparent pixels of the
// current frame are blended with those of the previous canvas.
typedef enum WebPMuxAnimBlend {
WEBP_MUX_BLEND, // Blend.
WEBP_MUX_NO_BLEND // Do not blend.
} WebPMuxAnimBlend;
// Data type used to describe 'raw' data, e.g., chunk data
// (ICC profile, metadata) and WebP compressed image data.
// 'bytes' memory must be allocated using WebPMalloc() and such.
struct WebPData {
const uint8_t* bytes;
size_t size;
};
// Initializes the contents of the 'webp_data' object with default values.
static WEBP_INLINE void WebPDataInit(WebPData* webp_data) {
if (webp_data != NULL) {
memset(webp_data, 0, sizeof(*webp_data));
}
}
// Clears the contents of the 'webp_data' object by calling WebPFree().
// Does not deallocate the object itself.
static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
if (webp_data != NULL) {
WebPFree((void*)webp_data->bytes);
WebPDataInit(webp_data);
}
}
// Allocates necessary storage for 'dst' and copies the contents of 'src'.
// Returns true on success.
static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
if (src == NULL || dst == NULL) return 0;
WebPDataInit(dst);
if (src->bytes != NULL && src->size != 0) {
dst->bytes = (uint8_t*)WebPMalloc(src->size);
if (dst->bytes == NULL) return 0;
memcpy((void*)dst->bytes, src->bytes, src->size);
dst->size = src->size;
}
return 1;
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_MUX_TYPES_H_

View File

@ -0,0 +1,68 @@
// Copyright 2010 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Common types + memory wrappers
//
// Author: Skal (pascal.massimino@gmail.com)
#ifndef WEBP_WEBP_TYPES_H_
#define WEBP_WEBP_TYPES_H_
#include <stddef.h> // for size_t
#ifndef _MSC_VER
#include <inttypes.h>
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
#define WEBP_INLINE inline
#else
#define WEBP_INLINE
#endif
#else
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
typedef long long int int64_t;
#define WEBP_INLINE __forceinline
#endif /* _MSC_VER */
#ifndef WEBP_EXTERN
// This explicitly marks library functions and allows for changing the
// signature for e.g., Windows DLL builds.
# if defined(__GNUC__) && __GNUC__ >= 4
# define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
# else
# define WEBP_EXTERN extern
# endif /* __GNUC__ >= 4 */
#endif /* WEBP_EXTERN */
// Macro to check ABI compatibility (same major revision number)
#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
#ifdef __cplusplus
extern "C" {
#endif
// Allocates 'size' bytes of memory. Returns NULL upon error. Memory
// must be deallocated by calling WebPFree(). This function is made available
// by the core 'libwebp' library.
WEBP_EXTERN void* WebPMalloc(size_t size);
// Releases memory returned by the WebPDecode*() functions (from decode.h).
WEBP_EXTERN void WebPFree(void* ptr);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_WEBP_TYPES_H_

View File

@ -0,0 +1,684 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** @file */
#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C
#ifdef __cplusplus
#include <cstddef>
#include <cstdarg>
extern "C" {
#else
#include <stdarg.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "lws_config.h"
#if defined(LWS_SUPPRESS_DEPRECATED_API_WARNINGS)
#define OPENSSL_USE_DEPRECATED
#endif
/* place for one-shot opaque forward references */
typedef struct lws_context * lws_ctx_t;
struct lws_sequencer;
struct lws_dsh;
/*
* CARE: everything using cmake defines needs to be below here
*/
#define LWS_US_PER_SEC ((lws_usec_t)1000000)
#define LWS_MS_PER_SEC ((lws_usec_t)1000)
#define LWS_US_PER_MS ((lws_usec_t)1000)
#define LWS_NS_PER_US ((lws_usec_t)1000)
#define LWS_KI (1024)
#define LWS_MI (LWS_KI * 1024)
#define LWS_GI (LWS_MI * 1024)
#define LWS_TI ((uint64_t)LWS_GI * 1024)
#define LWS_PI ((uint64_t)LWS_TI * 1024)
#define LWS_US_TO_MS(x) ((x + (LWS_US_PER_MS / 2)) / LWS_US_PER_MS)
#if defined(LWS_HAS_INTPTR_T)
#include <stdint.h>
#define lws_intptr_t intptr_t
#else
typedef unsigned long long lws_intptr_t;
#endif
#if defined(WIN32) || defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stddef.h>
#include <basetsd.h>
#include <io.h>
#ifndef _WIN32_WCE
#include <fcntl.h>
#else
#define _O_RDONLY 0x0000
#define O_RDONLY _O_RDONLY
#endif
typedef int uid_t;
typedef int gid_t;
typedef unsigned short sa_family_t;
#if !defined(LWS_HAVE_SUSECONDS_T)
typedef unsigned int useconds_t;
typedef int suseconds_t;
#endif
#define LWS_INLINE __inline
#define LWS_VISIBLE
#define LWS_WARN_UNUSED_RESULT
#define LWS_WARN_DEPRECATED
#define LWS_FORMAT(string_index)
#if !defined(LWS_EXTERN) && defined(LWS_BUILDING_SHARED)
#ifdef LWS_DLL
#ifdef LWS_INTERNAL
#define LWS_EXTERN extern __declspec(dllexport)
#else
#define LWS_EXTERN extern __declspec(dllimport)
#endif
#endif
#endif
#if !defined(LWS_INTERNAL) && !defined(LWS_EXTERN)
#define LWS_EXTERN
#define LWS_VISIBLE
#endif
#if !defined(LWS_EXTERN)
#define LWS_EXTERN
#endif
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
#define LWS_SOCK_INVALID (INVALID_SOCKET)
#define LWS_O_RDONLY _O_RDONLY
#define LWS_O_WRONLY _O_WRONLY
#define LWS_O_CREAT _O_CREAT
#define LWS_O_TRUNC _O_TRUNC
#ifndef __func__
#define __func__ __FUNCTION__
#endif
#else /* NOT WIN32 */
#include <unistd.h>
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
#include <sys/capability.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defined(__OpenBSD__)
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#define LWS_INLINE inline
#define LWS_O_RDONLY O_RDONLY
#define LWS_O_WRONLY O_WRONLY
#define LWS_O_CREAT O_CREAT
#define LWS_O_TRUNC O_TRUNC
#if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_TA) && !defined(LWS_PLAT_FREERTOS)
#include <poll.h>
#include <netdb.h>
#define LWS_INVALID_FILE -1
#define LWS_SOCK_INVALID (-1)
#else
#define getdtablesize() (30)
#if defined(LWS_PLAT_FREERTOS)
#define LWS_INVALID_FILE NULL
#define LWS_SOCK_INVALID (-1)
#else
#define LWS_INVALID_FILE NULL
#define LWS_SOCK_INVALID (-1)
#endif
#endif
#if defined(__FreeBSD__)
#include <sys/signal.h>
#endif
#if defined(__GNUC__)
/* warn_unused_result attribute only supported by GCC 3.4 or later */
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define LWS_WARN_UNUSED_RESULT
#endif
#if defined(LWS_BUILDING_SHARED)
/* this is only set when we're building lws itself shared */
#define LWS_VISIBLE __attribute__((visibility("default")))
#define LWS_EXTERN extern
#else /* not shared */
#if defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
#define LWS_VISIBLE
#define LWS_EXTERN extern
#else
/*
* If we explicitly say hidden here, symbols exist as T but
* cannot be imported at link-time.
*/
#define LWS_VISIBLE
#define LWS_EXTERN
#endif
#endif /* not shared */
#define LWS_WARN_DEPRECATED __attribute__ ((deprecated))
#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1)))
#else /* not GNUC */
#define LWS_VISIBLE
#define LWS_WARN_UNUSED_RESULT
#define LWS_WARN_DEPRECATED
#define LWS_FORMAT(string_index)
#if !defined(LWS_EXTERN)
#define LWS_EXTERN extern
#endif
#endif
#if defined(__ANDROID__)
#include <netinet/in.h>
#include <unistd.h>
#endif
#endif
#ifdef _WIN32
#define random rand
#else
#if !defined(LWS_PLAT_OPTEE)
#include <sys/time.h>
#include <unistd.h>
#endif
#endif
#if defined(LWS_WITH_LIBUV_INTERNAL)
#include <uv.h>
#ifdef LWS_HAVE_UV_VERSION_H
#include <uv-version.h>
#endif
#ifdef LWS_HAVE_NEW_UV_VERSION_H
#include <uv/version.h>
#endif
#endif
#if defined(LWS_WITH_TLS)
#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
#ifdef _WIN32
/*
* Include user-controlled settings for windows from
* <wolfssl-root>/IDE/WIN/user_settings.h
*/
#include <IDE/WIN/user_settings.h>
#include <cyassl/ctaocrypt/settings.h>
#else
#include <cyassl/options.h>
#endif
#include <cyassl/openssl/ssl.h>
#include <cyassl/error-ssl.h>
#else
#ifdef _WIN32
/*
* Include user-controlled settings for windows from
* <wolfssl-root>/IDE/WIN/user_settings.h
*/
#include <IDE/WIN/user_settings.h>
#include <wolfssl/wolfcrypt/settings.h>
#else
#include <wolfssl/options.h>
#endif
#include <wolfssl/openssl/ssl.h>
#include <wolfssl/error-ssl.h>
#endif /* not USE_OLD_CYASSL */
#else
#if defined(LWS_WITH_MBEDTLS)
#if defined(LWS_PLAT_FREERTOS)
/* this filepath is passed to us but without quotes or <> */
#if !defined(LWS_AMAZON_RTOS)
/* AMAZON RTOS has its own setting via MTK_MBEDTLS_CONFIG_FILE */
#undef MBEDTLS_CONFIG_FILE
#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h>
#endif
#endif
#if defined(LWS_WITH_TLS)
#include <mbedtls/ssl.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#if !defined(MBEDTLS_PRIVATE)
#define MBEDTLS_PRIVATE(_q) _q
#endif
#endif
#else
#include <openssl/ssl.h>
#if !defined(LWS_WITH_MBEDTLS)
#include <openssl/err.h>
#endif
#endif
#endif /* not USE_WOLFSSL */
#endif
/*
* Helpers for pthread mutex in user code... if lws is built for
* multiple service threads, these resolve to pthread mutex
* operations. In the case LWS_MAX_SMP is 1 (the default), they
* are all NOPs and no pthread type or api is referenced.
*/
#if LWS_MAX_SMP > 1
#include <pthread.h>
#define lws_pthread_mutex(name) pthread_mutex_t name;
static LWS_INLINE void
lws_pthread_mutex_init(pthread_mutex_t *lock)
{
pthread_mutex_init(lock, NULL);
}
static LWS_INLINE void
lws_pthread_mutex_destroy(pthread_mutex_t *lock)
{
pthread_mutex_destroy(lock);
}
static LWS_INLINE void
lws_pthread_mutex_lock(pthread_mutex_t *lock)
{
pthread_mutex_lock(lock);
}
static LWS_INLINE void
lws_pthread_mutex_unlock(pthread_mutex_t *lock)
{
pthread_mutex_unlock(lock);
}
#else
#define lws_pthread_mutex(name)
#define lws_pthread_mutex_init(_a)
#define lws_pthread_mutex_destroy(_a)
#define lws_pthread_mutex_lock(_a)
#define lws_pthread_mutex_unlock(_a)
#endif
#define CONTEXT_PORT_NO_LISTEN -1
#define CONTEXT_PORT_NO_LISTEN_SERVER -2
#include <libwebsockets/lws-logs.h>
#include <stddef.h>
#ifndef lws_container_of
#define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))
#endif
#define LWS_ALIGN_TO(x, bou) x += ((bou) - ((x) % (bou))) % (bou)
struct lws;
/* api change list for user code to test against */
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG
/* the struct lws_protocols has the id field present */
#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD
/* you can call lws_get_peer_write_allowance */
#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE
/* extra parameter introduced in 917f43ab821 */
#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN
/* File operations stuff exists */
#define LWS_FEATURE_FOPS
#if defined(_WIN32)
#if !defined(LWS_WIN32_HANDLE_TYPES)
typedef SOCKET lws_sockfd_type;
typedef HANDLE lws_filefd_type;
#endif
#define lws_pollfd pollfd
#define LWS_POLLHUP (POLLHUP)
#define LWS_POLLIN (POLLRDNORM | POLLRDBAND)
#define LWS_POLLOUT (POLLWRNORM)
#else
#if defined(LWS_PLAT_FREERTOS)
#include <libwebsockets/lws-freertos.h>
#else
typedef int lws_sockfd_type;
typedef int lws_filefd_type;
#endif
#if defined(LWS_PLAT_OPTEE)
#include <time.h>
struct timeval {
time_t tv_sec;
unsigned int tv_usec;
};
#if defined(LWS_WITH_NETWORK)
// #include <poll.h>
#define lws_pollfd pollfd
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *tz);
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
typedef unsigned short sa_family_t;
typedef unsigned short in_port_t;
typedef uint32_t socklen_t;
#include <libwebsockets/lws-optee.h>
#if !defined(TEE_SE_READER_NAME_MAX)
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
#endif
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t read(int fd, void *buf, size_t count);
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
extern int errno;
uint16_t ntohs(uint16_t netshort);
uint16_t htons(uint16_t hostshort);
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
#define MSG_NOSIGNAL 0x4000
#define EAGAIN 11
#define EINTR 4
#define EWOULDBLOCK EAGAIN
#define EADDRINUSE 98
#define INADDR_ANY 0
#define AF_INET 2
#define SHUT_WR 1
#define AF_UNSPEC 0
#define PF_UNSPEC 0
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
# define AI_PASSIVE 0x0001
#define IPPROTO_UDP 17
#define SOL_SOCKET 1
#define SO_SNDBUF 7
#define EISCONN 106
#define EALREADY 114
#define EINPROGRESS 115
int shutdown(int sockfd, int how);
int close(int fd);
int atoi(const char *nptr);
long long atoll(const char *nptr);
int socket(int domain, int type, int protocol);
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
#if !defined(TEE_SE_READER_NAME_MAX)
struct lws_pollfd
{
int fd; /* File descriptor to poll. */
short int events; /* Types of events poller cares about. */
short int revents; /* Types of events that actually occurred. */
};
#endif
int poll(struct pollfd *fds, int nfds, int timeout);
#define LWS_POLLHUP (0x18)
#define LWS_POLLIN (1)
#define LWS_POLLOUT (4)
#else
struct lws_pollfd;
struct sockaddr_in;
#endif
#else
#define lws_pollfd pollfd
#define LWS_POLLHUP (POLLHUP | POLLERR)
#define LWS_POLLIN (POLLIN)
#define LWS_POLLOUT (POLLOUT)
#endif
#endif
#if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__)
/* ... */
#define ssize_t SSIZE_T
#endif
#if defined(WIN32) && defined(LWS_HAVE__STAT32I64)
#include <sys/types.h>
#include <sys/stat.h>
#endif
#if defined(LWS_HAVE_STDINT_H)
#include <stdint.h>
#else
#if defined(WIN32) || defined(_WIN32)
/* !!! >:-[ */
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
#else
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
#endif
#endif
typedef int64_t lws_usec_t;
typedef unsigned long long lws_filepos_t;
typedef long long lws_fileofs_t;
typedef uint32_t lws_fop_flags_t;
#define lws_concat_temp(_t, _l) (_t + sizeof(_t) - _l)
#define lws_concat_used(_t, _l) (sizeof(_t) - _l)
/** struct lws_pollargs - argument structure for all external poll related calls
* passed in via 'in' */
struct lws_pollargs {
lws_sockfd_type fd; /**< applicable socket descriptor */
int events; /**< the new event mask */
int prev_events; /**< the previous event mask */
};
struct lws_extension; /* needed even with ws exts disabled for create context */
struct lws_token_limits;
struct lws_protocols;
struct lws_context;
struct lws_tokens;
struct lws_vhost;
struct lws;
#include <libwebsockets/lws-dll2.h>
#include <libwebsockets/lws-map.h>
#include <libwebsockets/lws-fault-injection.h>
#include <libwebsockets/lws-timeout-timer.h>
#include <libwebsockets/lws-cache-ttl.h>
#if defined(LWS_WITH_SYS_SMD)
#include <libwebsockets/lws-smd.h>
#endif
#include <libwebsockets/lws-state.h>
#include <libwebsockets/lws-retry.h>
#include <libwebsockets/lws-adopt.h>
#include <libwebsockets/lws-network-helper.h>
#include <libwebsockets/lws-metrics.h>
#include <libwebsockets/lws-system.h>
#include <libwebsockets/lws-ws-close.h>
#include <libwebsockets/lws-callbacks.h>
#include <libwebsockets/lws-ws-state.h>
#include <libwebsockets/lws-ws-ext.h>
#include <libwebsockets/lws-protocols-plugins.h>
#include <libwebsockets/lws-context-vhost.h>
#if defined(LWS_WITH_CONMON)
#include <libwebsockets/lws-conmon.h>
#endif
#if defined(LWS_ROLE_MQTT)
#include <libwebsockets/lws-mqtt.h>
#endif
#include <libwebsockets/lws-client.h>
#include <libwebsockets/lws-http.h>
#include <libwebsockets/lws-spa.h>
#include <libwebsockets/lws-purify.h>
#include <libwebsockets/lws-misc.h>
#include <libwebsockets/lws-dsh.h>
#include <libwebsockets/lws-service.h>
#include <libwebsockets/lws-write.h>
#include <libwebsockets/lws-writeable.h>
#include <libwebsockets/lws-ring.h>
#include <libwebsockets/lws-sha1-base64.h>
#include <libwebsockets/lws-x509.h>
#include <libwebsockets/lws-cgi.h>
#if defined(LWS_WITH_FILE_OPS)
#include <libwebsockets/lws-vfs.h>
#endif
#include <libwebsockets/lws-gencrypto.h>
#include <libwebsockets/lws-lejp.h>
#include <libwebsockets/lws-lecp.h>
#include <libwebsockets/lws-cose.h>
#include <libwebsockets/lws-struct.h>
#include <libwebsockets/lws-threadpool.h>
#include <libwebsockets/lws-tokenize.h>
#include <libwebsockets/lws-lwsac.h>
#include <libwebsockets/lws-fts.h>
#include <libwebsockets/lws-diskcache.h>
#include <libwebsockets/lws-sequencer.h>
#include <libwebsockets/lws-secure-streams.h>
#include <libwebsockets/lws-secure-streams-policy.h>
#include <libwebsockets/lws-secure-streams-client.h>
#if !defined(LWS_PLAT_FREERTOS)
#include <libwebsockets/abstract/abstract.h>
#include <libwebsockets/lws-test-sequencer.h>
#endif
#include <libwebsockets/lws-async-dns.h>
#if defined(LWS_WITH_TLS)
#include <libwebsockets/lws-tls-sessions.h>
#if defined(LWS_WITH_MBEDTLS)
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#endif
#include <libwebsockets/lws-genhash.h>
#include <libwebsockets/lws-genrsa.h>
#include <libwebsockets/lws-genaes.h>
#include <libwebsockets/lws-genec.h>
#include <libwebsockets/lws-jwk.h>
#include <libwebsockets/lws-jose.h>
#include <libwebsockets/lws-jws.h>
#include <libwebsockets/lws-jwe.h>
#endif
#include <libwebsockets/lws-eventlib-exports.h>
#include <libwebsockets/lws-i2c.h>
#include <libwebsockets/lws-spi.h>
#include <libwebsockets/lws-gpio.h>
#include <libwebsockets/lws-bb-i2c.h>
#include <libwebsockets/lws-bb-spi.h>
#include <libwebsockets/lws-button.h>
#include <libwebsockets/lws-led.h>
#include <libwebsockets/lws-pwm.h>
#include <libwebsockets/lws-display.h>
#include <libwebsockets/lws-ssd1306-i2c.h>
#include <libwebsockets/lws-ili9341-spi.h>
#include <libwebsockets/lws-settings.h>
#include <libwebsockets/lws-netdev.h>
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,138 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* These are used to optionally pass an array of index = C string, binary array,
* or ulong tokens to the abstract transport or protocol. For example if it's
* raw socket transport, then the DNS address to connect to and the port are
* passed using these when the client created and bound to the transport.
*/
typedef struct lws_token_map {
union {
const char *value;
uint8_t *bvalue;
unsigned long lvalue;
} u;
short name_index; /* 0 here indicates end of array */
short length_or_zero;
} lws_token_map_t;
/*
* The indvidual protocols and transports define their own name_index-es which
* are meaningful to them. Define index 0 globally as the end of an array of
* them, and provide bases so user protocol and transport ones don't overlap.
*/
enum {
LTMI_END_OF_ARRAY,
LTMI_PROTOCOL_BASE = 2048,
LTMI_TRANSPORT_BASE = 4096
};
struct lws_abs_transport;
struct lws_abs_protocol;
typedef struct lws_abs lws_abs_t;
LWS_VISIBLE LWS_EXTERN const lws_token_map_t *
lws_abs_get_token(const lws_token_map_t *token_map, short name_index);
/*
* the combination of a protocol, transport, and token maps for each
*/
typedef void lws_abs_transport_inst_t;
typedef void lws_abs_protocol_inst_t;
/**
* lws_abstract_alloc() - allocate and configure an lws_abs_t
*
* \param vhost: the struct lws_vhost to bind to
* \param user: opaque user pointer
* \param abstract_path: "protocol.transport" names
* \param ap_tokens: tokens for protocol options
* \param at_tokens: tokens for transport
* \param seq: optional sequencer we should bind to, or NULL
* \param opaque_user_data: data given in sequencer callback, if any
*
* Returns an allocated lws_abs_t pointer set up with the other arguments.
*
* Doesn't create a connection instance, just allocates the lws_abs_t and
* sets it up with the arguments.
*
* Returns NULL is there's any problem.
*/
LWS_VISIBLE LWS_EXTERN lws_abs_t *
lws_abstract_alloc(struct lws_vhost *vhost, void *user,
const char *abstract_path, const lws_token_map_t *ap_tokens,
const lws_token_map_t *at_tokens, struct lws_sequencer *seq,
void *opaque_user_data);
/**
* lws_abstract_free() - free an allocated lws_abs_t
*
* \param pabs: pointer to the lws_abs_t * to free
*
* Frees and sets the pointer to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_abstract_free(lws_abs_t **pabs);
/**
* lws_abs_bind_and_create_instance - use an abstract protocol and transport
*
* \param abs: the lws_abs_t describing the combination desired
*
* This instantiates an abstract protocol and abstract transport bound together.
* A single heap allocation is made for the combination and the protocol and
* transport creation ops are called on it. The ap_tokens and at_tokens
* are consulted by the creation ops to decide the details of the protocol and
* transport for the instance.
*/
LWS_VISIBLE LWS_EXTERN lws_abs_t *
lws_abs_bind_and_create_instance(const lws_abs_t *ai);
/**
* lws_abs_destroy_instance() - destroys an instance
*
* \param ai: pointer to the ai pointer to destroy
*
* This is for destroying an instance created by
* lws_abs_bind_and_create_instance() above.
*
* Calls the protocol and transport destroy operations on the instance, then
* frees the combined allocation in one step. The pointer ai is set to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_abs_destroy_instance(lws_abs_t **ai);
/*
* bring in all the protocols and transports definitions
*/
#include <libwebsockets/abstract/protocols.h>
#include <libwebsockets/abstract/transports.h>

View File

@ -0,0 +1,88 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* Information about how this protocol handles multiple use of connections.
*
* .flags of 0 indicates each connection must start with a fresh transport.
*
* Flags can be used to indicate the protocol itself supports different
* kinds of multiple use. However the actual use or not of these may depend on
* negotiation with the remote peer.
*
* LWS_AP_FLAG_PIPELINE_TRANSACTIONS: other instances can be queued on one
* with an existing connection and get a
* chance to "hot take over" the existing
* transport in turn, like h1 keepalive
* pipelining
*
* LWS_AP_FLAG_MUXABLE_STREAM: an existing connection can absorb more child
* connections and mux them as separate child
* streams ongoing, like h2
*/
enum {
LWS_AP_FLAG_PIPELINE_TRANSACTIONS = (1 << 0),
LWS_AP_FLAG_MUXABLE_STREAM = (1 << 1),
};
typedef struct lws_abs_protocol {
const char *name;
int alloc;
int flags;
int (*create)(const struct lws_abs *ai);
void (*destroy)(lws_abs_protocol_inst_t **d);
int (*compare)(lws_abs_t *abs1, lws_abs_t *abs2);
/* events the transport invokes (handled by abstract protocol) */
int (*accept)(lws_abs_protocol_inst_t *d);
int (*rx)(lws_abs_protocol_inst_t *d, const uint8_t *b, size_t l);
int (*writeable)(lws_abs_protocol_inst_t *d, size_t budget);
int (*closed)(lws_abs_protocol_inst_t *d);
int (*heartbeat)(lws_abs_protocol_inst_t *d);
/* as parent, we get a notification a new child / queue entry
* bound to us... this is the parent lws_abs_t as arg */
int (*child_bind)(lws_abs_t *abs);
} lws_abs_protocol_t;
/**
* lws_abs_protocol_get_by_name() - returns a pointer to the named protocol ops
*
* \param name: the name of the abstract protocol
*
* Returns a pointer to the named protocol ops struct if available, otherwise
* NULL.
*/
LWS_VISIBLE LWS_EXTERN const lws_abs_protocol_t *
lws_abs_protocol_get_by_name(const char *name);
/*
* bring in public api pieces from protocols
*/
#include <libwebsockets/abstract/protocols/smtp.h>

View File

@ -0,0 +1,115 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup smtp SMTP related functions
* ##SMTP related functions
* \ingroup lwsapi
*
* These apis let you communicate with a local SMTP server to send email from
* lws. It handles all the SMTP sequencing and protocol actions.
*
* Your system should have postfix, sendmail or another MTA listening on port
* 25 and able to send email using the "mail" commandline app. Usually distro
* MTAs are configured for this by default.
*
* You can either use the abstract protocol layer directly, or instead use the
* provided smtp sequencer... this takes care of creating the protocol
* connections, and provides and email queue and retry management.
*/
//@{
#if defined(LWS_WITH_SMTP)
enum {
LTMI_PSMTP_V_HELO = LTMI_PROTOCOL_BASE, /* u.value */
LTMI_PSMTP_V_LWS_SMTP_EMAIL_T, /* u.value */
};
enum {
LWS_SMTP_DISPOSITION_SENT,
LWS_SMTP_DISPOSITION_FAILED,
LWS_SMTP_DISPOSITION_FAILED_DESTROY
};
typedef struct lws_smtp_sequencer_args {
const char helo[32];
struct lws_vhost *vhost;
time_t retry_interval;
time_t delivery_timeout;
size_t email_queue_max;
size_t max_content_size;
} lws_smtp_sequencer_args_t;
typedef struct lws_smtp_sequencer lws_smtp_sequencer_t;
typedef struct lws_smtp_email lws_smtp_email_t;
LWS_VISIBLE LWS_EXTERN lws_smtp_sequencer_t *
lws_smtp_sequencer_create(const lws_smtp_sequencer_args_t *args);
LWS_VISIBLE LWS_EXTERN void
lws_smtp_sequencer_destroy(lws_smtp_sequencer_t *s);
typedef int (*lws_smtp_cb_t)(void *e, void *d, int disp, const void *b, size_t l);
typedef struct lws_smtp_email lws_smtp_email_t;
/**
* lws_smtpc_add_email() - Allocates and queues an email object
*
* \param s: smtp sequencer to queue on
* \param payload: the email payload string, with headers and terminating .
* \param payload_len: size in bytes of the payload string
* \param sender: the sender name and email
* \param recipient: the recipient name and email
* \param data: opaque user data returned in the done callback
* \param done: callback called when the email send succeeded or failed
*
* Allocates an email object and copies the payload, sender and recipient into
* it and initializes it. Returns NULL if OOM, otherwise the allocated email
* object.
*
* Because it copies the arguments into an allocated buffer, the original
* arguments can be safely destroyed after calling this.
*
* The done() callback must free the email object. It doesn't have to free any
* individual members.
*/
LWS_VISIBLE LWS_EXTERN int
lws_smtpc_add_email(lws_smtp_sequencer_t *s, const char *payload,
size_t payload_len, const char *sender,
const char *recipient, void *data, lws_smtp_cb_t done);
/**
* lws_smtpc_free_email() - Add email to the list of ones being sent
*
* \param e: email to queue for sending on \p c
*
* Adds an email to the linked-list of emails to send
*/
LWS_VISIBLE LWS_EXTERN int
lws_smtpc_free_email(lws_smtp_email_t *e);
#endif
//@}

View File

@ -0,0 +1,65 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* Abstract transport ops
*/
typedef struct lws_abs_transport {
const char *name;
int alloc;
int (*create)(lws_abs_t *abs);
void (*destroy)(lws_abs_transport_inst_t **d);
/* check if the transport settings for these connections are the same */
int (*compare)(lws_abs_t *abs1, lws_abs_t *abs2);
/* events the abstract protocol invokes (handled by transport) */
int (*tx)(lws_abs_transport_inst_t *d, uint8_t *buf, size_t len);
int (*client_conn)(const lws_abs_t *abs);
int (*close)(lws_abs_transport_inst_t *d);
int (*ask_for_writeable)(lws_abs_transport_inst_t *d);
int (*set_timeout)(lws_abs_transport_inst_t *d, int reason, int secs);
int (*state)(lws_abs_transport_inst_t *d);
} lws_abs_transport_t;
/**
* lws_abs_protocol_get_by_name() - returns a pointer to the named protocol ops
*
* \param name: the name of the abstract protocol
*
* Returns a pointer to the named protocol ops struct if available, otherwise
* NULL.
*/
LWS_VISIBLE LWS_EXTERN const lws_abs_transport_t *
lws_abs_transport_get_by_name(const char *name);
/*
* bring in public api pieces from transports
*/
#include <libwebsockets/abstract/transports/raw-skt.h>
#include <libwebsockets/abstract/transports/unit-test.h>

View File

@ -0,0 +1,29 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
enum {
LTMI_PEER_V_DNS_ADDRESS = LTMI_TRANSPORT_BASE, /* u.value */
LTMI_PEER_LV_PORT, /* u.lvalue */
LTMI_PEER_LV_TLS_FLAGS, /* u.lvalue */
};

View File

@ -0,0 +1,81 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is an abstract transport useful for unit testing abstract protocols.
*
* Instead of passing data anywhere, you give the transport a list of packets
* to deliver and packets you expect back from the abstract protocol it's
* bound to.
*/
enum {
LWS_AUT_EXPECT_TEST_END = (1 << 0),
LWS_AUT_EXPECT_LOCAL_CLOSE = (1 << 1),
LWS_AUT_EXPECT_DO_REMOTE_CLOSE = (1 << 2),
LWS_AUT_EXPECT_TX /* expect this as tx from protocol */ = (1 << 3),
LWS_AUT_EXPECT_RX /* present this as rx to protocol */ = (1 << 4),
LWS_AUT_EXPECT_SHOULD_FAIL = (1 << 5),
LWS_AUT_EXPECT_SHOULD_TIMEOUT = (1 << 6),
};
typedef enum {
LPE_CONTINUE,
LPE_SUCCEEDED,
LPE_FAILED,
LPE_FAILED_UNEXPECTED_TIMEOUT,
LPE_FAILED_UNEXPECTED_PASS,
LPE_FAILED_UNEXPECTED_CLOSE,
LPE_SKIPPED,
LPE_CLOSING
} lws_unit_test_packet_disposition;
typedef int (*lws_unit_test_packet_test_cb)(const void *cb_user, int disposition);
typedef int (*lws_unit_test_packet_cb)(lws_abs_t *instance);
/* each step in the unit test */
typedef struct lws_unit_test_packet {
void *buffer;
lws_unit_test_packet_cb pre;
size_t len;
uint32_t flags;
} lws_unit_test_packet_t;
/* each unit test */
typedef struct lws_unit_test {
const char * name; /* NULL indicates end of test array */
lws_unit_test_packet_t * expect_array;
int max_secs;
} lws_unit_test_t;
enum {
LTMI_PEER_V_EXPECT_TEST = LTMI_TRANSPORT_BASE, /* u.value */
LTMI_PEER_V_EXPECT_RESULT_CB, /* u.value */
LTMI_PEER_V_EXPECT_RESULT_CB_ARG, /* u.value */
};
LWS_VISIBLE LWS_EXTERN const char *
lws_unit_test_result_name(int in);

View File

@ -0,0 +1,271 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup sock-adopt Socket adoption helpers
* ##Socket adoption helpers
*
* When integrating with an external app with its own event loop, these can
* be used to accept connections from someone else's listening socket.
*
* When using lws own event loop, these are not needed.
*/
///@{
/**
* lws_adopt_socket() - adopt foreign socket as if listen socket accepted it
* for the default vhost of context.
*
* \param context: lws context
* \param accept_fd: fd of already-accepted socket to adopt
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* LWS adopts the socket in http serving mode, it's ready to accept an upgrade
* to ws or just serve http.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd);
/**
* lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted
* it for vhost
*
* \param vh: lws vhost
* \param accept_fd: fd of already-accepted socket to adopt
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* LWS adopts the socket in http serving mode, it's ready to accept an upgrade
* to ws or just serve http.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
typedef enum {
LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */
LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */
LWS_ADOPT_SOCKET = 2, /* flag: absent implies file */
LWS_ADOPT_ALLOW_SSL = 4, /* flag: use tls */
LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */
LWS_ADOPT_FLAG_RAW_PROXY = 32, /* flag: raw proxy */
LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP,
} lws_adoption_type;
typedef union {
lws_sockfd_type sockfd;
lws_filefd_type filefd;
} lws_sock_file_fd_type;
#if defined(LWS_ESP_PLATFORM)
#include <lwip/sockets.h>
#endif
typedef union {
#if defined(LWS_WITH_IPV6)
struct sockaddr_in6 sa6;
#else
#if defined(LWS_ESP_PLATFORM)
uint8_t _pad_sa6[28];
#endif
#endif
struct sockaddr_in sa4;
} lws_sockaddr46;
#define sa46_sockaddr(_sa46) ((struct sockaddr *)(_sa46))
#if defined(LWS_WITH_IPV6)
#define sa46_socklen(_sa46) (socklen_t)((_sa46)->sa4.sin_family == AF_INET ? \
sizeof(struct sockaddr_in) : \
sizeof(struct sockaddr_in6))
#define sa46_sockport(_sa46, _sp) { if ((_sa46)->sa4.sin_family == AF_INET) \
(_sa46)->sa4.sin_port = (_sp); else \
(_sa46)->sa6.sin6_port = (_sp); }
#define sa46_address(_sa46) ((uint8_t *)((_sa46)->sa4.sin_family == AF_INET ? \
&_sa46->sa4.sin_addr : &_sa46->sa6.sin6_addr ))
#else
#define sa46_socklen(_sa46) (socklen_t)sizeof(struct sockaddr_in)
#define sa46_sockport(_sa46, _sp) (_sa46)->sa4.sin_port = (_sp)
#define sa46_address(_sa46) (uint8_t *)&_sa46->sa4.sin_addr
#endif
#define sa46_address_len(_sa46) ((_sa46)->sa4.sin_family == AF_INET ? 4 : 16)
#if defined(LWS_WITH_UDP)
struct lws_udp {
lws_sockaddr46 sa46;
lws_sockaddr46 sa46_pending;
uint8_t connected:1;
};
#endif
/**
* lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor
* if socket descriptor, should already have been accepted from listen socket
*
* \param vh: lws vhost
* \param type: OR-ed combinations of lws_adoption_type flags
* \param fd: union with either .sockfd or .filefd set
* \param vh_prot_name: NULL or vh protocol name to bind raw connection to
* \param parent: NULL or struct lws to attach new_wsi to as a child
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
* ready to accept an upgrade to ws or just serve http.
*
* parent may be NULL, if given it should be an existing wsi that will become the
* parent of the new wsi created by this call.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,
lws_sock_file_fd_type fd, const char *vh_prot_name,
struct lws *parent);
typedef struct lws_adopt_desc {
struct lws_vhost *vh; /**< vhost the wsi should belong to */
lws_adoption_type type; /**< OR-ed combinations of lws_adoption_type flags */
lws_sock_file_fd_type fd; /**< union with either .sockfd or .filefd set */
const char *vh_prot_name; /**< NULL or vh protocol name to bind raw connection to */
struct lws *parent; /**< NULL or struct lws to attach new_wsi to as a child */
void *opaque; /**< opaque pointer to set on created wsi */
const char *fi_wsi_name; /**< NULL, or Fault Injection inheritence filter for wsi=string/ context faults */
} lws_adopt_desc_t;
/**
* lws_adopt_descriptor_vhost_via_info() - adopt foreign socket or file descriptor
* if socket descriptor, should already have been accepted from listen socket
*
* \param info: the struct containing the parameters
*
* - vh: lws vhost
* - type: OR-ed combinations of lws_adoption_type flags
* - fd: union with either .sockfd or .filefd set
* - vh_prot_name: NULL or vh protocol name to bind raw connection to
* - parent: NULL or struct lws to attach new_wsi to as a child
* - opaque: opaque pointer to set on created wsi
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's
* ready to accept an upgrade to ws or just serve http.
*
* parent may be NULL, if given it should be an existing wsi that will become the
* parent of the new wsi created by this call.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_descriptor_vhost_via_info(const lws_adopt_desc_t *info);
/**
* lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it
* for the default vhost of context.
* \param context: lws context
* \param accept_fd: fd of already-accepted socket to adopt
* \param readbuf: NULL or pointer to data that must be drained before reading from
* accept_fd
* \param len: The length of the data held at \p readbuf
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* LWS adopts the socket in http serving mode, it's ready to accept an upgrade
* to ws or just serve http.
*
* If your external code did not already read from the socket, you can use
* lws_adopt_socket() instead.
*
* This api is guaranteed to use the data at \p readbuf first, before reading from
* the socket.
*
* \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd,
const char *readbuf, size_t len);
/**
* lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket
* accepted it for vhost.
* \param vhost: lws vhost
* \param accept_fd: fd of already-accepted socket to adopt
* \param readbuf: NULL or pointer to data that must be drained before reading from accept_fd
* \param len: The length of the data held at \p readbuf
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
*
* LWS adopts the socket in http serving mode, it's ready to accept an upgrade
* to ws or just serve http.
*
* If your external code did not already read from the socket, you can use
* lws_adopt_socket() instead.
*
* This api is guaranteed to use the data at \p readbuf first, before reading from
* the socket.
*
* \p readbuf is limited to the size of the ah rx buf, currently 2048 bytes.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost,
lws_sockfd_type accept_fd, const char *readbuf,
size_t len);
#define LWS_CAUDP_BIND (1 << 0)
#define LWS_CAUDP_BROADCAST (1 << 1)
#define LWS_CAUDP_PF_PACKET (1 << 2)
#if defined(LWS_WITH_UDP)
/**
* lws_create_adopt_udp() - create, bind and adopt a UDP socket
*
* \param vhost: lws vhost
* \param ads: NULL or address to do dns lookup on
* \param port: UDP port to bind to, -1 means unbound
* \param flags: 0 or LWS_CAUDP_NO_BIND
* \param protocol_name: Name of protocol on vhost to bind wsi to
* \param ifname: NULL, for network interface name to bind socket to
* \param parent_wsi: NULL or parent wsi new wsi will be a child of
* \param opaque: set created wsi opaque ptr to this
* \param retry_policy: NULL for vhost default policy else wsi specific policy
* \param fi_wsi_name: NULL, or string to inherit Fault Injection rules in
* form "wsi=string/rule". "wsi/rule" faults will be
* automatically applied as well. It's done at creation
* time so the rules can, eg, inject faults related to
* creation.
*
* Either returns new wsi bound to accept_fd, or closes accept_fd and
* returns NULL, having cleaned up any new wsi pieces.
* */
LWS_VISIBLE LWS_EXTERN struct lws *
lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
int flags, const char *protocol_name, const char *ifname,
struct lws *parent_wsi, void *opaque,
const lws_retry_bo_t *retry_policy, const char *fi_wsi_name);
#endif
///@}

View File

@ -0,0 +1,86 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if defined(LWS_WITH_UDP)
typedef enum dns_query_type {
LWS_ADNS_RECORD_A = 0x01,
LWS_ADNS_RECORD_CNAME = 0x05,
LWS_ADNS_RECORD_MX = 0x0f,
LWS_ADNS_RECORD_AAAA = 0x1c,
} adns_query_type_t;
typedef enum {
LADNS_RET_FAILED_WSI_CLOSED = -4,
LADNS_RET_NXDOMAIN = -3,
LADNS_RET_TIMEDOUT = -2,
LADNS_RET_FAILED = -1,
LADNS_RET_FOUND,
LADNS_RET_CONTINUING
} lws_async_dns_retcode_t;
struct addrinfo;
typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
const struct addrinfo *result, int n, void *opaque);
/**
* lws_async_dns_query() - perform a dns lookup using async dns
*
* \param context: the lws_context
* \param tsi: thread service index (usually 0)
* \param name: DNS name to look up
* \param qtype: type of query (A, AAAA etc)
* \param cb: query completion callback
* \param wsi: wsi if the query is related to one
*
* Starts an asynchronous DNS lookup, on completion the \p cb callback will
* be called.
*
* The reference count on the cached object is incremented for every callback
* that was called with the cached addrinfo results.
*
* The cached object can't be evicted until the reference count reaches zero...
* use lws_async_dns_freeaddrinfo() to indicate you're finsihed with the
* results for each callback that happened with them.
*/
LWS_VISIBLE LWS_EXTERN lws_async_dns_retcode_t
lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
adns_query_type_t qtype, lws_async_dns_cb_t cb,
struct lws *wsi, void *opaque);
/**
* lws_async_dns_freeaddrinfo() - decrement refcount on cached addrinfo results
*
* \param pai: a pointert to a pointer to first addrinfo returned as result in the callback
*
* Decrements the cache object's reference count. When it reaches zero, the
* cached object may be reaped subject to LRU rules.
*
* The pointer to the first addrinfo give in the argument is set to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_async_dns_freeaddrinfo(const struct addrinfo **ai);
#endif

View File

@ -0,0 +1,66 @@
/*
* I2C - bitbanged generic gpio implementation
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is like an abstract class for gpio, a real implementation provides
* functions for the ops that use the underlying OS gpio arrangements.
*/
typedef struct lws_bb_i2c {
lws_i2c_ops_t bb_ops; /* init to lws_bb_i2c_ops */
/* implementation-specific members */
_lws_plat_gpio_t scl;
_lws_plat_gpio_t sda;
const lws_gpio_ops_t *gpio;
void (*delay)(void);
} lws_bb_i2c_t;
#define lws_bb_i2c_ops \
{ \
.init = lws_bb_i2c_init, \
.start = lws_bb_i2c_start, \
.stop = lws_bb_i2c_stop, \
.write = lws_bb_i2c_write, \
.read = lws_bb_i2c_read, \
.set_ack = lws_bb_i2c_set_ack, \
}
int
lws_bb_i2c_init(const lws_i2c_ops_t *octx);
int
lws_bb_i2c_start(const lws_i2c_ops_t *octx);
void
lws_bb_i2c_stop(const lws_i2c_ops_t *octx);
int
lws_bb_i2c_write(const lws_i2c_ops_t *octx, uint8_t data);
int
lws_bb_i2c_read(const lws_i2c_ops_t *octx);
void
lws_bb_i2c_set_ack(const lws_i2c_ops_t *octx, int ack);

View File

@ -0,0 +1,62 @@
/*
* I2C - bitbanged generic gpio implementation
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is like an abstract class for gpio, a real implementation provides
* functions for the ops that use the underlying OS gpio arrangements.
*/
#define LWSBBSPI_FLAG_USE_NCMD3 (1 << 7)
#define LWSBBSPI_FLAG_USE_NCMD2 (1 << 6)
#define LWSBBSPI_FLAG_USE_NCMD1 (1 << 5)
#define LWSBBSPI_FLAG_USE_NCMD0 (1 << 4)
#define LWSBBSPI_FLAG_USE_NCS3 (1 << 3)
#define LWSBBSPI_FLAG_USE_NCS2 (1 << 2)
#define LWSBBSPI_FLAG_USE_NCS1 (1 << 1)
#define LWSBBSPI_FLAG_USE_NCS0 (1 << 0)
#define LWS_SPI_BB_MAX_CH 4
typedef struct lws_bb_spi {
lws_spi_ops_t bb_ops; /* init to lws_bb_spi_ops */
/* implementation-specific members */
const lws_gpio_ops_t *gpio;
_lws_plat_gpio_t clk;
_lws_plat_gpio_t ncs[LWS_SPI_BB_MAX_CH];
_lws_plat_gpio_t ncmd[LWS_SPI_BB_MAX_CH];
_lws_plat_gpio_t mosi;
_lws_plat_gpio_t miso;
uint8_t flags;
} lws_bb_spi_t;
#define lws_bb_spi_ops \
.init = lws_bb_spi_init, \
.queue = lws_bb_spi_queue
int
lws_bb_spi_init(const lws_spi_ops_t *octx);
int
lws_bb_spi_queue(const lws_spi_ops_t *octx, const lws_spi_desc_t *desc);

View File

@ -0,0 +1,120 @@
/*
* Generic button ops
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Leverages the lws generic gpio pieces to bind gpio buttons to smd events
*/
#if !defined(__LWS_BUTTON_H__)
#define __LWS_BUTTON_H__
typedef uint16_t lws_button_idx_t;
/* actual minimum may be 1 x RTOS tick depending on platform */
#define LWS_BUTTON_MON_TIMER_MS 5
typedef void (*lws_button_cb_t)(void *opaque, lws_button_idx_t idx, int state);
/* These are specified in ms but the granularity is LWS_BUTTON_MON_TIMER_MS,
* which may have been rounded up to an RTOS tick depending on platform */
enum {
LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK = (1 << 0)
};
typedef struct lws_button_regime {
uint16_t ms_min_down;
uint16_t ms_min_down_longpress;
uint16_t ms_up_settle;
uint16_t ms_doubleclick_grace;
uint16_t ms_repeat_down;
uint8_t flags;
/**< when double-click classification is enabled, clicks are delayed
* by ms_min_down + ms_doubleclick_grace to wait and see if it will
* become a double-click. Set LWSBTNRGMFLAG_CLASSIFY_DOUBLECLICK to
* enable it or leave that bit at 0 to get faster single-click
* classification.
*/
} lws_button_regime_t;
/*
* This is the const part of the button controller, describing the static
* bindings to gpio, and lws_smd event name information
*/
typedef struct lws_button_map {
_lws_plat_gpio_t gpio;
const char *smd_interaction_name;
const lws_button_regime_t *regime;
/**< a default regime is applied if this is left NULL */
} lws_button_map_t;
typedef struct lws_button_controller {
const char *smd_bc_name;
const lws_gpio_ops_t *gpio_ops;
const lws_button_map_t *button_map;
lws_button_idx_t active_state_bitmap;
uint8_t count_buttons;
} lws_button_controller_t;
struct lws_button_state; /* opaque */
/**
* lws_button_controller_create() - instantiate a button controller
*
* \param ctx: the lws_context
* \param controller: the static controller definition
*
* Instantiates a button controller from a static definition of the buttons
* and their smd names, and active levels, and binds it to a gpio implementation
*/
LWS_VISIBLE LWS_EXTERN struct lws_button_state *
lws_button_controller_create(struct lws_context *ctx,
const lws_button_controller_t *controller);
/**
* lws_button_controller_destroy() - destroys a button controller
*
* \param bcs: button controller state previously created
*
* Disables all buttons and then destroys and frees a previously created
* button controller.
*/
LWS_VISIBLE LWS_EXTERN void
lws_button_controller_destroy(struct lws_button_state *bcs);
LWS_VISIBLE LWS_EXTERN lws_button_idx_t
lws_button_get_bit(struct lws_button_state *bcs, const char *name);
/*
* lws_button_enable() - enable and disable buttons
*/
LWS_VISIBLE LWS_EXTERN void
lws_button_enable(struct lws_button_state *bcs,
lws_button_idx_t _reset, lws_button_idx_t _set);
#endif

View File

@ -0,0 +1,348 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup lws_cache_ttl Cache supporting expiry
* ##Cache supporting expiry
*
* These apis let you quickly and reliably implement caches of named objects,
* that have a "destroy-by date" and cache limits that will be observed.
*
* You can instantiate as many caches as you need. The first one must be an
* L1 / heap cache type, it can have parents and grandparents of other types
* which are accessible why writing / looking up and getting from the L1 cache.
* The outer "cache" layer may persistently store items to a backing store.
*
* Allocated object memory is entirely for the use of user code, up to the
* requested size.
*
* The key name for the listed objects may be any string chosen by the user,
* there is no special length limit as it is also allocated.
*
* Both expiry and LRU orderings are kept so it is easy to find out usage
* ordering and when the next object that will expire.
*
* Cached objects may be destroyed any time you go around the event loop, when
* you allocate new objects (to keep the whole cache under the specified limit),
* or when their expiry time arrives. So you shouldn't keep copies of pointers
* to cached objects after returning to the event loop.
*/
///@{
struct lws_cache_ttl_lru;
/**
* lws_cache_write_through() - add a new cache item object in all layers
*
* \param cache: the existing cache to allocate the object in
* \param specific_key: a key string that identifies the item in the cache
* \param source: optional payload for the cached item, NULL means caller will
* write the payload
* \param size: the size of the object to allocate
* \param expiry: the usec time that the object will autodestroy
* \param ppay: NULL, or a pointer to a void * to be set to the L1 payload
*
* If an item with the key already exists, it is destroyed before allocating a
* new one.
*
* Returns 0 if successful. The written entry will be scheduled to be auto-
* destroyed when \p expiry occurs.
*
* Adding or removing cache items may cause invalidation of cached queries.
*/
LWS_VISIBLE LWS_EXTERN int /* only valid until return to event loop */
lws_cache_write_through(struct lws_cache_ttl_lru *cache,
const char *specific_key, const uint8_t *source,
size_t size, lws_usec_t expiry, void **ppay);
typedef struct lws_cache_match {
lws_dll2_t list;
lws_usec_t expiry;
/* earliest expiry amongst results */
size_t payload_size;
/**< the payload is not attached here. This is a hint about what
* (*get)() will return for this tag name.
*/
size_t tag_size;
/* tag name + NUL is overcommitted */
} lws_cache_match_t;
/**
* lws_cache_heap_lookup() - get a list of matching items
*
* \param cache: the cache to search for the key
* \param wildcard_key: the item key string, may contain wildcards
* \param pdata: pointer to pointer to be set to the serialized result list
* \param psize: pointer to size_t to receive length of serialized result list
*
* This finds all unique items in the final cache that match search_key, which
* may contain wildcards. It does not return the payloads for matching items,
* just a list of specific tags in the that match.
*
* If successful, results are provided in a serialized list format, in no
* particular order, each result has the following fields
*
* - BE32: payload size in bytes (payload itself is not included)
* - BE32: specific tag name length in bytes
* - chars: tag name with terminating NUL
*
* These serialized results are themselves cached in L1 cache (only) and the
* result pointers are set pointing into that. If the results are still in L1
* cache next time this api is called, the results will be returned directly
* from that without repeating the expensive lookup on the backup store. That
* is why the results are provided in serialized form.
*
* The cached results list expiry is set to the earliest expiry of any listed
* item. Additionally any cached results are invalidated on addition or
* deletion (update is done as addition + deletion) of any item that would
* match the results' original wildcard_key. For the typical case new items
* are rare compared to lookups, this is efficient.
*
* Lookup matching does not itself affect LRU or cache status of the result
* itsems. Typically user code will get the lookup results, and then perform
* get operations on each item in its desired order, that will bring the items
* to the head of the LRU list and occupy L1 cache.
*
* Returns 0 if proceeded alright, or nonzero if error. If there was an error,
* any partial results set has been deallocated cleanly before returning.
*/
LWS_VISIBLE LWS_EXTERN int
lws_cache_lookup(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
const void **pdata, size_t *psize);
/**
* lws_cache_item_get() - bring a specific item into L1 and get payload info
*
* \param cache: the cache to search for the key
* \param specific_key: the key string of the item to get
* \param pdata: pointer to a void * to be set to the payload in L1 cache
* \param psize: pointer to a size_t to be set to the payload size
*
* If the cache still has an item matching the key string, it will be destroyed.
*
* Adding or removing cache items may cause invalidation of cached queries.
*
* Notice the cache payload is a blob of the given size. If you are storing
* strings, there is no NUL termination unless you stored them with it.
*
* Returns 0 if successful.
*/
LWS_VISIBLE LWS_EXTERN int
lws_cache_item_get(struct lws_cache_ttl_lru *cache, const char *specific_key,
const void **pdata, size_t *psize);
/**
* lws_cache_item_remove() - remove item from all cache levels
*
* \param cache: the cache to search for the key
* \param wildcard_key: the item key string
*
* Removes any copy of any item matching the \p wildcard_key from any cache
* level in one step.
*
* Adding or removing cache items may cause invalidation of cached queries
* that could refer to the removed item.
*/
LWS_VISIBLE LWS_EXTERN int
lws_cache_item_remove(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
/**
* lws_cache_footprint() - query the amount of storage used by the cache layer
*
* \param cache: cache to query
*
* Returns number of payload bytes stored in cache currently
*/
LWS_VISIBLE LWS_EXTERN uint64_t
lws_cache_footprint(struct lws_cache_ttl_lru *cache);
/**
* lws_cache_debug_dump() - if built in debug mode dump cache contents to log
*
* \param cache: cache to dump
*
* If lws was built in debug mode, dump cache to log, otherwise a NOP.
*/
LWS_VISIBLE LWS_EXTERN void
lws_cache_debug_dump(struct lws_cache_ttl_lru *cache);
typedef struct lws_cache_results {
const uint8_t *ptr; /* set before using walk api */
size_t size; /* set before using walk api */
size_t payload_len;
size_t tag_len;
const uint8_t *tag;
} lws_cache_results_t;
/**
* lws_cache_results_walk() - parse next result
*
* \param walk_ctx: the context of the results blob to walk
*
* Caller must initialize \p walk_ctx.ptr and \p walk_ctx.size before calling.
* These are set to the results returned from a _lookup api call.
*
* The call returns 0 if the struct elements have been set to a result, or 1
* if there where no more results in the blob to walk.
*
* If successful, after the call \p payload_len is set to the length of the
* payload related to this result key (the payload itself is not present),
* \p tag_len is set to the length of the result key name, and \p tag is set
* to the result tag name, with a terminating NUL.
*/
LWS_VISIBLE LWS_EXTERN int
lws_cache_results_walk(lws_cache_results_t *walk_ctx);
typedef void (*lws_cache_item_destroy_cb)(void *item, size_t size);
struct lws_cache_creation_info {
struct lws_context *cx;
/**< Mandatory: the lws_context */
const char *name;
/**< Mandatory: short cache name */
lws_cache_item_destroy_cb cb;
/**< NULL, or a callback that can hook cache item destory */
struct lws_cache_ttl_lru *parent;
/**< NULL, or next cache level */
const struct lws_cache_ops *ops;
/**< NULL for default, heap-based ops, else custom cache storage and
* query implementation */
union {
struct {
const char *filepath;
/**< the filepath to store items in */
} nscookiejar;
} u;
/**< these are extra configuration for specific cache types */
size_t max_footprint;
/**< 0, or the max heap allocation allowed before destroying
* lru items to keep it under the limit */
size_t max_items;
/**< 0, or the max number of items allowed in the cache before
* destroying lru items to keep it under the limit */
size_t max_payload;
/**< 0, or the max allowed payload size for one item */
int tsi;
/**< 0 unless using SMP, then tsi to bind sul to */
};
struct lws_cache_ops {
struct lws_cache_ttl_lru *
(*create)(const struct lws_cache_creation_info *info);
/**< create an instance of the cache type specified in info */
void
(*destroy)(struct lws_cache_ttl_lru **_cache);
/**< destroy the logical cache instance pointed to by *_cache, doesn't
* affect any NV backing storage */
int
(*expunge)(struct lws_cache_ttl_lru *cache);
/**< completely delete any backing storage related to the cache
* instance, eg, delete the backing file */
int
(*write)(struct lws_cache_ttl_lru *cache, const char *specific_key,
const uint8_t *source, size_t size, lws_usec_t expiry,
void **ppvoid);
/**< create an entry in the cache level according to the given info */
int
(*tag_match)(struct lws_cache_ttl_lru *cache, const char *wc,
const char *tag, char lookup_rules);
/**< Just tell us if tag would match wildcard, using whatever special
* rules the backing store might use for tag matching. 0 indicates
* it is a match on wildcard, nonzero means does not match.
*/
int
(*lookup)(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
lws_dll2_owner_t *results_owner);
/**+ add keys for search_key matches not already listed in the results
* owner */
int
(*invalidate)(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
/**< remove matching item(s) from cache level */
int
(*get)(struct lws_cache_ttl_lru *cache, const char *specific_key,
const void **pdata, size_t *psize);
/**< if it has the item, fills L1 with item. updates LRU, and returns
* pointer to payload in L1 */
void
(*debug_dump)(struct lws_cache_ttl_lru *cache);
/**< Helper to dump the whole cache contents to log, useful for debug */
};
/**
* lws_cache_create() - create an empty cache you can allocate items in
*
* \param info: a struct describing the cache to create
*
* Create an empty cache you can allocate items in. The cache will be kept
* below the max_footprint and max_items limits if they are nonzero, by
* destroying least-recently-used items until it remains below the limits.
*
* Items will auto-destroy when their expiry time is reached.
*
* When items are destroyed from the cache, if \p cb is non-NULL, it will be
* called back with the item pointer after it has been removed from the cache,
* but before it is deallocated and destroyed.
*
* context and tsi are used when scheduling expiry callbacks
*/
LWS_VISIBLE LWS_EXTERN struct lws_cache_ttl_lru *
lws_cache_create(const struct lws_cache_creation_info *info);
/**
* lws_cache_destroy() - destroy a previously created cache
*
* \param cache: pointer to the cache
*
* Everything in the cache is destroyed, then the cache itself is destroyed,
* and *cache set to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_cache_destroy(struct lws_cache_ttl_lru **cache);
/**
* lws_cache_expunge() - destroy all items in cache and parents
*
* \param cache: pointer to the cache
*
* Everything in the cache and parents is destroyed, leaving it empty.
* If the cache has a backing store, it is deleted.
*
* Returns 0 if no problems reported at any cache layer, else nonzero.
*/
LWS_VISIBLE LWS_EXTERN int
lws_cache_expunge(struct lws_cache_ttl_lru *cache);
LWS_VISIBLE extern const struct lws_cache_ops lws_cache_ops_heap,
lws_cache_ops_nscookiejar;
///@}

View File

@ -0,0 +1,924 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup usercb User Callback
*
* ##User protocol callback
*
* The protocol callback is the primary way lws interacts with
* user code. For one of a list of a few dozen reasons the callback gets
* called at some event to be handled.
*
* All of the events can be ignored, returning 0 is taken as "OK" and returning
* nonzero in most cases indicates that the connection should be closed.
*/
///@{
struct lws_ssl_info {
int where;
int ret;
};
enum lws_cert_update_state {
LWS_CUS_IDLE,
LWS_CUS_STARTING,
LWS_CUS_SUCCESS,
LWS_CUS_FAILED,
LWS_CUS_CREATE_KEYS,
LWS_CUS_REG,
LWS_CUS_AUTH,
LWS_CUS_CHALLENGE,
LWS_CUS_CREATE_REQ,
LWS_CUS_REQ,
LWS_CUS_CONFIRM,
LWS_CUS_ISSUE,
};
enum {
LWS_TLS_REQ_ELEMENT_COUNTRY,
LWS_TLS_REQ_ELEMENT_STATE,
LWS_TLS_REQ_ELEMENT_LOCALITY,
LWS_TLS_REQ_ELEMENT_ORGANIZATION,
LWS_TLS_REQ_ELEMENT_COMMON_NAME,
LWS_TLS_REQ_ELEMENT_SUBJECT_ALT_NAME,
LWS_TLS_REQ_ELEMENT_EMAIL,
LWS_TLS_REQ_ELEMENT_COUNT,
LWS_TLS_SET_DIR_URL = LWS_TLS_REQ_ELEMENT_COUNT,
LWS_TLS_SET_AUTH_PATH,
LWS_TLS_SET_CERT_PATH,
LWS_TLS_SET_KEY_PATH,
LWS_TLS_TOTAL_COUNT
};
struct lws_acme_cert_aging_args {
struct lws_vhost *vh;
const char *element_overrides[LWS_TLS_TOTAL_COUNT]; /* NULL = use pvo */
};
/*
* With LWS_CALLBACK_FILTER_NETWORK_CONNECTION callback, user_data pointer
* points to one of these
*/
struct lws_filter_network_conn_args {
struct sockaddr_storage cli_addr;
socklen_t clilen;
lws_sockfd_type accept_fd;
};
/*
* NOTE: These public enums are part of the abi. If you want to add one,
* add it at where specified so existing users are unaffected.
*/
/** enum lws_callback_reasons - reason you're getting a protocol callback */
enum lws_callback_reasons {
/* ---------------------------------------------------------------------
* ----- Callbacks related to wsi and protocol binding lifecycle -----
*/
LWS_CALLBACK_PROTOCOL_INIT = 27,
/**< One-time call per protocol, per-vhost using it, so it can
* do initial setup / allocations etc */
LWS_CALLBACK_PROTOCOL_DESTROY = 28,
/**< One-time call per protocol, per-vhost using it, indicating
* this protocol won't get used at all after this callback, the
* vhost is getting destroyed. Take the opportunity to
* deallocate everything that was allocated by the protocol. */
LWS_CALLBACK_WSI_CREATE = 29,
/**< outermost (earliest) wsi create notification to protocols[0] */
LWS_CALLBACK_WSI_DESTROY = 30,
/**< outermost (latest) wsi destroy notification to protocols[0] */
LWS_CALLBACK_WSI_TX_CREDIT_GET = 103,
/**< manually-managed connection received TX credit (len is int32) */
/* ---------------------------------------------------------------------
* ----- Callbacks related to Server TLS -----
*/
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21,
/**< if configured for
* including OpenSSL support, this callback allows your user code
* to perform extra SSL_CTX_load_verify_locations() or similar
* calls to direct OpenSSL where to find certificates the client
* can use to confirm the remote server identity. user is the
* OpenSSL SSL_CTX* */
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22,
/**< if configured for
* including OpenSSL support, this callback allows your user code
* to load extra certificates into the server which allow it to
* verify the validity of certificates returned by clients. user
* is the server's OpenSSL SSL_CTX* and in is the lws_vhost */
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23,
/**< if the libwebsockets vhost was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, user is the x509_ctx,
* in is the ssl pointer and len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates. */
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37,
/**< if configured for including OpenSSL support but no private key
* file has been specified (ssl_private_key_filepath is NULL), this is
* called to allow the user to set the private key directly via
* libopenssl and perform further operations if required; this might be
* useful in situations where the private key is not directly accessible
* by the OS, for example if it is stored on a smartcard.
* user is the server's OpenSSL SSL_CTX* */
LWS_CALLBACK_SSL_INFO = 67,
/**< SSL connections only. An event you registered an
* interest in at the vhost has occurred on a connection
* using the vhost. in is a pointer to a
* struct lws_ssl_info containing information about the
* event*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to Client TLS -----
*/
LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION = 58,
/**< Similar to LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION
* this callback is called during OpenSSL verification of the cert
* sent from the server to the client. It is sent to protocol[0]
* callback as no protocol has been negotiated on the connection yet.
* Notice that the wsi is set because lws_client_connect_via_info was
* successful.
*
* See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, user is the x509_ctx,
* in is the ssl pointer and len is preverify_ok.
*
* THIS IS NOT RECOMMENDED BUT if a cert validation error shall be
* overruled and cert shall be accepted as ok,
* X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK); must be
* called and return value must be 0 to mean the cert is OK;
* returning 1 will fail the cert in any case.
*
* This also means that if you don't handle this callback then
* the default callback action of returning 0 will not accept the
* certificate in case of a validation error decided by the SSL lib.
*
* This is expected and secure behaviour when validating certificates.
*
* Note: LCCSCF_ALLOW_SELFSIGNED and
* LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK still work without this
* callback being implemented.
*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to HTTP Server -----
*/
LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19,
/**< A new client has been accepted by the ws server. This
* callback allows setting any relevant property to it. Because this
* happens immediately after the instantiation of a new client,
* there's no websocket protocol selected yet so this callback is
* issued only to protocol 0. Only wsi is defined, pointing to the
* new client, and the return value is ignored. */
LWS_CALLBACK_HTTP = 12,
/**< an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* in points to the URI path requested and
* lws_serve_http_file() makes it very
* simple to send back a file to the client.
* Normally after sending the file you are done
* with the http connection, since the rest of the
* activity will come by websockets from the script
* that was delivered by http, so you will want to
* return 1; to close and free up the connection. */
LWS_CALLBACK_HTTP_BODY = 13,
/**< the next len bytes data from the http
* request body HTTP connection is now available in in. */
LWS_CALLBACK_HTTP_BODY_COMPLETION = 14,
/**< the expected amount of http request body has been delivered */
LWS_CALLBACK_HTTP_FILE_COMPLETION = 15,
/**< a file requested to be sent down http link has completed. */
LWS_CALLBACK_HTTP_WRITEABLE = 16,
/**< you can write more down the http protocol link now. */
LWS_CALLBACK_CLOSED_HTTP = 5,
/**< when a HTTP (non-websocket) session ends */
LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18,
/**< called when the request has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* user is a pointer to the connection user space allocation,
* in is the URI, eg, "/"
* In your handler you can use the public APIs
* lws_hdr_total_length() / lws_hdr_copy() to access all of the
* headers using the header enums lws_token_indexes from
* libwebsockets.h to check for and read the supported header
* presence and content before deciding to allow the http
* connection to proceed or to kill the connection. */
LWS_CALLBACK_ADD_HEADERS = 53,
/**< This gives your user code a chance to add headers to a server
* transaction bound to your protocol. `in` points to a
* `struct lws_process_html_args` describing a buffer and length
* you can add headers into using the normal lws apis.
*
* (see LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to add headers to
* a client transaction)
*
* Only `args->p` and `args->len` are valid, and `args->p` should
* be moved on by the amount of bytes written, if any. Eg
*
* case LWS_CALLBACK_ADD_HEADERS:
*
* struct lws_process_html_args *args =
* (struct lws_process_html_args *)in;
*
* if (lws_add_http_header_by_name(wsi,
* (unsigned char *)"set-cookie:",
* (unsigned char *)cookie, cookie_len,
* (unsigned char **)&args->p,
* (unsigned char *)args->p + args->max_len))
* return 1;
*
* break;
*/
LWS_CALLBACK_VERIFY_BASIC_AUTHORIZATION = 102,
/**< This gives the user code a chance to accept or reject credentials
* provided HTTP to basic authorization. It will only be called if the
* http mount's authentication_mode is set to LWSAUTHM_BASIC_AUTH_CALLBACK
* `in` points to a credential string of the form `username:password` If
* the callback returns zero (the default if unhandled), then the
* transaction ends with HTTP_STATUS_UNAUTHORIZED, otherwise the request
* will be processed */
LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51,
/**< This gives the user code a chance to forbid an http access.
* `in` points to a `struct lws_process_html_args`, which
* describes the URL, and a bit mask describing the type of
* authentication required. If the callback returns nonzero,
* the transaction ends with HTTP_STATUS_UNAUTHORIZED. */
LWS_CALLBACK_PROCESS_HTML = 52,
/**< This gives your user code a chance to mangle outgoing
* HTML. `in` points to a `struct lws_process_html_args`
* which describes the buffer containing outgoing HTML.
* The buffer may grow up to `.max_len` (currently +128
* bytes per buffer).
*/
LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49,
/**< By default, all HTTP handling is done in protocols[0].
* However you can bind different protocols (by name) to
* different parts of the URL space using callback mounts. This
* callback occurs in the new protocol when a wsi is bound
* to that protocol. Any protocol allocation related to the
* http transaction processing should be created then.
* These specific callbacks are necessary because with HTTP/1.1,
* a single connection may perform at series of different
* transactions at different URLs, thus the lifetime of the
* protocol bind is just for one transaction, not connection. */
LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50,
/**< This is called when a transaction is unbound from a protocol.
* It indicates the connection completed its transaction and may
* do something different now. Any protocol allocation related
* to the http transaction processing should be destroyed. */
LWS_CALLBACK_HTTP_CONFIRM_UPGRADE = 86,
/**< This is your chance to reject an HTTP upgrade action. The
* name of the protocol being upgraded to is in 'in', and the ah
* is still bound to the wsi, so you can look at the headers.
*
* The default of returning 0 (ie, also if not handled) means the
* upgrade may proceed. Return <0 to just hang up the connection,
* or >0 if you have rejected the connection by returning http headers
* and response code yourself.
*
* There is no need for you to call transaction_completed() as the
* caller will take care of it when it sees you returned >0.
*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to HTTP Client -----
*/
LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44,
/**< The HTTP client connection has succeeded, and is now
* connected to the server */
LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45,
/**< The HTTP client connection is closing */
LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48,
/**< This is generated by lws_http_client_read() used to drain
* incoming data. In the case the incoming data was chunked, it will
* be split into multiple smaller callbacks for each chunk block,
* removing the chunk headers. If not chunked, it will appear all in
* one callback. */
LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46,
/**< This indicates data was received on the HTTP client connection. It
* does NOT actually drain or provide the data, so if you are doing
* http client, you MUST handle this and call lws_http_client_read().
* Failure to deal with it as in the minimal examples may cause spinning
* around the event loop as it's continuously signalled the same data
* is available for read. The related minimal examples show how to
* handle it.
*
* It's possible to defer calling lws_http_client_read() if you use
* rx flow control to stop further rx handling on the connection until
* you did deal with it. But normally you would call it in the handler.
*
* lws_http_client_read() strips any chunked framing and calls back
* with only payload data to LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ. The
* chunking is the reason this is not just all done in one callback for
* http.
*/
LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47,
/**< The client transaction completed... at the moment this
* is the same as closing since transaction pipelining on
* client side is not yet supported. */
LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57,
/**< when doing an HTTP type client connection, you can call
* lws_client_http_body_pending(wsi, 1) from
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callbacks
* sending the HTTP headers.
*
* From this callback, when you have sent everything, you should let
* lws know by calling lws_client_http_body_pending(wsi, 0)
*/
LWS_CALLBACK_CLIENT_HTTP_REDIRECT = 104,
/**< we're handling a 3xx redirect... return nonzero to hang up */
LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL = 85,
LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL = 76,
/* ---------------------------------------------------------------------
* ----- Callbacks related to Websocket Server -----
*/
LWS_CALLBACK_ESTABLISHED = 0,
/**< (VH) after the server completes a handshake with an incoming
* client. If you built the library with ssl support, in is a
* pointer to the ssl struct associated with the connection or NULL.
*
* b0 of len is set if the connection was made using ws-over-h2
*/
LWS_CALLBACK_CLOSED = 4,
/**< when the websocket session ends */
LWS_CALLBACK_SERVER_WRITEABLE = 11,
/**< See LWS_CALLBACK_CLIENT_WRITEABLE */
LWS_CALLBACK_RECEIVE = 6,
/**< data has appeared for this server endpoint from a
* remote client, it can be found at *in and is
* len bytes long */
LWS_CALLBACK_RECEIVE_PONG = 7,
/**< servers receive PONG packets with this callback reason */
LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38,
/**< The peer has sent an unsolicited Close WS packet. in and
* len are the optional close code (first 2 bytes, network
* order) and the optional additional information which is not
* defined in the standard, and may be a string or non human-readable
* data.
* If you return 0 lws will echo the close and then close the
* connection. If you return nonzero lws will just close the
* connection. */
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20,
/**< called when the handshake has
* been received and parsed from the client, but the response is
* not sent yet. Return non-zero to disallow the connection.
* user is a pointer to the connection user space allocation,
* in is the requested protocol name
* In your handler you can use the public APIs
* lws_hdr_total_length() / lws_hdr_copy() to access all of the
* headers using the header enums lws_token_indexes from
* libwebsockets.h to check for and read the supported header
* presence and content before deciding to allow the handshake
* to proceed or to kill the connection. */
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25,
/**< When the server handshake code
* sees that it does support a requested extension, before
* accepting the extension by additing to the list sent back to
* the client it gives this callback just to check that it's okay
* to use that extension. It calls back to the requested protocol
* and with in being the extension name, len is 0 and user is
* valid. Note though at this time the ESTABLISHED callback hasn't
* happened yet so if you initialize user content there, user
* content during this callback might not be useful for anything. */
LWS_CALLBACK_WS_SERVER_BIND_PROTOCOL = 77,
LWS_CALLBACK_WS_SERVER_DROP_PROTOCOL = 78,
/* ---------------------------------------------------------------------
* ----- Callbacks related to Websocket Client -----
*/
LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1,
/**< the request client connection has been unable to complete a
* handshake with the remote server. If in is non-NULL, you can
* find an error string of length len where it points to
*
* Diagnostic strings that may be returned include
*
* "getaddrinfo (ipv6) failed"
* "unknown address family"
* "getaddrinfo (ipv4) failed"
* "set socket opts failed"
* "insert wsi failed"
* "lws_ssl_client_connect1 failed"
* "lws_ssl_client_connect2 failed"
* "Peer hung up"
* "read failed"
* "HS: URI missing"
* "HS: Redirect code but no Location"
* "HS: URI did not parse"
* "HS: Redirect failed"
* "HS: Server did not return 200"
* "HS: OOM"
* "HS: disallowed by client filter"
* "HS: disallowed at ESTABLISHED"
* "HS: ACCEPT missing"
* "HS: ws upgrade response not 101"
* "HS: UPGRADE missing"
* "HS: Upgrade to something other than websocket"
* "HS: CONNECTION missing"
* "HS: UPGRADE malformed"
* "HS: PROTOCOL malformed"
* "HS: Cannot match protocol"
* "HS: EXT: list too big"
* "HS: EXT: failed setting defaults"
* "HS: EXT: failed parsing defaults"
* "HS: EXT: failed parsing options"
* "HS: EXT: Rejects server options"
* "HS: EXT: unknown ext"
* "HS: Accept hash wrong"
* "HS: Rejected by filter cb"
* "HS: OOM"
* "HS: SO_SNDBUF failed"
* "HS: Rejected at CLIENT_ESTABLISHED"
*/
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2,
/**< this is the last chance for the client user code to examine the
* http headers and decide to reject the connection. If the
* content in the headers is interesting to the
* client (url, etc) it needs to copy it out at
* this point since it will be destroyed before
* the CLIENT_ESTABLISHED call */
LWS_CALLBACK_CLIENT_ESTABLISHED = 3,
/**< after your client connection completed the websocket upgrade
* handshake with the remote server */
LWS_CALLBACK_CLIENT_CLOSED = 75,
/**< when a client websocket session ends */
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24,
/**< this callback happens
* when a client handshake is being compiled. user is NULL,
* in is a char **, it's pointing to a char * which holds the
* next location in the header buffer where you can add
* headers, and len is the remaining space in the header buffer,
* which is typically some hundreds of bytes. So, to add a canned
* cookie, your handler code might look similar to:
*
* char **p = (char **)in, *end = (*p) + len;
*
* if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_COOKIE,
* (unsigned char)"a=b", 3, p, end))
* return -1;
*
* See LWS_CALLBACK_ADD_HEADERS for adding headers to server
* transactions.
*/
LWS_CALLBACK_CLIENT_RECEIVE = 8,
/**< data has appeared from the server for the client connection, it
* can be found at *in and is len bytes long */
LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9,
/**< clients receive PONG packets with this callback reason */
LWS_CALLBACK_CLIENT_WRITEABLE = 10,
/**< If you call lws_callback_on_writable() on a connection, you will
* get one of these callbacks coming when the connection socket
* is able to accept another write packet without blocking.
* If it already was able to take another packet without blocking,
* you'll get this callback at the next call to the service loop
* function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE
* and servers get LWS_CALLBACK_SERVER_WRITEABLE. */
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26,
/**< When a ws client
* connection is being prepared to start a handshake to a server,
* each supported extension is checked with protocols[0] callback
* with this reason, giving the user code a chance to suppress the
* claim to support that extension by returning non-zero. If
* unhandled, by default 0 will be returned and the extension
* support included in the header to the server. Notice this
* callback comes to protocols[0]. */
LWS_CALLBACK_WS_EXT_DEFAULTS = 39,
/**< Gives client connections an opportunity to adjust negotiated
* extension defaults. `user` is the extension name that was
* negotiated (eg, "permessage-deflate"). `in` points to a
* buffer and `len` is the buffer size. The user callback can
* set the buffer to a string describing options the extension
* should parse. Or just ignore for defaults. */
LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17,
/**< called when a client connects to
* the server at network level; the connection is accepted but then
* passed to this callback to decide whether to hang up immediately
* or not, based on the client IP.
*
* user_data in the callback points to a
* struct lws_filter_network_conn_args that is prepared with the
* sockfd, and the peer's address information.
*
* in contains the connection socket's descriptor.
*
* Since the client connection information is not available yet,
* wsi still pointing to the main server socket.
*
* Return non-zero to terminate the connection before sending or
* receiving anything. Because this happens immediately after the
* network connection from the client, there's no websocket protocol
* selected yet so this callback is issued only to protocol 0. */
LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL = 79,
LWS_CALLBACK_WS_CLIENT_DROP_PROTOCOL = 80,
/* ---------------------------------------------------------------------
* ----- Callbacks related to external poll loop integration -----
*/
LWS_CALLBACK_GET_THREAD_ID = 31,
/**< lws can accept callback when writable requests from other
* threads, if you implement this callback and return an opaque
* current thread ID integer. */
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD = 32,
/**< lws normally deals with its poll() or other event loop
* internally, but in the case you are integrating with another
* server you will need to have lws sockets share a
* polling array with the other server. This and the other
* POLL_FD related callbacks let you put your specialized
* poll array interface code in the callback for protocol 0, the
* first protocol you support, usually the HTTP protocol in the
* serving case.
* This callback happens when a socket needs to be
* added to the polling loop: in points to a struct
* lws_pollargs; the fd member of the struct is the file
* descriptor, and events contains the active events
*
* If you are using the internal lws polling / event loop
* you can just ignore these callbacks. */
LWS_CALLBACK_DEL_POLL_FD = 33,
/**< This callback happens when a socket descriptor
* needs to be removed from an external polling array. in is
* again the struct lws_pollargs containing the fd member
* to be removed. If you are using the internal polling
* loop, you can just ignore it. */
LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34,
/**< This callback happens when lws wants to modify the events for
* a connection.
* in is the struct lws_pollargs with the fd to change.
* The new event mask is in events member and the old mask is in
* the prev_events member.
* If you are using the internal polling loop, you can just ignore
* it. */
LWS_CALLBACK_LOCK_POLL = 35,
/**< These allow the external poll changes driven
* by lws to participate in an external thread locking
* scheme around the changes, so the whole thing is threadsafe.
* These are called around three activities in the library,
* - inserting a new wsi in the wsi / fd table (len=1)
* - deleting a wsi from the wsi / fd table (len=1)
* - changing a wsi's POLLIN/OUT state (len=0)
* Locking and unlocking external synchronization objects when
* len == 1 allows external threads to be synchronized against
* wsi lifecycle changes if it acquires the same lock for the
* duration of wsi dereference from the other thread context. */
LWS_CALLBACK_UNLOCK_POLL = 36,
/**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll */
/* ---------------------------------------------------------------------
* ----- Callbacks related to CGI serving -----
*/
LWS_CALLBACK_CGI = 40,
/**< CGI: CGI IO events on stdin / out / err are sent here on
* protocols[0]. The provided `lws_callback_http_dummy()`
* handles this and the callback should be directed there if
* you use CGI. */
LWS_CALLBACK_CGI_TERMINATED = 41,
/**< CGI: The related CGI process ended, this is called before
* the wsi is closed. Used to, eg, terminate chunking.
* The provided `lws_callback_http_dummy()`
* handles this and the callback should be directed there if
* you use CGI. The child PID that terminated is in len. */
LWS_CALLBACK_CGI_STDIN_DATA = 42,
/**< CGI: Data is, to be sent to the CGI process stdin, eg from
* a POST body. The provided `lws_callback_http_dummy()`
* handles this and the callback should be directed there if
* you use CGI. */
LWS_CALLBACK_CGI_STDIN_COMPLETED = 43,
/**< CGI: no more stdin is coming. The provided
* `lws_callback_http_dummy()` handles this and the callback
* should be directed there if you use CGI. */
LWS_CALLBACK_CGI_PROCESS_ATTACH = 70,
/**< CGI: Sent when the CGI process is spawned for the wsi. The
* len parameter is the PID of the child process */
/* ---------------------------------------------------------------------
* ----- Callbacks related to Generic Sessions -----
*/
LWS_CALLBACK_SESSION_INFO = 54,
/**< This is only generated by user code using generic sessions.
* It's used to get a `struct lws_session_info` filled in by
* generic sessions with information about the logged-in user.
* See the messageboard sample for an example of how to use. */
LWS_CALLBACK_GS_EVENT = 55,
/**< Indicates an event happened to the Generic Sessions session.
* `in` contains a `struct lws_gs_event_args` describing the event. */
LWS_CALLBACK_HTTP_PMO = 56,
/**< per-mount options for this connection, called before
* the normal LWS_CALLBACK_HTTP when the mount has per-mount
* options.
*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to RAW PROXY -----
*/
LWS_CALLBACK_RAW_PROXY_CLI_RX = 89,
/**< RAW mode client (outgoing) RX */
LWS_CALLBACK_RAW_PROXY_SRV_RX = 90,
/**< RAW mode server (listening) RX */
LWS_CALLBACK_RAW_PROXY_CLI_CLOSE = 91,
/**< RAW mode client (outgoing) is closing */
LWS_CALLBACK_RAW_PROXY_SRV_CLOSE = 92,
/**< RAW mode server (listening) is closing */
LWS_CALLBACK_RAW_PROXY_CLI_WRITEABLE = 93,
/**< RAW mode client (outgoing) may be written */
LWS_CALLBACK_RAW_PROXY_SRV_WRITEABLE = 94,
/**< RAW mode server (listening) may be written */
LWS_CALLBACK_RAW_PROXY_CLI_ADOPT = 95,
/**< RAW mode client (onward) accepted socket was adopted
* (equivalent to 'wsi created') */
LWS_CALLBACK_RAW_PROXY_SRV_ADOPT = 96,
/**< RAW mode server (listening) accepted socket was adopted
* (equivalent to 'wsi created') */
LWS_CALLBACK_RAW_PROXY_CLI_BIND_PROTOCOL = 97,
LWS_CALLBACK_RAW_PROXY_SRV_BIND_PROTOCOL = 98,
LWS_CALLBACK_RAW_PROXY_CLI_DROP_PROTOCOL = 99,
LWS_CALLBACK_RAW_PROXY_SRV_DROP_PROTOCOL = 100,
/* ---------------------------------------------------------------------
* ----- Callbacks related to RAW sockets -----
*/
LWS_CALLBACK_RAW_RX = 59,
/**< RAW mode connection RX */
LWS_CALLBACK_RAW_CLOSE = 60,
/**< RAW mode connection is closing */
LWS_CALLBACK_RAW_WRITEABLE = 61,
/**< RAW mode connection may be written */
LWS_CALLBACK_RAW_ADOPT = 62,
/**< RAW mode connection was adopted (equivalent to 'wsi created') */
LWS_CALLBACK_RAW_CONNECTED = 101,
/**< outgoing client RAW mode connection was connected */
LWS_CALLBACK_RAW_SKT_BIND_PROTOCOL = 81,
LWS_CALLBACK_RAW_SKT_DROP_PROTOCOL = 82,
/* ---------------------------------------------------------------------
* ----- Callbacks related to RAW file handles -----
*/
LWS_CALLBACK_RAW_ADOPT_FILE = 63,
/**< RAW mode file was adopted (equivalent to 'wsi created') */
LWS_CALLBACK_RAW_RX_FILE = 64,
/**< This is the indication the RAW mode file has something to read.
* This doesn't actually do the read of the file and len is always
* 0... your code should do the read having been informed there is
* something to read now. */
LWS_CALLBACK_RAW_WRITEABLE_FILE = 65,
/**< RAW mode file is writeable */
LWS_CALLBACK_RAW_CLOSE_FILE = 66,
/**< RAW mode wsi that adopted a file is closing */
LWS_CALLBACK_RAW_FILE_BIND_PROTOCOL = 83,
LWS_CALLBACK_RAW_FILE_DROP_PROTOCOL = 84,
/* ---------------------------------------------------------------------
* ----- Callbacks related to generic wsi events -----
*/
LWS_CALLBACK_TIMER = 73,
/**< When the time elapsed after a call to
* lws_set_timer_usecs(wsi, usecs) is up, the wsi will get one of
* these callbacks. The deadline can be continuously extended into the
* future by later calls to lws_set_timer_usecs() before the deadline
* expires, or cancelled by lws_set_timer_usecs(wsi, -1);
*/
LWS_CALLBACK_EVENT_WAIT_CANCELLED = 71,
/**< This is sent to every protocol of every vhost in response
* to lws_cancel_service() or lws_cancel_service_pt(). This
* callback is serialized in the lws event loop normally, even
* if the lws_cancel_service[_pt]() call was from a different
* thread. */
LWS_CALLBACK_CHILD_CLOSING = 69,
/**< Sent to parent to notify them a child is closing / being
* destroyed. in is the child wsi.
*/
LWS_CALLBACK_CONNECTING = 105,
/**< Called before a socketfd is about to connect(). In is the
* socketfd, cast to a (void *), if on a platform where the socketfd
* is an int, recover portably using (lws_sockfd_type)(intptr_t)in.
*
* It's also called in SOCKS5 or http_proxy cases where the socketfd is
* going to try to connect to its proxy.
*/
/* ---------------------------------------------------------------------
* ----- Callbacks related to TLS certificate management -----
*/
LWS_CALLBACK_VHOST_CERT_AGING = 72,
/**< When a vhost TLS cert has its expiry checked, this callback
* is broadcast to every protocol of every vhost in case the
* protocol wants to take some action with this information.
* \p in is a pointer to a struct lws_acme_cert_aging_args,
* and \p len is the number of days left before it expires, as
* a (ssize_t). In the struct lws_acme_cert_aging_args, vh
* points to the vhost the cert aging information applies to,
* and element_overrides[] is an optional way to update information
* from the pvos... NULL in an index means use the information from
* from the pvo for the cert renewal, non-NULL in the array index
* means use that pointer instead for the index. */
LWS_CALLBACK_VHOST_CERT_UPDATE = 74,
/**< When a vhost TLS cert is being updated, progress is
* reported to the vhost in question here, including completion
* and failure. in points to optional JSON, and len represents the
* connection state using enum lws_cert_update_state */
/* ---------------------------------------------------------------------
* ----- Callbacks related to MQTT Client -----
*/
LWS_CALLBACK_MQTT_NEW_CLIENT_INSTANTIATED = 200,
LWS_CALLBACK_MQTT_IDLE = 201,
LWS_CALLBACK_MQTT_CLIENT_ESTABLISHED = 202,
LWS_CALLBACK_MQTT_SUBSCRIBED = 203,
LWS_CALLBACK_MQTT_CLIENT_WRITEABLE = 204,
LWS_CALLBACK_MQTT_CLIENT_RX = 205,
LWS_CALLBACK_MQTT_UNSUBSCRIBED = 206,
LWS_CALLBACK_MQTT_DROP_PROTOCOL = 207,
LWS_CALLBACK_MQTT_CLIENT_CLOSED = 208,
LWS_CALLBACK_MQTT_ACK = 209,
/**< When a message is fully sent, if QoS0 this callback is generated
* to locally "acknowledge" it. For QoS1, this callback is only
* generated when the matching PUBACK is received. Return nonzero to
* close the wsi.
*/
LWS_CALLBACK_MQTT_RESEND = 210,
/**< In QoS1 or QoS2, this callback is generated instead of the _ACK one
* if we timed out waiting for a PUBACK or a PUBREC, and we must resend
* the message. Return nonzero to close the wsi.
*/
LWS_CALLBACK_MQTT_UNSUBSCRIBE_TIMEOUT = 211,
/**< When a UNSUBSCRIBE is sent, this callback is generated instead of
* the _UNSUBSCRIBED one if we timed out waiting for a UNSUBACK.
* Return nonzero to close the wsi.
*/
/****** add new things just above ---^ ******/
LWS_CALLBACK_USER = 1000,
/**< user code can use any including above without fear of clashes */
};
/**
* typedef lws_callback_function() - User server actions
* \param wsi: Opaque websocket instance pointer
* \param reason: The reason for the call
* \param user: Pointer to per-session user data allocated by library
* \param in: Pointer used for some callback reasons
* \param len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with lws_create_server.
*/
typedef int
lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len);
#define LWS_CB_REASON_AUX_BF__CGI 1
#define LWS_CB_REASON_AUX_BF__PROXY 2
#define LWS_CB_REASON_AUX_BF__CGI_CHUNK_END 4
#define LWS_CB_REASON_AUX_BF__CGI_HEADERS 8
#define LWS_CB_REASON_AUX_BF__PROXY_TRANS_END 16
#define LWS_CB_REASON_AUX_BF__PROXY_HEADERS 32
///@}

View File

@ -0,0 +1,104 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup cgi cgi handling
*
* ##CGI handling
*
* These functions allow low-level control over stdin/out/err of the cgi.
*
* However for most cases, binding the cgi to http in and out, the default
* lws implementation already does the right thing.
*/
enum lws_enum_stdinouterr {
LWS_STDIN = 0,
LWS_STDOUT = 1,
LWS_STDERR = 2,
};
enum lws_cgi_hdr_state {
LCHS_HEADER,
LCHS_CR1,
LCHS_LF1,
LCHS_CR2,
LCHS_LF2,
LHCS_RESPONSE,
LHCS_DUMP_HEADERS,
LHCS_PAYLOAD,
LCHS_SINGLE_0A,
};
struct lws_cgi_args {
struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */
enum lws_enum_stdinouterr ch; /**< channel index */
unsigned char *data; /**< for messages with payload */
enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi headers */
int len; /**< length */
};
#ifdef LWS_WITH_CGI
/**
* lws_cgi: spawn network-connected cgi process
*
* \param wsi: connection to own the process
* \param exec_array: array of "exec-name" "arg1" ... "argn" NULL
* \param script_uri_path_len: how many chars on the left of the uri are the
* path to the cgi, or -1 to spawn without URL-related env vars
* \param timeout_secs: seconds script should be allowed to run
* \param mp_cgienv: pvo list with per-vhost cgi options to put in env
*/
LWS_VISIBLE LWS_EXTERN int
lws_cgi(struct lws *wsi, const char * const *exec_array,
int script_uri_path_len, int timeout_secs,
const struct lws_protocol_vhost_options *mp_cgienv);
/**
* lws_cgi_write_split_stdout_headers: write cgi output accounting for header part
*
* \param wsi: connection to own the process
*/
LWS_VISIBLE LWS_EXTERN int
lws_cgi_write_split_stdout_headers(struct lws *wsi);
/**
* lws_cgi_kill: terminate cgi process associated with wsi
*
* \param wsi: connection to own the process
*/
LWS_VISIBLE LWS_EXTERN int
lws_cgi_kill(struct lws *wsi);
/**
* lws_cgi_get_stdwsi: get wsi for stdin, stdout, or stderr
*
* \param wsi: parent wsi that has cgi
* \param ch: which of LWS_STDIN, LWS_STDOUT or LWS_STDERR
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_cgi_get_stdwsi(struct lws *wsi, enum lws_enum_stdinouterr ch);
#endif
///@}

View File

@ -0,0 +1,411 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup client Client related functions
* ##Client releated functions
* \ingroup lwsapi
*
* */
///@{
/** enum lws_client_connect_ssl_connection_flags - flags that may be used
* with struct lws_client_connect_info ssl_connection member to control if
* and how SSL checks apply to the client connection being created
*/
enum lws_client_connect_ssl_connection_flags {
LCCSCF_USE_SSL = (1 << 0),
LCCSCF_ALLOW_SELFSIGNED = (1 << 1),
LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK = (1 << 2),
LCCSCF_ALLOW_EXPIRED = (1 << 3),
LCCSCF_ALLOW_INSECURE = (1 << 4),
LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM = (1 << 5),
LCCSCF_H2_QUIRK_OVERFLOWS_TXCR = (1 << 6),
LCCSCF_H2_AUTH_BEARER = (1 << 7),
LCCSCF_H2_HEXIFY_AUTH_TOKEN = (1 << 8),
LCCSCF_H2_MANUAL_RXFLOW = (1 << 9),
LCCSCF_HTTP_MULTIPART_MIME = (1 << 10),
LCCSCF_HTTP_X_WWW_FORM_URLENCODED = (1 << 11),
LCCSCF_HTTP_NO_FOLLOW_REDIRECT = (1 << 12),
LCCSCF_PIPELINE = (1 << 16),
/**< Serialize / pipeline multiple client connections
* on a single connection where possible.
*
* HTTP/1.0: possible if Keep-Alive: yes sent by server
* HTTP/1.1: always possible... uses pipelining
* HTTP/2: always possible... uses parallel streams
*/
LCCSCF_MUXABLE_STREAM = (1 << 17),
LCCSCF_H2_PRIOR_KNOWLEDGE = (1 << 18),
LCCSCF_WAKE_SUSPEND__VALIDITY = (1 << 19),
/* our validity checks are important enough to wake from suspend */
LCCSCF_PRIORITIZE_READS = (1 << 20),
/**<
* Normally lws balances reads and writes on all connections, so both
* are possible even on busy connections, and we go around the event
* loop more often to facilitate that, even if there is pending data.
*
* This flag indicates that you want to handle any pending reads on this
* connection without yielding the service loop for anything else. This
* means you may block other connection processing in favour of incoming
* data processing on this one if it receives back to back incoming rx.
*/
LCCSCF_SECSTREAM_CLIENT = (1 << 21),
/**< used to mark client wsi as bound to secure stream */
LCCSCF_SECSTREAM_PROXY_LINK = (1 << 22),
/**< client is a link between SS client and SS proxy */
LCCSCF_SECSTREAM_PROXY_ONWARD = (1 << 23),
/**< client the SS proxy's onward connection */
LCCSCF_IP_LOW_LATENCY = (1 << 24),
/**< set the "low delay" bit on the IP packets of this connection */
LCCSCF_IP_HIGH_THROUGHPUT = (1 << 25),
/**< set the "high throughput" bit on the IP packets of this
* connection */
LCCSCF_IP_HIGH_RELIABILITY = (1 << 26),
/**< set the "high reliability" bit on the IP packets of this
* connection */
LCCSCF_IP_LOW_COST = (1 << 27),
/**< set the "minimize monetary cost" bit on the IP packets of this
* connection */
LCCSCF_CONMON = (1 << 28),
/**< If LWS_WITH_CONMON enabled for build, keeps a copy of the
* getaddrinfo results so they can be queried subsequently */
LCCSCF_ACCEPT_TLS_DOWNGRADE_REDIRECTS = (1 << 29),
/**< By default lws rejects https redirecting to http. Set this
* flag on the client connection to allow it. */
LCCSCF_CACHE_COOKIES = (1 << 30),
/**< If built with -DLWS_WITH_CACHE_NSCOOKIEJAR, store and reapply
* http cookies in a Netscape Cookie Jar on this connection */
};
/** struct lws_client_connect_info - parameters to connect with when using
* lws_client_connect_via_info() */
struct lws_client_connect_info {
struct lws_context *context;
/**< lws context to create connection in */
const char *address;
/**< remote address to connect to */
int port;
/**< remote port to connect to */
int ssl_connection;
/**< 0, or a combination of LCCSCF_ flags */
const char *path;
/**< uri path */
const char *host;
/**< content of host header */
const char *origin;
/**< content of origin header */
const char *protocol;
/**< list of ws protocols we could accept */
int ietf_version_or_minus_one;
/**< deprecated: currently leave at 0 or -1 */
void *userdata;
/**< if non-NULL, use this as wsi user_data instead of malloc it */
const void *client_exts;
/**< UNUSED... provide in info.extensions at context creation time */
const char *method;
/**< if non-NULL, do this http method instead of ws[s] upgrade.
* use "GET" to be a simple http client connection. "RAW" gets
* you a connected socket that lws itself will leave alone once
* connected. */
struct lws *parent_wsi;
/**< if another wsi is responsible for this connection, give it here.
* this is used to make sure if the parent closes so do any
* child connections first. */
const char *uri_replace_from;
/**< if non-NULL, when this string is found in URIs in
* text/html content-encoding, it's replaced with uri_replace_to */
const char *uri_replace_to;
/**< see uri_replace_from */
struct lws_vhost *vhost;
/**< vhost to bind to (used to determine related SSL_CTX) */
struct lws **pwsi;
/**< if not NULL, store the new wsi here early in the connection
* process. Although we return the new wsi, the call to create the
* client connection does progress the connection somewhat and may
* meet an error that will result in the connection being scrubbed and
* NULL returned. While the wsi exists though, he may process a
* callback like CLIENT_CONNECTION_ERROR with his wsi: this gives the
* user callback a way to identify which wsi it is that faced the error
* even before the new wsi is returned and even if ultimately no wsi
* is returned.
*/
const char *iface;
/**< NULL to allow routing on any interface, or interface name or IP
* to bind the socket to */
const char *local_protocol_name;
/**< NULL: .protocol is used both to select the local protocol handler
* to bind to and as the list of remote ws protocols we could
* accept.
* non-NULL: this protocol name is used to bind the connection to
* the local protocol handler. .protocol is used for the
* list of remote ws protocols we could accept */
const char *alpn;
/**< NULL: allow lws default ALPN list, from vhost if present or from
* list of roles built into lws
* non-NULL: require one from provided comma-separated list of alpn
* tokens
*/
struct lws_sequencer *seq;
/**< NULL, or an lws_seq_t that wants to be given messages about
* this wsi's lifecycle as it connects, errors or closes.
*/
void *opaque_user_data;
/**< This data has no meaning to lws but is applied to the client wsi
* and can be retrieved by user code with lws_get_opaque_user_data().
* It's also provided with sequencer messages if the wsi is bound to
* an lws_seq_t.
*/
const lws_retry_bo_t *retry_and_idle_policy;
/**< optional retry and idle policy to apply to this connection.
* Currently only the idle parts are applied to the connection.
*/
int manual_initial_tx_credit;
/**< if LCCSCF_H2_MANUAL_REFLOW is set, this becomes the initial tx
* credit for the stream.
*/
uint8_t sys_tls_client_cert;
/**< 0 means no client cert. 1+ means apply lws_system client cert 0+
* to the client connection.
*/
uint8_t priority;
/**< 0 means normal priority... otherwise sets the IP priority on
* packets coming from this connection, from 1 - 7. Setting 7
* (network management priority) requires CAP_NET_ADMIN capability but
* the others can be set by anyone.
*/
#if defined(LWS_ROLE_MQTT)
const lws_mqtt_client_connect_param_t *mqtt_cp;
#else
void *mqtt_cp;
#endif
#if defined(LWS_WITH_SYS_FAULT_INJECTION)
lws_fi_ctx_t fic;
/**< Attach external Fault Injection context to the client wsi,
* hierarchy is wsi -> vhost -> context */
#endif
/* for convenience, available when FI disabled in build */
const char *fi_wsi_name;
/**< specific Fault Injection namespace name for wsi created for this
* connection, allows targeting by "wsi=XXX/..." if you give XXX here.
*/
uint16_t keep_warm_secs;
/**< 0 means 5s. If the client connection to the endpoint becomes idle,
* defer closing it for this many seconds in case another outgoing
* connection to the same endpoint turns up.
*/
lws_log_cx_t *log_cx;
/**< NULL to use lws_context log context, else a pointer to a log
* context template to take a copy of for this wsi. Used to isolate
* wsi-specific logs into their own stream or file.
*/
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility
*
* The below is to ensure later library versions with new
* members added above will see 0 (default) even if the app
* was not built against the newer headers.
*/
void *_unused[4]; /**< dummy */
};
/**
* lws_client_connect_via_info() - Connect to another websocket server
* \param ccinfo: pointer to lws_client_connect_info struct
*
* This function creates a connection to a remote server using the
* information provided in ccinfo.
*/
LWS_VISIBLE LWS_EXTERN struct lws *
lws_client_connect_via_info(const struct lws_client_connect_info *ccinfo);
/**
* lws_init_vhost_client_ssl() - also enable client SSL on an existing vhost
*
* \param info: client ssl related info
* \param vhost: which vhost to initialize client ssl operations on
*
* You only need to call this if you plan on using SSL client connections on
* the vhost. For non-SSL client connections, it's not necessary to call this.
*
* The following members of info are used during the call
*
* - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set,
* otherwise the call does nothing
* - provided_client_ssl_ctx must be NULL to get a generated client
* ssl context, otherwise you can pass a prepared one in by setting it
* - ssl_cipher_list may be NULL or set to the client valid cipher list
* - ssl_ca_filepath may be NULL or client cert filepath
* - ssl_cert_filepath may be NULL or client cert filepath
* - ssl_private_key_filepath may be NULL or client cert private key
*
* You must create your vhost explicitly if you want to use this, so you have
* a pointer to the vhost. Create the context first with the option flag
* LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with
* the same info struct.
*/
LWS_VISIBLE LWS_EXTERN int
lws_init_vhost_client_ssl(const struct lws_context_creation_info *info,
struct lws_vhost *vhost);
/**
* lws_http_client_read() - consume waiting received http client data
*
* \param wsi: client connection
* \param buf: pointer to buffer pointer - fill with pointer to your buffer
* \param len: pointer to chunk length - fill with max length of buffer
*
* This is called when the user code is notified client http data has arrived.
* The user code may choose to delay calling it to consume the data, for example
* waiting until an onward connection is writeable.
*
* For non-chunked connections, up to len bytes of buf are filled with the
* received content. len is set to the actual amount filled before return.
*
* For chunked connections, the linear buffer content contains the chunking
* headers and it cannot be passed in one lump. Instead, this function will
* call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the
* chunk start and len set to the chunk length. There will be as many calls
* as there are chunks or partial chunks in the buffer.
*/
LWS_VISIBLE LWS_EXTERN int
lws_http_client_read(struct lws *wsi, char **buf, int *len);
/**
* lws_http_client_http_response() - get last HTTP response code
*
* \param wsi: client connection
*
* Returns the last server response code, eg, 200 for client http connections.
*
* You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP
* callback, because after that the memory reserved for storing the related
* headers is freed and this value is lost.
*/
LWS_VISIBLE LWS_EXTERN unsigned int
lws_http_client_http_response(struct lws *wsi);
/**
* lws_tls_client_vhost_extra_cert_mem() - add more certs to vh client tls ctx
*
* \param vh: the vhost to give more client certs to
* \param der: pointer to der format additional cert
* \param der_len: size in bytes of der
*
* After the vhost is created with one cert for client verification, you
* can add additional, eg, intermediate, certs to the client tls context
* of the vhost, for use with validating the incoming server cert(s).
*/
LWS_VISIBLE LWS_EXTERN int
lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh,
const uint8_t *der, size_t der_len);
/**
* lws_client_http_body_pending() - control if client connection needs to send body
*
* \param wsi: client connection
* \param something_left_to_send: nonzero if need to send more body, 0 (default)
* if nothing more to send
*
* If you will send payload data with your HTTP client connection, eg, for POST,
* when you set the related http headers in
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call
* this API with something_left_to_send nonzero, and call
* lws_callback_on_writable(wsi);
*
* After sending the headers, lws will call your callback with
* LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send the
* next part of the http body payload, calling lws_callback_on_writable(wsi);
* if there is more to come, or lws_client_http_body_pending(wsi, 0); to
* let lws know the last part is sent and the connection can move on.
*/
LWS_VISIBLE LWS_EXTERN void
lws_client_http_body_pending(struct lws *wsi, int something_left_to_send);
/**
* lws_client_http_multipart() - issue appropriate multipart header or trailer
*
* \param wsi: client connection
* \param name: multipart header name field, or NULL if end of multipart
* \param filename: multipart header filename field, or NULL if none
* \param content_type: multipart header content-type part, or NULL if none
* \param p: pointer to position in buffer
* \param end: end of buffer
*
* This issues a multipart mime boundary, or terminator if name = NULL.
*
* Returns 0 if OK or nonzero if couldn't fit in buffer
*/
LWS_VISIBLE LWS_EXTERN int
lws_client_http_multipart(struct lws *wsi, const char *name,
const char *filename, const char *content_type,
char **p, char *end);
/**
* lws_http_basic_auth_gen() - helper to encode client basic auth string
*
* \param user: user name
* \param pw: password
* \param buf: where to store base64 result
* \param len: max usable size of buf
*
* Encodes a username and password in Basic Auth format for use with the
* Authorization header. On return, buf is filled with something like
* "Basic QWxhZGRpbjpPcGVuU2VzYW1l".
*/
LWS_VISIBLE LWS_EXTERN int
lws_http_basic_auth_gen(const char *user, const char *pw, char *buf, size_t len);
/**
* lws_tls_session_is_reused() - returns nonzero if tls session was cached
*
* \param wsi: the wsi
*
* Returns zero if the tls session is fresh, else nonzero if the tls session was
* taken from the cache. If lws is built with LWS_WITH_TLS_SESSIONS and the vhost
* was created with the option LWS_SERVER_OPTION_ENABLE_TLS_SESSION_CACHE, then
* on full tls session establishment of a client connection, the session is added
* to the tls cache.
*
* This lets you find out if your session was new (0) or from the cache (nonzero),
* it'a mainly useful for stats and testing.
*/
LWS_VISIBLE LWS_EXTERN int
lws_tls_session_is_reused(struct lws *wsi);
///@}

View File

@ -0,0 +1,155 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup conmon Connection Latency information
* ## Connection Latency information
*
* When LWS_WITH_CONMON is enabled at build, collects detailed statistics
* about the client connection setup latency, available to the connection
* itself
*/
///@{
/* enough for 4191s, or just over an hour */
typedef uint32_t lws_conmon_interval_us_t;
/*
* Connection latency information... note that not all wsi actually make
* connections, for example h2 streams after the initial one will have 0
* for everything except ciu_txn_resp.
*
* If represented in JSON, it should look like this
*
* {
* "peer": "46.105.127.147",
* "dns_us": 1234,
* "dns_disp": 1,
* "sockconn_us": 1234,
* "tls_us": 1234,
* "txn_resp_us": 1234,
* "dns":["46.105.127.147", "2001:41d0:2:ee93::1"],
* "prot_specific": {
* "protocol": "http",
* "resp": 200
* }
* }
*
* The indexes in "dns_disp" are declared in lws_conmon_dns_disposition_t
* below.
*
* "prot_specific" may not be present if the protocol doesn't have anything
* to report or is not supported.
*/
typedef enum lws_conmon_pcol {
LWSCONMON_PCOL_NONE,
LWSCONMON_PCOL_HTTP, /* .protocol_specific.http is valid */
} lws_conmon_pcol_t;
typedef enum lws_conmon_dns_disposition {
LWSCONMON_DNS_NONE,
/**< did not attempt DNS */
LWSCONMON_DNS_OK = 1,
/**< DNS lookup did give results */
LWSCONMON_DNS_SERVER_UNREACHABLE = 2,
/**< DNS server was not reachable */
LWSCONMON_DNS_NO_RESULT = 3
/**< DNS server replied but nothing usable */
} lws_conmon_dns_disposition_t;
struct lws_conmon {
lws_sockaddr46 peer46;
/**< The peer we actually connected to, if any. .peer46.sa4.sa_family
* is either 0 if invalid, or the AF_ */
union {
struct {
int response;
/**< h1 http response code */
} http;
} protocol_specific;
/**< possibly-present protocol-specific additional information. This
* is only valid for the first transaction after connection and does
* not capture results for persistent or muxed connections like ws
* messages, mqtt messages, or h2 streams */
struct addrinfo *dns_results_copy;
/**< NULL, or Allocated copy of dns results, owned by this object and
* freed when object destroyed.
* Only set if client flag LCCSCF_CONMON applied */
lws_conmon_interval_us_t ciu_dns;
/**< 0, or if a socket connection, us taken to acquire this DNS response
*
*/
lws_conmon_interval_us_t ciu_sockconn;
/**< 0, or if connection-based, the us interval between the socket
* connect() attempt that succeeded, and the connection setup */
lws_conmon_interval_us_t ciu_tls;
/**< 0 if no tls, or us taken to establish the tls tunnel */
lws_conmon_interval_us_t ciu_txn_resp;
/**< 0, or if the protocol supports transactions, the interval between
* sending the initial transaction request and starting to receive the
* response */
lws_conmon_pcol_t pcol;
/**< indicates which extra protocol_specific info member is valid,
* if any */
lws_conmon_dns_disposition_t dns_disposition;
/**< indicates general disposition of DNS request */
};
/**
* lws_conmon_wsi_take() - create a connection latency object from client wsi
*
* \param context: lws wsi
* \param dest: conmon struct to fill
*
* Copies wsi conmon data into the caller's struct. Passes ownership of
* any allocations in the addrinfo list to the caller, lws will not delete that
* any more on wsi close after this call. The caller must call
* lws_conmon_release() on the struct to destroy any addrinfo in the struct
* that is prepared by this eventually but it can defer it as long as it wants.
*
* Other than the addrinfo list, the contents of the returned object are
* completely selfcontained and don't point outside of the object itself, ie,
* everything else in there remains in scope while the object itself does.
*/
LWS_VISIBLE LWS_EXTERN void
lws_conmon_wsi_take(struct lws *wsi, struct lws_conmon *dest);
/**
* lws_conmon_release() - free any allocations in the conmon struct
*
* \param conmon: pointer to conmon struct
*
* Destroys any allocations in the conmon struct so it can go out of scope.
* It doesn't free \p dest itself, it's designed to clean out a struct that
* is on the stack or embedded in another object.
*/
LWS_VISIBLE LWS_EXTERN void
lws_conmon_release(struct lws_conmon *conmon);
///@}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,511 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup cose COSE apis
* ##COSE related functions
* \ingroup lwsaoi
*
* COSE RFC 8152 relates to signed and encrypted CBOR
*/
//@{
enum {
/* RFC8152: Table 2: Common Header Parameters
* https://www.iana.org/assignments/cose/cose.xhtml#header-parameters
*/
LWSCOSE_WKL_ALG = 1, /* int / tstr */
LWSCOSE_WKL_CRIT, /* [+ label ] */
LWSCOSE_WKL_CONTENT_TYPE, /* tstr / uint */
LWSCOSE_WKL_KID, /* bstr */
LWSCOSE_WKL_IV, /* bstr */
LWSCOSE_WKL_IV_PARTIAL, /* bstr */
LWSCOSE_WKL_COUNTERSIG, /* COSE sig(s) */
LWSCOSE_WKL_COUNTERSIG0 = 9, /* bstr */
LWSCOSE_WKL_KID_CONTEXT, /* bstr */
LWSCOSE_WKL_CUPH_NONCE = 256, /* bstr */
LWSCOSE_WKL_CUPH_OWNER_PUBKEY = 257, /* array */
/* RFC8152: Table 3: key map labels */
LWSCOSE_WKK_KTY = 1, /* int / tstr */
LWSCOSE_WKK_KID, /* bstr */
LWSCOSE_WKK_ALG, /* int / tstr */
LWSCOSE_WKK_KEY_OPS, /* [ + (int / tstr) ] */
LWSCOSE_WKK_BASE_IV, /* bstr */
/* RFC8152: Table 4: Key Operation Values */
LWSCOSE_WKKO_SIGN = 1,
LWSCOSE_WKKO_VERIFY,
LWSCOSE_WKKO_ENCRYPT,
LWSCOSE_WKKO_DECRYPT,
LWSCOSE_WKKO_WRAP_KEY,
LWSCOSE_WKKO_UNWRAP_KEY,
LWSCOSE_WKKO_DERIVE_KEY,
LWSCOSE_WKKO_DERIVE_BITS,
LWSCOSE_WKKO_MAC_CREATE,
LWSCOSE_WKKO_MAC_VERIFY,
/* RFC8152: Table 5: ECDSA algs */
LWSCOSE_WKAECDSA_ALG_ES256 = -7,
LWSCOSE_WKAECDSA_ALG_ES384 = -35,
LWSCOSE_WKAECDSA_ALG_ES512 = -36,
/* RFC8152: Table 6: EDDSA algs */
LWSCOSE_WKAEDDSA_ALG_EDDSA = -8,
/* RFC8152: Table 7: HMAC algs */
LWSCOSE_WKAHMAC_256_64 = 4,
LWSCOSE_WKAHMAC_256_256,
LWSCOSE_WKAHMAC_384_384,
LWSCOSE_WKAHMAC_512_512,
/* RFC8152: Table 8: AES algs */
LWSCOSE_WKAAES_128_64 = 14,
LWSCOSE_WKAAES_256_64,
LWSCOSE_WKAAES_128_128 = 25,
LWSCOSE_WKAAES_256_128,
/* RFC8152: Table 9: AES GCM algs */
LWSCOSE_WKAAESGCM_128 = 1,
LWSCOSE_WKAAESGCM_192,
LWSCOSE_WKAAESGCM_256,
/* RFC8152: Table 10: AES CCM algs */
LWSCOSE_WKAAESCCM_16_64_128 = 10,
LWSCOSE_WKAAESCCM_16_64_256,
LWSCOSE_WKAAESCCM_64_64_128,
LWSCOSE_WKAAESCCM_64_64_256,
LWSCOSE_WKAAESCCM_16_128_128,
LWSCOSE_WKAAESCCM_16_128_256,
LWSCOSE_WKAAESCCM_64_128_128,
LWSCOSE_WKAAESCCM_64_128_256,
/* RFC8152: Table 11: CHACHA20 / Poly1305 */
LWSCOSE_WKACHACHA_POLY1305 = 24,
/* RFC8152: Table 13: HKDF param */
LWSCOSE_WKAPHKDF_SALT = -20,
/* RFC8152: Table 14: Context Algorithm Parameters */
LWSCOSE_WKAPCTX_PARTY_U_IDENTITY = -21,
LWSCOSE_WKAPCTX_PARTY_U_NONCE = -22,
LWSCOSE_WKAPCTX_PARTY_U_OTHER = -23,
LWSCOSE_WKAPCTX_PARTY_V_IDENTITY = -24,
LWSCOSE_WKAPCTX_PARTY_V_NONCE = -25,
LWSCOSE_WKAPCTX_PARTY_V_OTHER = -26,
/* RFC8152: Table 15: Direct key */
LWSCOSE_WKK_DIRECT_CEK = -6,
/* RFC8152: Table 16: Direct key with KDF */
LWSCOSE_WKK_DIRECT_HKDF_SHA_256 = -10,
LWSCOSE_WKK_DIRECT_HKDF_SHA_512 = -11,
LWSCOSE_WKK_DIRECT_HKDF_AES_128 = -12,
LWSCOSE_WKK_DIRECT_HKDF_AES_256 = -13,
/* RFC8152: Table 17: AES Key Wrap Algorithm Values */
LWSCOSE_WKK_DIRECT_HKDFKW_SHA_256 = -3,
LWSCOSE_WKK_DIRECT_HKDFKW_SHA_512 = -4,
LWSCOSE_WKK_DIRECT_HKDFKW_AES_128 = -5,
/* RFC8152: Table 18: ECDH Algorithm Values */
LWSCOSE_WKAECDH_ALG_ES_HKDF_256 = -25,
LWSCOSE_WKAECDH_ALG_ES_HKDF_512 = -26,
LWSCOSE_WKAECDH_ALG_SS_HKDF_256 = -27,
LWSCOSE_WKAECDH_ALG_SS_HKDF_512 = -28,
/* RFC8152: Table 19: ECDH Algorithm Parameters */
LWSCOSE_WKAPECDH_EPHEMERAL_KEY = -1,
LWSCOSE_WKAPECDH_STATIC_KEY = -2,
LWSCOSE_WKAPECDH_STATIC_KEY_ID = -3,
/* RFC8152: Table 20: ECDH Algorithm Parameters with key wrap */
LWSCOSE_WKAPECDH_ES_A128KW = -29,
LWSCOSE_WKAPECDH_ES_A192KW = -30,
LWSCOSE_WKAPECDH_ES_A256KW = -31,
LWSCOSE_WKAPECDH_SS_A128KW = -32,
LWSCOSE_WKAPECDH_SS_A192KW = -33,
LWSCOSE_WKAPECDH_SS_A256KW = -34,
/* RFC8152: Table 21: Key Type Values
* https://www.iana.org/assignments/cose/cose.xhtml#key-type
*/
LWSCOSE_WKKTV_OKP = 1,
LWSCOSE_WKKTV_EC2 = 2,
LWSCOSE_WKKTV_RSA = 3,
LWSCOSE_WKKTV_SYMMETRIC = 4,
LWSCOSE_WKKTV_HSS_LMS = 5,
LWSCOSE_WKKTV_WALNUTDSA = 6,
/* RFC8152: Table 22: Elliptic Curves
* https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
*/
LWSCOSE_WKEC_P256 = 1,
LWSCOSE_WKEC_P384,
LWSCOSE_WKEC_P521,
LWSCOSE_WKEC_X25519,
LWSCOSE_WKEC_X448,
LWSCOSE_WKEC_ED25519,
LWSCOSE_WKEC_ED448,
LWSCOSE_WKEC_SECP256K1,
/* RFC8152: Table 23: EC Key Parameters */
LWSCOSE_WKECKP_CRV = -1,
LWSCOSE_WKECKP_X = -2,
LWSCOSE_WKECKP_Y = -3,
LWSCOSE_WKECKP_D = -4,
/* RFC8152: Table 24: Octet Key Pair (OKP) Parameters */
LWSCOSE_WKOKP_CRV = -1,
LWSCOSE_WKOKP_X = -2,
LWSCOSE_WKOKP_D = -4,
/* Additional from
* https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
*/
LWSCOSE_WKKPRSA_N = -1,
LWSCOSE_WKKPRSA_E = -2,
LWSCOSE_WKKPRSA_D = -3,
LWSCOSE_WKKPRSA_P = -4,
LWSCOSE_WKKPRSA_Q = -5,
LWSCOSE_WKKPRSA_DP = -6,
LWSCOSE_WKKPRSA_DQ = -7,
LWSCOSE_WKKPRSA_QINV = -8,
LWSCOSE_WKKPRSA_OTHER = -9,
LWSCOSE_WKKPRSA_RI = -10,
LWSCOSE_WKKPRSA_DI = -11,
LWSCOSE_WKKPRSA_TI = -12,
/* RFC8152: Table 25: Symmetric Key Parameters */
LWSCOSE_WKSYMKP_KEY_VALUE = 4,
/* RFC8152: Table 26: CoAP Content-Formats for COSE */
LWSCOAP_CONTENTFORMAT_COSE_SIGN = 98,
LWSCOAP_CONTENTFORMAT_COSE_SIGN1 = 18,
LWSCOAP_CONTENTFORMAT_COSE_ENCRYPT = 96,
LWSCOAP_CONTENTFORMAT_COSE_ENCRYPT0 = 16,
LWSCOAP_CONTENTFORMAT_COSE_MAC = 97,
LWSCOAP_CONTENTFORMAT_COSE_MAC0 = 17,
LWSCOAP_CONTENTFORMAT_COSE_KEY = 101,
LWSCOAP_CONTENTFORMAT_COSE_KEY_SET = 102,
/* RFC8152: Table 27: Header Parameter for CounterSignature0 */
LWSCOSE_WKL_COUNTERSIGNATURE0 = 9, /* bstr */
/* RFC8812: Table 1: RSASSA-PKCS1-v1_5 Algorithm Values */
LWSCOSE_WKARSA_ALG_RS256 = -257, /* + SHA-256 */
LWSCOSE_WKARSA_ALG_RS384 = -258, /* + SHA-384 */
LWSCOSE_WKARSA_ALG_RS512 = -259, /* + SHA-512 */
};
enum enum_cose_key_meta_tok {
COSEKEY_META_KTY,
COSEKEY_META_KID,
COSEKEY_META_KEY_OPS,
COSEKEY_META_BASE_IV,
COSEKEY_META_ALG,
LWS_COUNT_COSE_KEY_ELEMENTS
};
typedef int64_t cose_param_t;
LWS_VISIBLE LWS_EXTERN const char *
lws_cose_alg_to_name(cose_param_t alg);
LWS_VISIBLE LWS_EXTERN cose_param_t
lws_cose_name_to_alg(const char *name);
/*
* cose_key
*/
typedef struct lws_cose_key {
/* key data elements */
struct lws_gencrypto_keyelem e[LWS_GENCRYPTO_MAX_KEYEL_COUNT];
/* generic meta key elements, like KID */
struct lws_gencrypto_keyelem meta[LWS_COUNT_COSE_KEY_ELEMENTS];
lws_dll2_t list; /* used when part of a set */
int gencrypto_kty; /**< one of LWS_GENCRYPTO_KTY_ */
cose_param_t kty;
cose_param_t cose_alg;
cose_param_t cose_curve;
char private_key; /* nonzero = has private key elements */
} lws_cose_key_t;
typedef int (*lws_cose_key_import_callback)(struct lws_cose_key *s, void *user);
/** lws_cose_jwk_import() - Create an lws_cose_key_t object from cose_key CBOR
*
* \param pkey_set: NULL, or a pointer to an lws_dll2_owner_t for a cose_key set
* \param cb: callback for each jwk-processed key, or NULL if importing a single
* key with no parent "keys" JSON
* \param user: pointer to be passed to the callback, otherwise ignored by lws.
* NULL if importing a single key with no parent "keys" JSON
* \param in: a single cose_key
* \param len: the length of the cose_key in bytes
*
* Creates a single lws_cose_key_t if \p pkey_set is NULL or if the incoming
* CBOR doesn't start with an array, otherwise expects a CBOR array containing
* zero or more cose_key CBOR, and adds each to the \p pkey_set
* lws_dll2_owner_t struct. Created lws_cose_key_t are filled with data from
* the COSE representation and can be used with other COSE crypto ops.
*/
LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
lws_cose_key_import(lws_dll2_owner_t *pkey_set, lws_cose_key_import_callback cb,
void *user, const uint8_t *in, size_t len);
/** lws_cose_key_export() - Create cose_key CBOR from an lws_cose_key_t
*
* \param ck: the lws_cose_key_t to export to CBOR
* \param ctx: the CBOR writing context (same as for lws_lec_printf())
* \param flags: 0 to export only public elements, or LWSJWKF_EXPORT_PRIVATE
*
* Creates an lws_jwk struct filled with data from the COSE representation.
*/
LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
lws_cose_key_export(lws_cose_key_t *ck, lws_lec_pctx_t *ctx, int flags);
/**
* lws_cose_key_generate() - generate a fresh key
*
* \param context: the lws_context used to get random
* \param cose_kty: one of LWSCOSE_WKKTV_ indicating the well-known key type
* \param use_mask: 0, or a bitfield where (1 << LWSCOSE_WKKO_...) set means valid for use
* \param bits: key bits for RSA
* \param curve: for EC keys, one of "P-256", "P-384" or "P-521" currently
* \param kid: string describing the key, or NULL
*
* Create an lws_cose_key_t of the specified type and return it
*/
LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
lws_cose_key_generate(struct lws_context *context, cose_param_t cose_kty,
int use_mask, int bits, const char *curve,
const uint8_t *kid, size_t kl);
LWS_VISIBLE LWS_EXTERN lws_cose_key_t *
lws_cose_key_from_set(lws_dll2_owner_t *set, const uint8_t *kid, size_t kl);
LWS_VISIBLE LWS_EXTERN void
lws_cose_key_destroy(lws_cose_key_t **ck);
LWS_VISIBLE LWS_EXTERN void
lws_cose_key_set_destroy(lws_dll2_owner_t *o);
/* only available in _DEBUG build */
LWS_VISIBLE LWS_EXTERN void
lws_cose_key_dump(const lws_cose_key_t *ck);
/*
* cose_sign
*/
struct lws_cose_validate_context;
enum lws_cose_sig_types {
SIGTYPE_UNKNOWN,
SIGTYPE_MULTI,
SIGTYPE_SINGLE,
SIGTYPE_COUNTERSIGNED, /* not yet supported */
SIGTYPE_MAC, /* only supported for validation */
SIGTYPE_MAC0,
};
/* a list of these result objects is the output of the validation process */
typedef struct {
lws_dll2_t list;
const lws_cose_key_t *cose_key;
cose_param_t cose_alg;
int result; /* 0 = validated */
} lws_cose_validate_res_t;
enum {
LCOSESIGEXTCB_RET_FINISHED,
LCOSESIGEXTCB_RET_AGAIN,
LCOSESIGEXTCB_RET_ERROR = -1
};
typedef struct {
struct lws_cose_validate_context *cps;
const uint8_t *ext;
size_t xl;
} lws_cose_sig_ext_pay_t;
typedef int (*lws_cose_sign_ext_pay_cb_t)(lws_cose_sig_ext_pay_t *x);
typedef int (*lws_cose_validate_pay_cb_t)(struct lws_cose_validate_context *cps,
void *opaque, const uint8_t *paychunk,
size_t paychunk_len);
typedef struct lws_cose_validate_create_info {
struct lws_context *cx;
/**< REQUIRED: the lws context */
lws_dll2_owner_t *keyset;
/**< REQUIRED: one or more cose_keys */
enum lws_cose_sig_types sigtype;
/**< 0 if a CBOR tag is in the sig, else one of SIGTYPE_MULTI,
* SIGTYPE_SINGLE, etc*/
lws_cose_validate_pay_cb_t pay_cb;
/**< optional: called back with unvalidated payload pieces */
void *pay_opaque;
/**< optional: passed into pay_cb callback along with payload chunk */
lws_cose_sign_ext_pay_cb_t ext_cb;
/**< optional extra application data provision callback */
void *ext_opaque;
/**< optional extra application data provision callback opaque */
size_t ext_len;
/**< if we have extra app data, this must be set to the length of it */
} lws_cose_validate_create_info_t;
/**
* lws_cose_validate_create() - create a signature validation context
*
* \param info: struct describing the validation context to create
*
* Creates a signature validation context set up as described in \p info.
*
* You can then pass the signature cbor chunks to it using
* lws_cose_validate_chunk(), finialize and get the results list using
* lws_cose_validate_results() and destroy with lws_cose_validate_destroy().
*/
LWS_VISIBLE LWS_EXTERN struct lws_cose_validate_context *
lws_cose_validate_create(const lws_cose_validate_create_info_t *info);
/**
* lws_cose_validate_chunk() - passes chunks of CBOR into the signature validator
*
* \param cps: the validation context
* \param in: the chunk of CBOR (does not have to be logically complete)
* \param in_len: number of bytes available at \p in
*
* Parses signature CBOR to produce a list of result objects.
*
*
*/
LWS_VISIBLE LWS_EXTERN int
lws_cose_validate_chunk(struct lws_cose_validate_context *cps,
const uint8_t *in, size_t in_len, size_t *used_in);
LWS_VISIBLE LWS_EXTERN lws_dll2_owner_t *
lws_cose_validate_results(struct lws_cose_validate_context *cps);
LWS_VISIBLE LWS_EXTERN void
lws_cose_validate_destroy(struct lws_cose_validate_context **cps);
struct lws_cose_sign_context;
#define LCSC_FL_ADD_CBOR_TAG (1 << 0)
#define LCSC_FL_ADD_CBOR_PREFER_MAC0 (1 << 1)
typedef struct lws_cose_sign_create_info {
struct lws_context *cx;
/**< REQUIRED: the lws context */
lws_dll2_owner_t *keyset;
/**< REQUIRED: one or more cose_keys */
lws_lec_pctx_t *lec;
/**< REQUIRED: the cbor output context to emit to, user must
* initialize with lws_lec_init() beforehand */
lws_cose_sign_ext_pay_cb_t ext_cb;
/**< optional extra application data provision callback */
void *ext_opaque;
/**< optional extra application data provision callback opaque */
size_t ext_len;
/**< if we have extra app data, this must be set to the length of it */
size_t inline_payload_len;
/**< REQUIRED: size of the inline payload we will provide */
int flags;
/**< bitmap of LCSC_FL_* */
enum lws_cose_sig_types sigtype;
/**< 0, or sign type hint */
} lws_cose_sign_create_info_t;
/**
* lws_cose_sign_create() - Create a signing context
*
* \param info: a structure describing the signing context you want to create
*
* This allocates and returns a signing context created according to what is in
* the \p info parameter.
*
* \p info must be prepared with the lws_context, a keyset to use, a CBOR
* output context, and the inline payload length.
*
* Returns NULL on failure or the created signing context ready to add alg(s)
* to.
*/
LWS_VISIBLE LWS_EXTERN struct lws_cose_sign_context *
lws_cose_sign_create(const lws_cose_sign_create_info_t *info);
LWS_VISIBLE LWS_EXTERN int
lws_cose_sign_add(struct lws_cose_sign_context *csc, cose_param_t alg,
const lws_cose_key_t *ck);
LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
lws_cose_sign_payload_chunk(struct lws_cose_sign_context *csc,
const uint8_t *in, size_t in_len);
LWS_VISIBLE LWS_EXTERN void
lws_cose_sign_destroy(struct lws_cose_sign_context **csc);
//@}

View File

@ -0,0 +1,94 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* must be included manually as
*
* #include <libwebsockets/lws-dbus.h>
*
* if dbus apis needed
*/
#if !defined(__LWS_DBUS_H__)
#define __LWS_DBUS_H__
#include <dbus/dbus.h>
/* helper type to simplify implementing methods as individual functions */
typedef DBusHandlerResult (*lws_dbus_message_handler)(DBusConnection *conn,
DBusMessage *message, DBusMessage **reply, void *d);
struct lws_dbus_ctx;
typedef void (*lws_dbus_closing_t)(struct lws_dbus_ctx *ctx);
struct lws_dbus_ctx {
struct lws_dll2_owner owner; /* dbusserver ctx: HEAD of accepted list */
struct lws_dll2 next; /* dbusserver ctx: HEAD of accepted list */
struct lws_vhost *vh; /* the vhost we logically bind to in lws */
int tsi; /* the lws thread service index (0 if only one service
thread as is the default */
DBusConnection *conn;
DBusServer *dbs;
DBusWatch *w[4];
DBusPendingCall *pc;
char hup;
char timeouts;
/* cb_closing callback will be called after the connection and this
* related ctx struct have effectively gone out of scope.
*
* The callback should close and clean up the connection and free the
* ctx.
*/
lws_dbus_closing_t cb_closing;
};
/**
* lws_dbus_connection_setup() - bind dbus connection object to lws event loop
*
* \param ctx: additional information about the connection
* \param conn: the DBusConnection object to bind
*
* This configures a DBusConnection object to use lws for watchers and timeout
* operations.
*/
LWS_VISIBLE LWS_EXTERN int
lws_dbus_connection_setup(struct lws_dbus_ctx *ctx, DBusConnection *conn,
lws_dbus_closing_t cb_closing);
/**
* lws_dbus_server_listen() - bind dbus connection object to lws event loop
*
* \param ctx: additional information about the connection
* \param ads: the DBUS address to listen on, eg, "unix:abstract=mysocket"
* \param err: a DBusError object to take any extra error information
* \param new_conn: a callback function to prepare new accepted connections
*
* This creates a DBusServer and binds it to the lws event loop, and your
* callback to accept new connections.
*/
LWS_VISIBLE LWS_EXTERN DBusServer *
lws_dbus_server_listen(struct lws_dbus_ctx *ctx, const char *ads,
DBusError *err, DBusNewConnectionFunction new_conn);
#endif

View File

@ -0,0 +1,187 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup diskcache LWS disk cache
* ## Disk cache API
*
* Lws provides helper apis useful if you need a disk cache containing hashed
* files and need to delete files from it on an LRU basis to keep it below some
* size limit.
*
* The API `lws_diskcache_prepare()` deals with creating the cache dir and
* 256 subdirs, which are used according to the first two chars of the hex
* hash of the cache file.
*
* `lws_diskcache_create()` and `lws_diskcache_destroy()` allocate and free
* an opaque struct that represents the disk cache.
*
* `lws_diskcache_trim()` should be called at eg, 1s intervals to perform the
* cache dir monitoring and LRU autodelete in the background lazily. It can
* be done in its own thread or on a timer... it monitors the directories in a
* stateful way that stats one or more file in the cache per call, and keeps
* a list of the oldest files as it goes. When it completes a scan, if the
* aggregate size is over the limit, it will delete oldest files first to try
* to keep it under the limit.
*
* The cache size monitoring is extremely efficient in time and memory even when
* the cache directory becomes huge.
*
* `lws_diskcache_query()` is used to determine if the file already exists in
* the cache, or if it must be created. If it must be created, then the file
* is opened using a temp name that must be converted to a findable name with
* `lws_diskcache_finalize_name()` when the generation of the file contents are
* complete. Aborted cached files that did not complete generation will be
* flushed by the LRU eventually. If the file already exists, it is 'touched'
* to make it new again and the fd returned.
*
*/
///@{
struct lws_diskcache_scan;
/**
* lws_diskcache_create() - creates an opaque struct representing the disk cache
*
* \param cache_dir_base: The cache dir path, eg `/var/cache/mycache`
* \param cache_size_limit: maximum size on disk the cache is allowed to use
*
* This returns an opaque `struct lws_diskcache_scan *` which represents the
* disk cache, the trim scanning state and so on. You should use
* `lws_diskcache_destroy()` to free it to destroy it.
*/
LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan *
lws_diskcache_create(const char *cache_dir_base, uint64_t cache_size_limit);
/**
* lws_diskcache_destroy() - destroys the pointer returned by ...create()
*
* \param lds: pointer to the pointer returned by lws_diskcache_create()
*
* Frees *lds and any allocations it did, and then sets *lds to NULL and
* returns.
*/
LWS_VISIBLE LWS_EXTERN void
lws_diskcache_destroy(struct lws_diskcache_scan **lds);
/**
* lws_diskcache_prepare() - ensures the cache dir structure exists on disk
*
* \param cache_base_dir: The cache dir path, eg `/var/cache/mycache`
* \param mode: octal dir mode to enforce, like 0700
* \param uid: uid the cache dir should belong to
*
* This should be called while your app is still privileged. It will create
* the cache directory structure on disk as necessary, enforce the given access
* mode on it and set the given uid as the owner. It won't make any trouble
* if the cache already exists.
*
* Typically the mode is 0700 and the owner is the user that your application
* will transition to use when it drops root privileges.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_prepare(const char *cache_base_dir, int mode, uid_t uid);
#define LWS_DISKCACHE_QUERY_NO_CACHE 0
#define LWS_DISKCACHE_QUERY_EXISTS 1
#define LWS_DISKCACHE_QUERY_CREATING 2
#define LWS_DISKCACHE_QUERY_ONGOING 3 /* something else is creating it */
/**
* lws_diskcache_query() - ensures the cache dir structure exists on disk
*
* \param lds: The opaque struct representing the disk cache
* \param is_bot: nonzero means the request is from a bot. Don't create new cache contents if so.
* \param hash_hex: hex string representation of the cache object hash
* \param _fd: pointer to the fd to be set
* \param cache: destination string to take the cache filepath
* \param cache_len: length of the buffer at `cache`
* \param extant_cache_len: pointer to a size_t to take any extant cached file size
*
* This function is called when you want to find if the hashed name already
* exists in the cache. The possibilities for the return value are
*
* - LWS_DISKCACHE_QUERY_NO_CACHE: It's not in the cache and you can't create
* it in the cache for whatever reason.
* - LWS_DISKCACHE_QUERY_EXISTS: It exists in the cache. It's open RDONLY and
* *_fd has been set to the file descriptor. *extant_cache_len has been set
* to the size of the cached file in bytes. cache has been set to the
* full filepath of the cached file. Closing _fd is your responsibility.
* - LWS_DISKCACHE_QUERY_CREATING: It didn't exist, but a temp file has been
* created in the cache and *_fd set to a file descriptor opened on it RDWR.
* You should create the contents, and call `lws_diskcache_finalize_name()`
* when it is done. Closing _fd is your responsibility.
* - LWS_DISKCACHE_QUERY_ONGOING: not returned by this api, but you may find it
* desirable to make a wrapper function which can handle another asynchronous
* process that is already creating the cached file. This can be used to
* indicate that situation externally... how to determine the same thing is
* already being generated is out of scope of this api.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_query(struct lws_diskcache_scan *lds, int is_bot,
const char *hash_hex, int *_fd, char *cache, int cache_len,
size_t *extant_cache_len);
/**
* lws_diskcache_query() - ensures the cache dir structure exists on disk
*
* \param cache: The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING
*
* This renames the cache file you are creating to its final name. It should
* be called on the temp name returned by `lws_diskcache_query()` if it gave a
* LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and
* closed it.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_finalize_name(char *cache);
/**
* lws_diskcache_trim() - performs one or more file checks in the cache for size management
*
* \param lds: The opaque object representing the cache
*
* This should be called periodically to statefully walk the cache on disk
* collecting the oldest files. When it has visited every file, if the cache
* is oversize it will delete the oldest files until it's back under size again.
*
* Each time it's called, it will look at one or more dir in the cache. If
* called when the cache is oversize, it increases the amount of work done each
* call until it is reduced again. Typically it will take 256 calls before it
* deletes anything, so if called once per second, it will delete files once
* every 4 minutes. Each call is very inexpensive both in memory and time.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_trim(struct lws_diskcache_scan *lds);
/**
* lws_diskcache_secs_to_idle() - see how long to idle before calling trim
*
* \param lds: The opaque object representing the cache
*
* If the cache is undersize, there's no need to monitor it immediately. This
* suggests how long to "sleep" before calling `lws_diskcache_trim()` again.
*/
LWS_VISIBLE LWS_EXTERN int
lws_diskcache_secs_to_idle(struct lws_diskcache_scan *lds);
///@}

View File

@ -0,0 +1,158 @@
/*
* lws abstract display
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if !defined(__LWS_DISPLAY_H__)
#define __LWS_DISPLAY_H__
#include <stdint.h>
typedef uint16_t lws_display_scalar;
/*
* This is embedded in the actual display implementation object at the top,
* so a pointer to this can be cast to a pointer to the implementation object
* by any code that is specific to how it was implemented.
*
* Notice for the backlight / display intensity we contain pwm_ops... these can
* be some other pwm_ops like existing gpio pwm ops, or handled in a customized
* way like set oled contrast. Either way, the pwm level is arrived at via a
* full set of lws_led_sequences capable of generic lws transitions
*/
typedef struct lws_display {
int (*init)(const struct lws_display *disp);
const lws_pwm_ops_t *bl_pwm_ops;
int (*contrast)(const struct lws_display *disp, uint8_t contrast);
int (*blit)(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h);
int (*power)(const struct lws_display *disp, int state);
const lws_led_sequence_def_t *bl_active;
const lws_led_sequence_def_t *bl_dim;
const lws_led_sequence_def_t *bl_transition;
void *variant;
int bl_index;
lws_display_scalar w;
/**< display surface width in pixels */
lws_display_scalar h;
/**< display surface height in pixels */
uint8_t latency_wake_ms;
/**< ms required after wake from sleep before display usable again...
* delay bringing up the backlight for this amount of time on wake.
* This is managed via a sul on the event loop, not blocking. */
} lws_display_t;
/*
* This contains dynamic data related to display state
*/
enum lws_display_controller_state {
LWSDISPS_OFF,
LWSDISPS_AUTODIMMED, /* is in pre- blanking static dim mode */
LWSDISPS_BECOMING_ACTIVE, /* waiting for wake latency before active */
LWSDISPS_ACTIVE, /* is active */
LWSDISPS_GOING_OFF /* dimming then off */
};
typedef struct lws_display_state {
lws_sorted_usec_list_t sul_autodim;
const lws_display_t *disp;
struct lws_context *ctx;
int autodim_ms;
int off_ms;
struct lws_led_state *bl_lcs;
lws_led_state_chs_t chs;
/* set of sequencer transition channels */
enum lws_display_controller_state state;
} lws_display_state_t;
/**
* lws_display_state_init() - initialize display states
*
* \param lds: the display state object
* \param ctx: the lws context
* \param autodim_ms: ms since last active report to dim display (<0 = never)
* \param off_ms: ms since dim to turn display off (<0 = never)
* \param bl_lcs: the led controller instance that has the backlight
* \param disp: generic display object we belong to
*
* This initializes a display's state, and sets up the optional screen auto-dim
* and blanking on inactive, and gradual brightness change timer.
*
* - auto-dim then off: set autodim to some ms and off_ms to some ms
* - auto-dim only: set autodim to some ms and off_ms to -1
* - off-only: set autodim to some ms and off_ms to 0
* - neither: set both autodim and off_ms to -1
*/
LWS_VISIBLE LWS_EXTERN void
lws_display_state_init(lws_display_state_t *lds, struct lws_context *ctx,
int autodim_ms, int off_ms, struct lws_led_state *bl_lcs,
const lws_display_t *disp);
/**
* lws_display_state_set_brightness() - gradually change the brightness
*
* \param lds: the display state we are changing
* \param target: the target brightness to transition to
*
* Adjusts the brightness gradually twoards the target at 20Hz
*/
LWS_VISIBLE LWS_EXTERN void
lws_display_state_set_brightness(lws_display_state_t *lds,
const lws_led_sequence_def_t *pwmseq);
/*
* lws_display_state_active() - inform the system the display is active
*
* \param lds: the display state we are marking as active
*
* Resets the auto-dim and auto-off timers and makes sure the display is on and
* at the active brightness level
*/
LWS_VISIBLE LWS_EXTERN void
lws_display_state_active(lws_display_state_t *lds);
/*
* lws_display_state_off() - turns off the related display
*
* \param lds: the display state we are turning off
*
* Turns the display to least power mode or completely off if possible.
* Disables the timers related to dimming and blanking.
*/
LWS_VISIBLE LWS_EXTERN void
lws_display_state_off(lws_display_state_t *lds);
#endif

View File

@ -0,0 +1,305 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup ll linked-lists
* ##Linked list apis
*
* simple single and doubly-linked lists
*/
///@{
/**
* lws_start_foreach_ll(): linkedlist iterator helper start
*
* \param type: type of iteration, eg, struct xyz *
* \param it: iterator var name to create
* \param start: start of list
*
* This helper creates an iterator and starts a while (it) {
* loop. The iterator runs through the linked list starting at start and
* ends when it gets a NULL.
* The while loop should be terminated using lws_start_foreach_ll().
*/
#define lws_start_foreach_ll(type, it, start)\
{ \
type it = start; \
while (it) {
/**
* lws_end_foreach_ll(): linkedlist iterator helper end
*
* \param it: same iterator var name given when starting
* \param nxt: member name in the iterator pointing to next list element
*
* This helper is the partner for lws_start_foreach_ll() that ends the
* while loop.
*/
#define lws_end_foreach_ll(it, nxt) \
it = it->nxt; \
} \
}
/**
* lws_start_foreach_ll_safe(): linkedlist iterator helper start safe against delete
*
* \param type: type of iteration, eg, struct xyz *
* \param it: iterator var name to create
* \param start: start of list
* \param nxt: member name in the iterator pointing to next list element
*
* This helper creates an iterator and starts a while (it) {
* loop. The iterator runs through the linked list starting at start and
* ends when it gets a NULL.
* The while loop should be terminated using lws_end_foreach_ll_safe().
* Performs storage of next increment for situations where iterator can become invalidated
* during iteration.
*/
#define lws_start_foreach_ll_safe(type, it, start, nxt)\
{ \
type it = start; \
while (it) { \
type next_##it = it->nxt;
/**
* lws_end_foreach_ll_safe(): linkedlist iterator helper end (pre increment storage)
*
* \param it: same iterator var name given when starting
*
* This helper is the partner for lws_start_foreach_ll_safe() that ends the
* while loop. It uses the precreated next_ variable already stored during
* start.
*/
#define lws_end_foreach_ll_safe(it) \
it = next_##it; \
} \
}
/**
* lws_start_foreach_llp(): linkedlist pointer iterator helper start
*
* \param type: type of iteration, eg, struct xyz **
* \param it: iterator var name to create
* \param start: start of list
*
* This helper creates an iterator and starts a while (it) {
* loop. The iterator runs through the linked list starting at the
* address of start and ends when it gets a NULL.
* The while loop should be terminated using lws_start_foreach_llp().
*
* This helper variant iterates using a pointer to the previous linked-list
* element. That allows you to easily delete list members by rewriting the
* previous pointer to the element's next pointer.
*/
#define lws_start_foreach_llp(type, it, start)\
{ \
type it = &(start); \
while (*(it)) {
#define lws_start_foreach_llp_safe(type, it, start, nxt)\
{ \
type it = &(start); \
type next; \
while (*(it)) { \
next = &((*(it))->nxt); \
/**
* lws_end_foreach_llp(): linkedlist pointer iterator helper end
*
* \param it: same iterator var name given when starting
* \param nxt: member name in the iterator pointing to next list element
*
* This helper is the partner for lws_start_foreach_llp() that ends the
* while loop.
*/
#define lws_end_foreach_llp(it, nxt) \
it = &(*(it))->nxt; \
} \
}
#define lws_end_foreach_llp_safe(it) \
it = next; \
} \
}
#define lws_ll_fwd_insert(\
___new_object, /* pointer to new object */ \
___m_list, /* member for next list object ptr */ \
___list_head /* list head */ \
) {\
___new_object->___m_list = ___list_head; \
___list_head = ___new_object; \
}
#define lws_ll_fwd_remove(\
___type, /* type of listed object */ \
___m_list, /* member for next list object ptr */ \
___target, /* object to remove from list */ \
___list_head /* list head */ \
) { \
lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \
if (*___ppss == ___target) { \
*___ppss = ___target->___m_list; \
break; \
} \
} lws_end_foreach_llp(___ppss, ___m_list); \
}
/*
* doubly linked-list
*/
/*
* lws_dll2_owner / lws_dll2 : more capable version of lws_dll. Differences:
*
* - there's an explicit lws_dll2_owner struct which holds head, tail and
* count of members.
*
* - list members all hold a pointer to their owner. So user code does not
* have to track anything about exactly what lws_dll2_owner list the object
* is a member of.
*
* - you can use lws_dll unless you want the member count or the ability to
* not track exactly which list it's on.
*
* - layout is compatible with lws_dll (but lws_dll apis will not update the
* new stuff)
*/
struct lws_dll2;
struct lws_dll2_owner;
typedef struct lws_dll2 {
struct lws_dll2 *prev;
struct lws_dll2 *next;
struct lws_dll2_owner *owner;
} lws_dll2_t;
typedef struct lws_dll2_owner {
struct lws_dll2 *tail;
struct lws_dll2 *head;
uint32_t count;
} lws_dll2_owner_t;
LWS_VISIBLE LWS_EXTERN int
lws_dll2_is_detached(const struct lws_dll2 *d);
static LWS_INLINE const struct lws_dll2_owner *
lws_dll2_owner(const struct lws_dll2 *d) { return d->owner; }
static LWS_INLINE struct lws_dll2 *
lws_dll2_get_head(struct lws_dll2_owner *owner) { return owner->head; }
static LWS_INLINE struct lws_dll2 *
lws_dll2_get_tail(struct lws_dll2_owner *owner) { return owner->tail; }
LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_head(struct lws_dll2 *d, struct lws_dll2_owner *owner);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_tail(struct lws_dll2 *d, struct lws_dll2_owner *owner);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_remove(struct lws_dll2 *d);
typedef int (*lws_dll2_foreach_cb_t)(struct lws_dll2 *d, void *user);
LWS_VISIBLE LWS_EXTERN int
lws_dll2_foreach_safe(struct lws_dll2_owner *owner, void *user,
lws_dll2_foreach_cb_t cb);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_clear(struct lws_dll2 *d);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_owner_clear(struct lws_dll2_owner *d);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_before(struct lws_dll2 *d, struct lws_dll2 *after);
LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_sorted_priv(lws_dll2_t *d, lws_dll2_owner_t *own, void *priv,
int (*compare3)(void *priv, const lws_dll2_t *d,
const lws_dll2_t *i));
LWS_VISIBLE LWS_EXTERN void *
_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
size_t dll2_ofs, size_t ptr_ofs);
/*
* Searches objects in an owner list linearly and returns one with a given
* member C-string matching a supplied length-provided string if it exists, else
* NULL.
*/
#define lws_dll2_search_sz_pl(own, name, namelen, type, membd2list, membptr) \
((type *)_lws_dll2_search_sz_pl(own, name, namelen, \
offsetof(type, membd2list), \
offsetof(type, membptr)))
#if defined(_DEBUG)
void
lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);
#else
#define lws_dll2_describe(x, y)
#endif
/*
* these are safe against the current container object getting deleted,
* since the hold his next in a temp and go to that next. ___tmp is
* the temp.
*/
#define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \
{ \
___type ___it = ___start; \
while (___it) { \
___type ___tmp = (___it)->next;
#define lws_end_foreach_dll_safe(___it, ___tmp) \
___it = ___tmp; \
} \
}
#define lws_start_foreach_dll(___type, ___it, ___start) \
{ \
___type ___it = ___start; \
while (___it) {
#define lws_end_foreach_dll(___it) \
___it = (___it)->next; \
} \
}
///@}

View File

@ -0,0 +1,148 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* lws_dsh (Disordered Shared Heap) is an opaque abstraction supporting a single
* linear buffer (overallocated at end of the lws_dsh_t) which may contain
* multiple kinds of packets that are retired out of order, and tracked by kind.
*
* Each kind of packet has an lws_dll2 list of its kind of packets and acts as
* a FIFO; packets of a particular type are always retired in order. But there
* is no requirement about the order types are retired matching the original
* order they arrived.
*
* Gaps are tracked as just another kind of "packet" list.
*
* "allocations" (including gaps) are prepended by an lws_dsh_object_t.
*
* dsh may themselves be on an lws_dll2_owner list, and under memory pressure
* allocate into other buffers on the list.
*
* All management structures exist inside the allocated buffer.
*/
/**
* lws_dsh_create() - Allocate a DSH buffer
*
* \param owner: the owning list this dsh belongs on, or NULL if standalone
* \param buffer_size: the allocation in bytes
* \param count_kinds: how many separately-tracked fifos use the buffer
*
* This makes a single heap allocation that includes internal tracking objects
* in the buffer. Sub-allocated objects are bound to a "kind" index and
* managed via a FIFO for each kind.
*
* Every "kind" of allocation shares the same buffer space.
*
* Multiple buffers may be bound together in an lws_dll2 list, and if an
* allocation cannot be satisfied by the local buffer, space can be borrowed
* from other dsh in the same list (the local dsh FIFO tracks these "foreign"
* allocations as if they were local).
*
* Returns an opaque pointer to the dsh, or NULL if allocation failed.
*/
LWS_VISIBLE LWS_EXTERN struct lws_dsh *
lws_dsh_create(lws_dll2_owner_t *owner, size_t buffer_size, int count_kinds);
/**
* lws_dsh_destroy() - Destroy a DSH buffer
*
* \param pdsh: pointer to the dsh pointer
*
* Deallocates the DSH and sets *pdsh to NULL.
*
* Before destruction, any foreign buffer usage on the part of this dsh are
* individually freed. All dsh on the same list are walked and checked if they
* have their own foreign allocations on the dsh buffer being destroyed. If so,
* it attempts to migrate the allocation to a dsh that is not currently being
* destroyed. If all else fails (basically the buffer memory is being shrunk)
* unmigratable objects are cleanly destroyed.
*/
LWS_VISIBLE LWS_EXTERN void
lws_dsh_destroy(struct lws_dsh **pdsh);
/**
* lws_dsh_alloc_tail() - make a suballocation inside a dsh
*
* \param dsh: the dsh tracking the allocation
* \param kind: the kind of allocation
* \param src1: the first source data to copy
* \param size1: the size of the first source data
* \param src2: the second source data to copy (after the first), or NULL
* \param size2: the size of the second source data
*
* Allocates size1 + size2 bytes in a dsh (it prefers the given dsh but will
* borrow space from other dsh on the same list if necessary) and copies size1
* bytes into it from src1, followed by size2 bytes from src2 if src2 isn't
* NULL. The actual suballocation is a bit larger because of alignment and a
* prepended management header.
*
* The suballocation is added to the kind-specific FIFO at the tail.
*/
LWS_VISIBLE LWS_EXTERN int
lws_dsh_alloc_tail(struct lws_dsh *dsh, int kind, const void *src1,
size_t size1, const void *src2, size_t size2);
/**
* lws_dsh_free() - free a suballocation from the dsh
*
* \param obj: a pointer to a void * that pointed to the allocated payload
*
* This returns the space used by \p obj in the dsh buffer to the free list
* of the dsh the allocation came from.
*/
LWS_VISIBLE LWS_EXTERN void
lws_dsh_free(void **obj);
LWS_VISIBLE LWS_EXTERN size_t
lws_dsh_get_size(struct lws_dsh *dsh, int kind);
/**
* lws_dsh_get_head() - get the head allocation inside the dsh
*
* \param dsh: the dsh tracking the allocation
* \param kind: the kind of allocation
* \param obj: pointer to a void * to be set to the payload
* \param size: set to the size of the allocation
*
* This gets the "next" object in the kind FIFO for the dsh, and returns 0 if
* any. If none, returns nonzero.
*
* This is nondestructive of the fifo or the payload. Use lws_dsh_free on
* obj to remove the entry from the kind fifo and return the payload to the
* free list.
*/
LWS_VISIBLE LWS_EXTERN int
lws_dsh_get_head(struct lws_dsh *dsh, int kind, void **obj, size_t *size);
/**
* lws_dsh_describe() - DEBUG BUILDS ONLY dump the dsh to the logs
*
* \param dsh: the dsh to dump
* \param desc: text that appears at the top of the dump
*
* Useful information for debugging lws_dsh
*/
LWS_VISIBLE LWS_EXTERN void
lws_dsh_describe(struct lws_dsh *dsh, const char *desc);

View File

@ -0,0 +1,150 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* These are exports needed by event lib plugins.
*/
enum lws_event_lib_ops_flags {
LELOF_ISPOLL = (1 >> 0),
LELOF_DESTROY_FINAL = (1 >> 1),
};
enum {
LWS_EV_READ = (1 << 0),
LWS_EV_WRITE = (1 << 1),
LWS_EV_START = (1 << 2),
LWS_EV_STOP = (1 << 3),
};
struct lws_event_loop_ops {
const char *name;
/* event loop-specific context init during context creation */
int (*init_context)(struct lws_context *context,
const struct lws_context_creation_info *info);
/* called during lws_destroy_context */
int (*destroy_context1)(struct lws_context *context);
/* called during lws_destroy_context2 */
int (*destroy_context2)(struct lws_context *context);
/* init vhost listening wsi */
int (*init_vhost_listen_wsi)(struct lws *wsi);
/* init the event loop for a pt */
int (*init_pt)(struct lws_context *context, void *_loop, int tsi);
/* called at end of first phase of close_free_wsi() */
int (*wsi_logical_close)(struct lws *wsi);
/* return nonzero if client connect not allowed */
int (*check_client_connect_ok)(struct lws *wsi);
/* close handle manually */
void (*close_handle_manually)(struct lws *wsi);
/* event loop accept processing */
int (*sock_accept)(struct lws *wsi);
/* control wsi active events */
void (*io)(struct lws *wsi, unsigned int flags);
/* run the event loop for a pt */
void (*run_pt)(struct lws_context *context, int tsi);
/* called before pt is destroyed */
void (*destroy_pt)(struct lws_context *context, int tsi);
/* called just before wsi is freed */
void (*destroy_wsi)(struct lws *wsi);
/* return nonzero if caller thread is not loop service thread */
int (*foreign_thread)(struct lws_context *context, int tsi);
uint8_t flags;
uint16_t evlib_size_ctx;
uint16_t evlib_size_pt;
uint16_t evlib_size_vh;
uint16_t evlib_size_wsi;
};
LWS_VISIBLE LWS_EXTERN void *
lws_evlib_wsi_to_evlib_pt(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN void *
lws_evlib_tsi_to_evlib_pt(struct lws_context *ctx, int tsi);
/*
* You should consider these opaque for normal user code.
*/
LWS_VISIBLE LWS_EXTERN void *
lws_realloc(void *ptr, size_t size, const char *reason);
LWS_VISIBLE LWS_EXTERN void
lws_vhost_destroy1(struct lws_vhost *vh);
LWS_VISIBLE LWS_EXTERN void
lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
const char *caller);
LWS_VISIBLE LWS_EXTERN int
lws_vhost_foreach_listen_wsi(struct lws_context *cx, void *arg,
lws_dll2_foreach_cb_t cb);
struct lws_context_per_thread;
LWS_VISIBLE LWS_EXTERN void
lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
#if !defined(wsi_from_fd) && !defined(WIN32) && !defined(_WIN32)
struct lws_context;
LWS_VISIBLE LWS_EXTERN struct lws *
wsi_from_fd(const struct lws_context *context, int fd);
#endif
LWS_VISIBLE LWS_EXTERN int
_lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
LWS_VISIBLE LWS_EXTERN void
lws_context_destroy2(struct lws_context *context);
LWS_VISIBLE LWS_EXTERN void
lws_destroy_event_pipe(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN void
__lws_close_free_wsi_final(struct lws *wsi);
#if LWS_MAX_SMP > 1
struct lws_mutex_refcount {
pthread_mutex_t lock;
pthread_t lock_owner;
const char *last_lock_reason;
char lock_depth;
char metadata;
};
LWS_VISIBLE LWS_EXTERN void
lws_mutex_refcount_assert_held(struct lws_mutex_refcount *mr);
LWS_VISIBLE LWS_EXTERN void
lws_mutex_refcount_init(struct lws_mutex_refcount *mr);
LWS_VISIBLE LWS_EXTERN void
lws_mutex_refcount_destroy(struct lws_mutex_refcount *mr);
LWS_VISIBLE LWS_EXTERN void
lws_mutex_refcount_lock(struct lws_mutex_refcount *mr, const char *reason);
LWS_VISIBLE LWS_EXTERN void
lws_mutex_refcount_unlock(struct lws_mutex_refcount *mr);
#endif

View File

@ -0,0 +1,251 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Fault injection api if built with LWS_WITH_SYS_FAULT_INJECTION
*/
typedef struct lws_xos {
uint64_t s[4];
} lws_xos_t;
/**
* lws_xos_init() - seed xoshiro256 PRNG
*
* \param xos: the prng state object to initialize
* \param seed: the 64-bit seed
*
* Initialize PRNG \xos with the starting state represented by \p seed
*/
LWS_VISIBLE LWS_EXTERN void
lws_xos_init(struct lws_xos *xos, uint64_t seed);
/**
* lws_xos() - get next xoshiro256 PRNG result and update state
*
* \param xos: the PRNG state to use
*
* Returns next 64-bit PRNG result. These are cheap to get,
* quite a white noise sequence, and completely deterministic
* according to the seed it was initialized with.
*/
LWS_VISIBLE LWS_EXTERN uint64_t LWS_WARN_UNUSED_RESULT
lws_xos(struct lws_xos *xos);
/**
* lws_xos_percent() - return 1 a given percent of the time on average
*
* \param xos: the PRNG state to use
* \param percent: chance in 100 of returning 1
*
* Returns 1 if next random % 100 is < \p percent, such that
* 100 always returns 1, 0 never returns 1, and the chance linearly scales
* inbetween
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_xos_percent(struct lws_xos *xos, int percent);
#if defined(LWS_WITH_SYS_FAULT_INJECTION)
enum {
LWSFI_ALWAYS,
LWSFI_DETERMINISTIC, /* do .count injections after .pre then stop */
LWSFI_PROBABILISTIC, /* .pre % chance of injection */
LWSFI_PATTERN, /* use .count bits in .pattern after .pre */
LWSFI_PATTERN_ALLOC, /* as _PATTERN, but .pattern is malloc'd */
LWSFI_RANGE /* pick a number between pre and count */
};
typedef struct lws_fi {
const char *name;
const uint8_t *pattern;
uint64_t pre;
uint64_t count;
uint64_t times; /* start at 0, tracks usage */
char type; /* LWSFI_* */
} lws_fi_t;
typedef struct lws_fi_ctx {
lws_dll2_owner_t fi_owner;
struct lws_xos xos;
const char *name;
} lws_fi_ctx_t;
/**
* lws_fi() - find out if we should perform the named fault injection this time
*
* \param fic: fault injection tracking context
* \param fi_name: name of fault injection
*
* This checks if the named fault is configured in the fi tracking context
* provided, if it is, then it will make a decision if the named fault should
* be applied this time, using the tracking in the named lws_fi_t.
*
* If the provided context has a parent, that is also checked for the named fi
* item recursively, with the first found being used to determine if to inject
* or not.
*
* If LWS_WITH_SYS_FAULT_INJECTION is not defined, then this always return 0.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fi(const lws_fi_ctx_t *fic, const char *fi_name);
/**
* lws_fi_range() - get a random number from a range
*
* \param fic: fault injection tracking context
* \param fi_name: name of fault injection
* \param result: points to uint64_t to be set to the result
*
* This lets you get a random number from an externally-set range, set using a
* fault injection syntax like "myfault(123..456)". That will cause us to
* return a number between those two inclusive, from the seeded PRNG.
*
* This is useful when you used lws_fi() with its own fault name to decide
* whether to inject the fault, and then the code to cause the fault needs
* additional constrained pseudo-random fuzzing for, eg, delays before issuing
* the fault.
*
* Returns 0 if \p *result is set, else nonzero for failure.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fi_range(const lws_fi_ctx_t *fic, const char *name, uint64_t *result);
/**
* lws_fi_add() - add an allocated copy of fault injection to a context
*
* \param fic: fault injection tracking context
* \param fi: the fault injection details
*
* This allocates a copy of \p fi and attaches it to the fault injection context
* \p fic. \p fi can go out of scope after this safely.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi);
/**
* lws_fi_remove() - remove an allocated copy of fault injection from a context
*
* \param fic: fault injection tracking context
* \param name: the fault injection name to remove
*
* This looks for the named fault injection and removes and destroys it from
* the specified fault injection context
*/
LWS_VISIBLE LWS_EXTERN void
lws_fi_remove(lws_fi_ctx_t *fic, const char *name);
/**
* lws_fi_import() - transfers all the faults from one context to another
*
* \param fic_dest: the fault context to receive the faults
* \param fic_src: the fault context that will be emptied out into \p fic_dest
*
* This is used to initialize created object fault injection contexts from
* the caller.
*/
LWS_VISIBLE LWS_EXTERN void
lws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src);
/**
* lws_fi_inherit_copy() - attach copies of matching fault injection objects to dest
*
* \param fic_dest: destination Fault Injection context
* \param fic_src: parent fault context that may contain matching rules
* \param scope: the name of the path match required, eg, "vh"
* \param value: the dynamic name of our match, eg, "myvhost"
*
* If called with scope "vh" and value "myvhost", then matches faults starting
* "vh=myvhost/", strips that part of the name if it matches and makes a copy
* of the rule with the modified name attached to the destination Fault Injection
* context.
*/
LWS_VISIBLE LWS_EXTERN void
lws_fi_inherit_copy(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src,
const char *scope, const char *value);
/**
* lws_fi_destroy() - removes all allocated fault injection entries
*
* \param fic: fault injection tracking context
*
* This walks any allocated fault injection entries in \p fic and detaches and
* destroys them. It doesn't try to destroc \p fic itself, since this is
* not usually directly allocated.
*/
LWS_VISIBLE LWS_EXTERN void
lws_fi_destroy(const lws_fi_ctx_t *fic);
/**
* lws_fi_deserialize() - adds fault in string form to Fault Injection Context
*
* \p fic: the fault injection context
* \p sers: the string serializing the desired fault details
*
* This turns a string like "ss=captive_portal_detect/wsi/dnsfail(10%)" into
* a fault injection struct added to the fault injection context \p fic
*
* You can prepare the context creation info .fic with these before creating
* the context, and use namespace paths on those to target other objects.
*/
LWS_VISIBLE LWS_EXTERN void
lws_fi_deserialize(lws_fi_ctx_t *fic, const char *sers);
LWS_VISIBLE LWS_EXTERN int
_lws_fi_user_wsi_fi(struct lws *wsi, const char *name);
LWS_VISIBLE LWS_EXTERN int
_lws_fi_user_context_fi(struct lws_context *ctx, const char *name);
#if defined(LWS_WITH_SECURE_STREAMS)
struct lws_ss_handle;
LWS_VISIBLE LWS_EXTERN int
_lws_fi_user_ss_fi(struct lws_ss_handle *h, const char *name);
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
struct lws_sspc_handle;
LWS_VISIBLE LWS_EXTERN int
_lws_fi_user_sspc_fi(struct lws_sspc_handle *h, const char *name);
#endif
#endif
#define lws_fi_user_wsi_fi(_wsi, _name) _lws_fi_user_wsi_fi(_wsi, _name)
#define lws_fi_user_context_fi(_ctx, _name) _lws_fi_user_context_fi(_ctx, _name)
#define lws_fi_user_ss_fi(_h, _name) _lws_fi_user_ss_fi(_h, _name)
#define lws_fi_user_sspc_fi(_h, _name) _lws_fi_user_sspc_fi(_h, _name)
#else
/*
* Helper so we can leave lws_fi() calls embedded in the code being tested,
* if fault injection is not enabled then it just always says "no" at buildtime.
*/
#define lws_fi(_fi_name, _fic) (0)
#define lws_fi_destroy(_x)
#define lws_fi_inherit_copy(_a, _b, _c, _d)
#define lws_fi_deserialize(_x, _y)
#define lws_fi_user_wsi_fi(_wsi, _name) (0)
#define lws_fi_user_context_fi(_wsi, _name) (0)
#define lws_fi_user_ss_fi(_h, _name) (0)
#define lws_fi_user_sspc_fi(_h, _name) (0)
#endif

View File

@ -0,0 +1,87 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is included from libwebsockets.h if LWS_PLAT_FREERTOS
*/
typedef int lws_sockfd_type;
typedef int lws_filefd_type;
#if defined(LWS_AMAZON_RTOS)
#include <FreeRTOS.h>
#include <event_groups.h>
#include <string.h>
#include "timers.h"
#include <lwip/sockets.h>
/*
* Later lwip (at least 2.1.12) already defines these in its own headers
* protected by the same test as used here... if POLLIN / POLLOUT already exist
* then assume no need to declare those and struct pollfd.
*
* Older lwip needs these declarations done here.
*/
#if !defined(POLLIN) && !defined(POLLOUT)
struct pollfd {
lws_sockfd_type fd; /**< fd related to */
short events; /**< which POLL... events to respond to */
short revents; /**< which POLL... events occurred */
};
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
#endif
#else /* LWS_AMAZON_RTOS */
#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
//#include "esp_event_loop.h"
#include "nvs.h"
#include "driver/gpio.h"
#include "esp_spi_flash.h"
#include "freertos/timers.h"
#if defined(LWS_ESP_PLATFORM)
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#if defined(LWS_WITH_DRIVERS)
#include "libwebsockets/lws-gpio.h"
extern const lws_gpio_ops_t lws_gpio_plat;
#endif
#endif
#endif /* LWS_AMAZON_RTOS */
#if !defined(CONFIG_FREERTOS_HZ)
#define CONFIG_FREERTOS_HZ 100
#endif

View File

@ -0,0 +1,215 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup search Search
*
* ##Full-text search
*
* Lws provides superfast indexing and fulltext searching from index files on
* storage.
*/
///@{
struct lws_fts;
struct lws_fts_file;
/*
* Queries produce their results in an lwsac, using these public API types.
* The first thing in the lwsac is always a struct lws_fts_result (see below)
* containing heads for linked-lists of the other result types.
*/
/* one filepath's results */
struct lws_fts_result_filepath {
struct lws_fts_result_filepath *next;
int matches; /* logical number of matches */
int matches_length; /* bytes in length table (may be zero) */
int lines_in_file;
int filepath_length;
/* - uint32_t line table follows (first for alignment) */
/* - filepath (of filepath_length) follows */
};
/* autocomplete result */
struct lws_fts_result_autocomplete {
struct lws_fts_result_autocomplete *next;
int instances;
int agg_instances;
int ac_length;
char elided; /* children skipped in interest of antecedent children */
char has_children;
/* - autocomplete suggestion (of length ac_length) follows */
};
/*
* The results lwsac always starts with this. If no results and / or no
* autocomplete the members may be NULL. This implies the symbol nor any
* suffix on it exists in the trie file.
*/
struct lws_fts_result {
struct lws_fts_result_filepath *filepath_head;
struct lws_fts_result_autocomplete *autocomplete_head;
int duration_ms;
int effective_flags; /* the search flags that were used */
};
/*
* index creation functions
*/
/**
* lws_fts_create() - Create a new index file
*
* \param fd: The fd opened for write
*
* Inits a new index file, returning a struct lws_fts to represent it
*/
LWS_VISIBLE LWS_EXTERN struct lws_fts *
lws_fts_create(int fd);
/**
* lws_fts_destroy() - Finalize a new index file / destroy the trie lwsac
*
* \param trie: The previously opened index being finalized
*
* Finalizes an index file that was being created, and frees the memory involved
* *trie is set to NULL afterwards.
*/
LWS_VISIBLE LWS_EXTERN void
lws_fts_destroy(struct lws_fts **trie);
/**
* lws_fts_file_index() - Create a new entry in the trie file for an input path
*
* \param t: The previously opened index being written
* \param filepath: The filepath (which may be virtual) associated with this file
* \param filepath_len: The number of chars in the filepath
* \param priority: not used yet
*
* Returns an ordinal that represents this new filepath in the index file.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fts_file_index(struct lws_fts *t, const char *filepath, int filepath_len,
int priority);
/**
* lws_fts_fill() - Process all or a bufferload of input file
*
* \param t: The previously opened index being written
* \param file_index: The ordinal representing this input filepath
* \param buf: A bufferload of data from the input file
* \param len: The number of bytes in buf
*
* Indexes a buffer of data from the input file.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fts_fill(struct lws_fts *t, uint32_t file_index, const char *buf,
size_t len);
/**
* lws_fts_serialize() - Store the in-memory trie into the index file
*
* \param t: The previously opened index being written
*
* The trie is held in memory where it can be added to... after all the input
* filepaths and data have been processed, this is called to serialize /
* write the trie data into the index file.
*/
LWS_VISIBLE LWS_EXTERN int
lws_fts_serialize(struct lws_fts *t);
/*
* index search functions
*/
/**
* lws_fts_open() - Open an existing index file to search it
*
* \param filepath: The filepath to the index file to open
*
* Opening the index file returns an opaque struct lws_fts_file * that is
* used to perform other operations on it, or NULL if it can't be opened.
*/
LWS_VISIBLE LWS_EXTERN struct lws_fts_file *
lws_fts_open(const char *filepath);
#define LWSFTS_F_QUERY_AUTOCOMPLETE (1 << 0)
#define LWSFTS_F_QUERY_FILES (1 << 1)
#define LWSFTS_F_QUERY_FILE_LINES (1 << 2)
#define LWSFTS_F_QUERY_QUOTE_LINE (1 << 3)
struct lws_fts_search_params {
/* the actual search term */
const char *needle;
/* if non-NULL, FILE results for this filepath only */
const char *only_filepath;
/* will be set to the results lwsac */
struct lwsac *results_head;
/* combination of LWSFTS_F_QUERY_* flags */
int flags;
/* maximum number of autocomplete suggestions to return */
int max_autocomplete;
/* maximum number of filepaths to return */
int max_files;
/* maximum number of line number results to return per filepath */
int max_lines;
};
/**
* lws_fts_search() - Perform a search operation on an index
*
* \param jtf: The index file struct returned by lws_fts_open
* \param ftsp: The struct lws_fts_search_params filled in by the caller
*
* The caller should memset the ftsp struct to 0 to ensure members that may be
* introduced in later versions contain known values, then set the related
* members to describe the kind of search action required.
*
* ftsp->results_head is the results lwsac, or NULL. It should be freed with
* lwsac_free() when the results are finished with.
*
* Returns a pointer into the results lwsac that is a struct lws_fts_result
* containing the head pointers into linked-lists of results for autocomplete
* and filepath data, along with some sundry information. This does not need
* to be freed since freeing the lwsac will also remove this and everything it
* points to.
*/
LWS_VISIBLE LWS_EXTERN struct lws_fts_result *
lws_fts_search(struct lws_fts_file *jtf, struct lws_fts_search_params *ftsp);
/**
* lws_fts_close() - Close a previously-opened index file
*
* \param jtf: The pointer returned from the open
*
* Closes the file handle on the index and frees any allocations
*/
LWS_VISIBLE LWS_EXTERN void
lws_fts_close(struct lws_fts_file *jtf);
///@}

View File

@ -0,0 +1,170 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup generic AES
* ## Generic AES related functions
*
* Lws provides generic AES functions that abstract the ones
* provided by whatever tls library you are linking against.
*
* It lets you use the same code if you build against mbedtls or OpenSSL
* for example.
*/
///@{
#if defined(LWS_WITH_MBEDTLS)
#include <mbedtls/aes.h>
#include <mbedtls/gcm.h>
#endif
enum enum_aes_modes {
LWS_GAESM_CBC,
LWS_GAESM_CFB128,
LWS_GAESM_CFB8,
LWS_GAESM_CTR,
LWS_GAESM_ECB,
LWS_GAESM_OFB,
LWS_GAESM_XTS, /* care... requires double-length key */
LWS_GAESM_GCM,
LWS_GAESM_KW,
};
enum enum_aes_operation {
LWS_GAESO_ENC,
LWS_GAESO_DEC
};
enum enum_aes_padding {
LWS_GAESP_NO_PADDING,
LWS_GAESP_WITH_PADDING
};
/* include/libwebsockets/lws-jwk.h must be included before this */
#define LWS_AES_BLOCKSIZE 128
#define LWS_AES_CBC_BLOCKLEN 16
struct lws_genaes_ctx {
#if defined(LWS_WITH_MBEDTLS)
union {
mbedtls_aes_context ctx;
#if defined(MBEDTLS_CIPHER_MODE_XTS)
mbedtls_aes_xts_context ctx_xts;
#endif
mbedtls_gcm_context ctx_gcm;
} u;
#else
EVP_CIPHER_CTX *ctx;
const EVP_CIPHER *cipher;
ENGINE *engine;
char init;
#endif
unsigned char tag[16];
struct lws_gencrypto_keyelem *k;
enum enum_aes_operation op;
enum enum_aes_modes mode;
enum enum_aes_padding padding;
int taglen;
char underway;
};
/** lws_genaes_create() - Create RSA public decrypt context
*
* \param ctx: your struct lws_genaes_ctx
* \param op: LWS_GAESO_ENC or LWS_GAESO_DEC
* \param mode: one of LWS_GAESM_
* \param el: struct prepared with key element data
* \param padding: 0 = no padding, 1 = padding
* \param engine: if openssl engine used, pass the pointer here
*
* Creates an RSA context with a public key associated with it, formed from
* the key elements in \p el.
*
* Returns 0 for OK or nonzero for error.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
enum enum_aes_padding padding, void *engine);
/** lws_genaes_destroy() - Destroy genaes AES context
*
* \param ctx: your struct lws_genaes_ctx
* \param tag: NULL, or, GCM-only: buffer to receive tag
* \param tlen: 0, or, GCM-only: length of tag buffer
*
* Destroys any allocations related to \p ctx.
*
* For GCM only, up to tlen bytes of tag buffer will be set on exit.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen);
/** lws_genaes_crypt() - Encrypt or decrypt
*
* \param ctx: your struct lws_genaes_ctx
* \param in: input plaintext or ciphertext
* \param len: length of input (which is always length of output)
* \param out: output plaintext or ciphertext
* \param iv_or_nonce_ctr_or_data_unit_16: NULL, iv, nonce_ctr16, or data_unit16
* \param stream_block_16: pointer to 16-byte stream block for CTR mode only
* \param nc_or_iv_off: NULL or pointer to nc, or iv_off
* \param taglen: length of tag
*
* Encrypts or decrypts using the AES mode set when the ctx was created.
* The last three arguments have different meanings depending on the mode:
*
* KW CBC CFB128 CFB8 CTR ECB OFB XTS
* iv_or_nonce_ct.._unit_16 : iv iv iv iv nonce NULL iv dataunt
* stream_block_16 : NULL NULL NULL NULL stream NULL NULL NULL
* nc_or_iv_off : NULL NULL iv_off NULL nc_off NULL iv_off NULL
*
* For GCM:
*
* iv_or_nonce_ctr_or_data_unit_16 : iv
* stream_block_16 : pointer to tag
* nc_or_iv_off : set pointed-to size_t to iv length
* in : first call: additional data, subsequently
* : input data
* len : first call: add data length, subsequently
* : input / output length
*
* The length of the optional arg is always 16 if used, regardless of the mode.
*
* Returns 0 for OK or nonzero for error.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len,
uint8_t *out,
uint8_t *iv_or_nonce_ctr_or_data_unit_16,
uint8_t *stream_block_16,
size_t *nc_or_iv_off, int taglen);
///@}

View File

@ -0,0 +1,137 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*
* These are gencrypto-level constants... they are used by both JOSE and direct
* gencrypto code. However while JWK relies on these, using gencrypto apis has
* no dependency at all on any JOSE type.
*/
enum lws_gencrypto_kty {
LWS_GENCRYPTO_KTY_UNKNOWN,
LWS_GENCRYPTO_KTY_OCT,
LWS_GENCRYPTO_KTY_RSA,
LWS_GENCRYPTO_KTY_EC
};
/*
* Keytypes where the same element name is reused must all agree to put the
* same-named element at the same e[] index. It's because when used with jwk,
* we parse and store in incoming key data, but we may not be informed of the
* definitive keytype until the end.
*/
enum lws_gencrypto_oct_tok {
LWS_GENCRYPTO_OCT_KEYEL_K, /* note... same offset as AES K */
LWS_GENCRYPTO_OCT_KEYEL_COUNT
};
enum lws_gencrypto_rsa_tok {
LWS_GENCRYPTO_RSA_KEYEL_E,
LWS_GENCRYPTO_RSA_KEYEL_N,
LWS_GENCRYPTO_RSA_KEYEL_D, /* note... same offset as EC D */
LWS_GENCRYPTO_RSA_KEYEL_P,
LWS_GENCRYPTO_RSA_KEYEL_Q,
LWS_GENCRYPTO_RSA_KEYEL_DP,
LWS_GENCRYPTO_RSA_KEYEL_DQ,
LWS_GENCRYPTO_RSA_KEYEL_QI,
/* we don't actively use these if given, but may come from COSE */
LWS_GENCRYPTO_RSA_KEYEL_OTHER,
LWS_GENCRYPTO_RSA_KEYEL_RI,
LWS_GENCRYPTO_RSA_KEYEL_DI,
LWS_GENCRYPTO_RSA_KEYEL_TI,
LWS_GENCRYPTO_RSA_KEYEL_COUNT
};
enum lws_gencrypto_ec_tok {
LWS_GENCRYPTO_EC_KEYEL_CRV,
LWS_GENCRYPTO_EC_KEYEL_X,
/* note... same offset as RSA D */
LWS_GENCRYPTO_EC_KEYEL_D = LWS_GENCRYPTO_RSA_KEYEL_D,
LWS_GENCRYPTO_EC_KEYEL_Y,
LWS_GENCRYPTO_EC_KEYEL_COUNT
};
enum lws_gencrypto_aes_tok {
/* note... same offset as OCT K */
LWS_GENCRYPTO_AES_KEYEL_K = LWS_GENCRYPTO_OCT_KEYEL_K,
LWS_GENCRYPTO_AES_KEYEL_COUNT
};
/* largest number of key elements for any algorithm */
#define LWS_GENCRYPTO_MAX_KEYEL_COUNT LWS_GENCRYPTO_RSA_KEYEL_COUNT
/* this "stretchy" type holds individual key element data in binary form.
* It's typcially used in an array with the layout mapping the element index to
* the key element meaning defined by the enums above. An array of these of
* length LWS_GENCRYPTO_MAX_KEYEL_COUNT can define key elements for any key
* type.
*/
typedef struct lws_gencrypto_keyelem {
uint8_t *buf;
uint32_t len;
} lws_gc_elem_t;
/**
* lws_gencrypto_bits_to_bytes() - returns rounded up bytes needed for bits
*
* \param bits
*
* Returns the number of bytes needed to store the given number of bits. If
* a byte is partially used, the byte count is rounded up.
*/
LWS_VISIBLE LWS_EXTERN int
lws_gencrypto_bits_to_bytes(int bits);
/**
* lws_base64_size() - returns estimated size of base64 encoding
*
* \param bytes
*
* Returns a slightly oversize estimate of the size of a base64 encoded version
* of the given amount of unencoded data.
*/
LWS_VISIBLE LWS_EXTERN int
lws_base64_size(int bytes);
/**
* lws_gencrypto_padded_length() - returns PKCS#5/#7 padded length
*
* @param blocksize - blocksize to pad to
* @param len - Length of input to pad
*
* Returns the length of a buffer originally of size len after PKCS#5 or PKCS#7
* padding has been applied to it.
*/
LWS_VISIBLE LWS_EXTERN size_t
lws_gencrypto_padded_length(size_t block_size, size_t len);

View File

@ -0,0 +1,211 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
enum enum_genec_alg {
LEGENEC_UNKNOWN,
LEGENEC_ECDH,
LEGENEC_ECDSA
};
struct lws_genec_ctx {
#if defined(LWS_WITH_MBEDTLS)
union {
mbedtls_ecdh_context *ctx_ecdh;
mbedtls_ecdsa_context *ctx_ecdsa;
} u;
#else
EVP_PKEY_CTX *ctx[2];
#endif
struct lws_context *context;
const struct lws_ec_curves *curve_table;
enum enum_genec_alg genec_alg;
char has_private;
};
#if defined(LWS_WITH_MBEDTLS)
enum enum_lws_dh_side {
LDHS_OURS = MBEDTLS_ECDH_OURS,
LDHS_THEIRS = MBEDTLS_ECDH_THEIRS
};
#else
enum enum_lws_dh_side {
LDHS_OURS,
LDHS_THEIRS
};
#endif
struct lws_ec_curves {
const char *name;
int tls_lib_nid;
uint16_t key_bytes;
};
/* ECDH-specific apis */
/** lws_genecdh_create() - Create a genecdh
*
* \param ctx: your genec context
* \param context: your lws_context (for RNG access)
* \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
* struct lws_ec_curves array, terminated by an entry with
* .name = NULL, of curves you want to allow
*
* Initializes a genecdh
*/
LWS_VISIBLE int
lws_genecdh_create(struct lws_genec_ctx *ctx, struct lws_context *context,
const struct lws_ec_curves *curve_table);
/** lws_genecdh_set_key() - Apply an EC key to our or theirs side
*
* \param ctx: your genecdh context
* \param el: your key elements
* \param side: LDHS_OURS or LDHS_THEIRS
*
* Applies an EC key to one side or the other of an ECDH ctx
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdh_set_key(struct lws_genec_ctx *ctx, struct lws_gencrypto_keyelem *el,
enum enum_lws_dh_side side);
/** lws_genecdh_new_keypair() - Create a genec with a new public / private key
*
* \param ctx: your genec context
* \param side: LDHS_OURS or LDHS_THEIRS
* \param curve_name: an EC curve name, like "P-256"
* \param el: array pf LWS_GENCRYPTO_EC_KEYEL_COUNT key elems to take the new key
*
* Creates a genecdh with a newly minted EC public / private key
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdh_new_keypair(struct lws_genec_ctx *ctx, enum enum_lws_dh_side side,
const char *curve_name, struct lws_gencrypto_keyelem *el);
LWS_VISIBLE LWS_EXTERN int
lws_genecdh_compute_shared_secret(struct lws_genec_ctx *ctx, uint8_t *ss,
int *ss_len);
/* ECDSA-specific apis */
/** lws_genecdsa_create() - Create a genecdsa and
*
* \param ctx: your genec context
* \param context: your lws_context (for RNG access)
* \param curve_table: NULL, enabling P-256, P-384 and P-521, or a replacement
* struct lws_ec_curves array, terminated by an entry with
* .name = NULL, of curves you want to allow
*
* Initializes a genecdh
*/
LWS_VISIBLE int
lws_genecdsa_create(struct lws_genec_ctx *ctx, struct lws_context *context,
const struct lws_ec_curves *curve_table);
/** lws_genecdsa_new_keypair() - Create a genecdsa with a new public / private key
*
* \param ctx: your genec context
* \param curve_name: an EC curve name, like "P-256"
* \param el: array pf LWS_GENCRYPTO_EC_KEYEL_COUNT key elements to take the new key
*
* Creates a genecdsa with a newly minted EC public / private key
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdsa_new_keypair(struct lws_genec_ctx *ctx, const char *curve_name,
struct lws_gencrypto_keyelem *el);
/** lws_genecdsa_set_key() - Apply an EC key to an ecdsa context
*
* \param ctx: your genecdsa context
* \param el: your key elements
*
* Applies an EC key to an ecdsa context
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdsa_set_key(struct lws_genec_ctx *ctx,
const struct lws_gencrypto_keyelem *el);
/** lws_genecdsa_hash_sig_verify_jws() - Verifies a JWS ECDSA signature on a given hash
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: unencrypted payload (usually a recomputed hash)
* \param hash_type: one of LWS_GENHASH_TYPE_
* \param keybits: number of bits in the crypto key
* \param sig: pointer to the signature we received with the payload
* \param sig_len: length of the signature we are checking in bytes
*
* This just looks at the signed hash... that's why there's no input length
* parameter, it's decided by the choice of hash. It's up to you to confirm
* separately the actual payload matches the hash that was confirmed by this to
* be validly signed.
*
* Returns <0 for error, or 0 if signature matches the hash + key..
*
* The JWS ECDSA signature verification algorithm differs to generic ECDSA
* signatures and they're not interoperable.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdsa_hash_sig_verify_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
enum lws_genhash_types hash_type, int keybits,
const uint8_t *sig, size_t sig_len);
/** lws_genecdsa_hash_sign_jws() - Creates a JWS ECDSA signature for a hash you provide
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: precomputed hash
* \param hash_type: one of LWS_GENHASH_TYPE_
* \param keybits: number of bits in the crypto key
* \param sig: pointer to buffer to take signature
* \param sig_len: length of the buffer (must be >= length of key N)
*
* Returns <0 for error, or 0 for success.
*
* This creates a JWS ECDSA signature for a hash you already computed and provide.
*
* The JWS ECDSA signature generation algorithm differs to generic ECDSA
* signatures and they're not interoperable.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genecdsa_hash_sign_jws(struct lws_genec_ctx *ctx, const uint8_t *in,
enum lws_genhash_types hash_type, int keybits,
uint8_t *sig, size_t sig_len);
/* Apis that apply to both ECDH and ECDSA */
LWS_VISIBLE LWS_EXTERN void
lws_genec_destroy(struct lws_genec_ctx *ctx);
LWS_VISIBLE LWS_EXTERN void
lws_genec_destroy_elements(struct lws_gencrypto_keyelem *el);
LWS_VISIBLE LWS_EXTERN int
lws_genec_dump(struct lws_gencrypto_keyelem *el);

View File

@ -0,0 +1,187 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup generichash Generic Hash
* ## Generic Hash related functions
*
* Lws provides generic hash / digest accessors that abstract the ones
* provided by whatever tls library you are linking against.
*
* It lets you use the same code if you build against mbedtls or OpenSSL
* for example.
*/
///@{
enum lws_genhash_types {
LWS_GENHASH_TYPE_UNKNOWN,
LWS_GENHASH_TYPE_MD5,
LWS_GENHASH_TYPE_SHA1,
LWS_GENHASH_TYPE_SHA256,
LWS_GENHASH_TYPE_SHA384,
LWS_GENHASH_TYPE_SHA512,
};
enum lws_genhmac_types {
LWS_GENHMAC_TYPE_UNKNOWN,
LWS_GENHMAC_TYPE_SHA256,
LWS_GENHMAC_TYPE_SHA384,
LWS_GENHMAC_TYPE_SHA512,
};
#define LWS_GENHASH_LARGEST 64
struct lws_genhash_ctx {
uint8_t type;
#if defined(LWS_WITH_MBEDTLS)
union {
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
mbedtls_sha256_context sha256;
mbedtls_sha512_context sha512; /* 384 also uses this */
const mbedtls_md_info_t *hmac;
} u;
#else
const EVP_MD *evp_type;
EVP_MD_CTX *mdctx;
#endif
};
struct lws_genhmac_ctx {
uint8_t type;
#if defined(LWS_WITH_MBEDTLS)
const mbedtls_md_info_t *hmac;
mbedtls_md_context_t ctx;
#else
const EVP_MD *evp_type;
#if defined(LWS_HAVE_EVP_PKEY_new_raw_private_key)
EVP_MD_CTX *ctx;
EVP_PKEY *key;
#else
#if defined(LWS_HAVE_HMAC_CTX_new)
HMAC_CTX *ctx;
#else
HMAC_CTX ctx;
#endif
#endif
#endif
};
/** lws_genhash_size() - get hash size in bytes
*
* \param type: one of LWS_GENHASH_TYPE_...
*
* Returns number of bytes in this type of hash
*/
LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
lws_genhash_size(enum lws_genhash_types type);
/** lws_genhmac_size() - get hash size in bytes
*
* \param type: one of LWS_GENHASH_TYPE_...
*
* Returns number of bytes in this type of hmac
*/
LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT
lws_genhmac_size(enum lws_genhmac_types type);
/** lws_genhash_init() - prepare your struct lws_genhash_ctx for use
*
* \param ctx: your struct lws_genhash_ctx
* \param type: one of LWS_GENHASH_TYPE_...
*
* Initializes the hash context for the type you requested
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type);
/** lws_genhash_update() - digest len bytes of the buffer starting at in
*
* \param ctx: your struct lws_genhash_ctx
* \param in: start of the bytes to digest
* \param len: count of bytes to digest
*
* Updates the state of your hash context to reflect digesting len bytes from in
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len);
/** lws_genhash_destroy() - copy out the result digest and destroy the ctx
*
* \param ctx: your struct lws_genhash_ctx
* \param result: NULL, or where to copy the result hash
*
* Finalizes the hash and copies out the digest. Destroys any allocations such
* that ctx can safely go out of scope after calling this.
*
* NULL result is supported so that you can destroy the ctx cleanly on error
* conditions, where there is no valid result.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result);
/** lws_genhmac_init() - prepare your struct lws_genhmac_ctx for use
*
* \param ctx: your struct lws_genhmac_ctx
* \param type: one of LWS_GENHMAC_TYPE_...
* \param key: pointer to the start of the HMAC key
* \param key_len: length of the HMAC key
*
* Initializes the hash context for the type you requested
*
* If the return is nonzero, it failed and there is nothing needing to be
* destroyed.
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type,
const uint8_t *key, size_t key_len);
/** lws_genhmac_update() - digest len bytes of the buffer starting at in
*
* \param ctx: your struct lws_genhmac_ctx
* \param in: start of the bytes to digest
* \param len: count of bytes to digest
*
* Updates the state of your hash context to reflect digesting len bytes from in
*
* If the return is nonzero, it failed and needs destroying.
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len);
/** lws_genhmac_destroy() - copy out the result digest and destroy the ctx
*
* \param ctx: your struct lws_genhmac_ctx
* \param result: NULL, or where to copy the result hash
*
* Finalizes the hash and copies out the digest. Destroys any allocations such
* that ctx can safely go out of scope after calling this.
*
* NULL result is supported so that you can destroy the ctx cleanly on error
* conditions, where there is no valid result.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result);
///@}

View File

@ -0,0 +1,255 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup genericRSA Generic RSA
* ## Generic RSA related functions
*
* Lws provides generic RSA functions that abstract the ones
* provided by whatever OpenSSL library you are linking against.
*
* It lets you use the same code if you build against mbedtls or OpenSSL
* for example.
*/
///@{
/* include/libwebsockets/lws-jwk.h must be included before this */
enum enum_genrsa_mode {
LGRSAM_PKCS1_1_5,
LGRSAM_PKCS1_OAEP_PSS,
LGRSAM_COUNT
};
struct lws_genrsa_ctx {
#if defined(LWS_WITH_MBEDTLS)
mbedtls_rsa_context *ctx;
#else
BIGNUM *bn[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
EVP_PKEY_CTX *ctx;
RSA *rsa;
#endif
struct lws_context *context;
enum enum_genrsa_mode mode;
};
/** lws_genrsa_public_decrypt_create() - Create RSA public decrypt context
*
* \param ctx: your struct lws_genrsa_ctx
* \param el: struct prepared with key element data
* \param context: lws_context for RNG
* \param mode: RSA mode, one of LGRSAM_ constants
* \param oaep_hashid: the lws genhash id for the hash used in MFG1 hash
* used in OAEP mode - normally, SHA1
*
* Creates an RSA context with a public key associated with it, formed from
* the key elements in \p el.
*
* Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses. It's
* recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations.
*
* Returns 0 for OK or nonzero for error.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_create(struct lws_genrsa_ctx *ctx,
const struct lws_gencrypto_keyelem *el,
struct lws_context *context, enum enum_genrsa_mode mode,
enum lws_genhash_types oaep_hashid);
/** lws_genrsa_destroy_elements() - Free allocations in genrsa_elements
*
* \param el: your struct lws_gencrypto_keyelem
*
* This is a helper for user code making use of struct lws_gencrypto_keyelem
* where the elements are allocated on the heap, it frees any non-NULL
* buf element and sets the buf to NULL.
*
* NB: lws_genrsa_public_... apis do not need this as they take care of the key
* creation and destruction themselves.
*/
LWS_VISIBLE LWS_EXTERN void
lws_genrsa_destroy_elements(struct lws_gencrypto_keyelem *el);
/** lws_genrsa_new_keypair() - Create new RSA keypair
*
* \param context: your struct lws_context (may be used for RNG)
* \param ctx: your struct lws_genrsa_ctx
* \param mode: RSA mode, one of LGRSAM_ constants
* \param el: struct to get the new key element data allocated into it
* \param bits: key size, eg, 4096
*
* Creates a new RSA context and generates a new keypair into it, with \p bits
* bits.
*
* Returns 0 for OK or nonzero for error.
*
* Mode LGRSAM_PKCS1_1_5 is in widespread use but has weaknesses. It's
* recommended to use LGRSAM_PKCS1_OAEP_PSS for new implementations.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx,
enum enum_genrsa_mode mode, struct lws_gencrypto_keyelem *el,
int bits);
/** lws_genrsa_public_encrypt() - Perform RSA public key encryption
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: plaintext input
* \param in_len: length of plaintext input
* \param out: encrypted output
*
* Performs PKCS1 v1.5 Encryption
*
* Returns <0 for error, or length of decrypted data.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
size_t in_len, uint8_t *out);
/** lws_genrsa_private_encrypt() - Perform RSA private key encryption
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: plaintext input
* \param in_len: length of plaintext input
* \param out: encrypted output
*
* Performs PKCS1 v1.5 Encryption
*
* Returns <0 for error, or length of decrypted data.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_private_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
size_t in_len, uint8_t *out);
/** lws_genrsa_public_decrypt() - Perform RSA public key decryption
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: encrypted input
* \param in_len: length of encrypted input
* \param out: decrypted output
* \param out_max: size of output buffer
*
* Performs PKCS1 v1.5 Decryption
*
* Returns <0 for error, or length of decrypted data.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
size_t in_len, uint8_t *out, size_t out_max);
/** lws_genrsa_private_decrypt() - Perform RSA private key decryption
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: encrypted input
* \param in_len: length of encrypted input
* \param out: decrypted output
* \param out_max: size of output buffer
*
* Performs PKCS1 v1.5 Decryption
*
* Returns <0 for error, or length of decrypted data.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_private_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in,
size_t in_len, uint8_t *out, size_t out_max);
/** lws_genrsa_hash_sig_verify() - Verifies RSA signature on a given hash
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: input to be hashed
* \param hash_type: one of LWS_GENHASH_TYPE_
* \param sig: pointer to the signature we received with the payload
* \param sig_len: length of the signature we are checking in bytes
*
* Returns <0 for error, or 0 if signature matches the payload + key.
*
* This just looks at a hash... that's why there's no input length
* parameter, it's decided by the choice of hash. It's up to you to confirm
* separately the actual payload matches the hash that was confirmed by this to
* be validly signed.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_hash_sig_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in,
enum lws_genhash_types hash_type,
const uint8_t *sig, size_t sig_len);
/** lws_genrsa_hash_sign() - Creates an ECDSA signature for a hash you provide
*
* \param ctx: your struct lws_genrsa_ctx
* \param in: input to be hashed and signed
* \param hash_type: one of LWS_GENHASH_TYPE_
* \param sig: pointer to buffer to take signature
* \param sig_len: length of the buffer (must be >= length of key N)
*
* Returns <0 for error, or 0 for success.
*
* This creates an RSA signature for a hash you already computed and provide.
* You should have created the hash before calling this by iterating over the
* actual payload you need to confirm.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_hash_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in,
enum lws_genhash_types hash_type,
uint8_t *sig, size_t sig_len);
/** lws_genrsa_public_decrypt_destroy() - Destroy RSA public decrypt context
*
* \param ctx: your struct lws_genrsa_ctx
*
* Destroys any allocations related to \p ctx.
*
* This and related APIs operate identically with OpenSSL or mbedTLS backends.
*/
LWS_VISIBLE LWS_EXTERN void
lws_genrsa_destroy(struct lws_genrsa_ctx *ctx);
/** lws_genrsa_render_pkey_asn1() - Exports public or private key to ASN1/DER
*
* \param ctx: your struct lws_genrsa_ctx
* \param _private: 0 = public part only, 1 = all parts of the key
* \param pkey_asn1: pointer to buffer to take the ASN1
* \param pkey_asn1_len: max size of the pkey_asn1_len
*
* Returns length of pkey_asn1 written, or -1 for error.
*/
LWS_VISIBLE LWS_EXTERN int
lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private,
uint8_t *pkey_asn1, size_t pkey_asn1_len);
///@}

View File

@ -0,0 +1,60 @@
/*
* Generic GPIO ops
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is like an abstract class for gpio, a real implementation provides
* functions for the ops that use the underlying OS gpio arrangements.
*/
#if !defined(__LWS_GPIO_H__)
#define __LWS_GPIO_H__
typedef int _lws_plat_gpio_t;
typedef enum {
LWSGGPIO_IRQ_NONE,
LWSGGPIO_IRQ_RISING,
LWSGGPIO_IRQ_FALLING,
LWSGGPIO_IRQ_CHANGE,
LWSGGPIO_IRQ_LOW,
LWSGGPIO_IRQ_HIGH
} lws_gpio_irq_t;
enum {
LWSGGPIO_FL_READ = (1 << 0),
LWSGGPIO_FL_WRITE = (1 << 1),
LWSGGPIO_FL_PULLUP = (1 << 2),
LWSGGPIO_FL_PULLDOWN = (1 << 3),
LWSGGPIO_FL_START_LOW = (1 << 4),
};
typedef void (*lws_gpio_irq_cb_t)(void *arg);
typedef struct lws_gpio_ops {
void (*mode)(_lws_plat_gpio_t gpio, int flags);
int (*read)(_lws_plat_gpio_t gpio);
void (*set)(_lws_plat_gpio_t gpio, int val);
int (*irq_mode)(_lws_plat_gpio_t gpio, lws_gpio_irq_t irq,
lws_gpio_irq_cb_t cb, void *arg);
} lws_gpio_ops_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
/*
* Generic I2C ops
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is like an abstract class for i2c, a real implementation provides
* functions for the ops that use the underlying OS arrangements.
*/
#if !defined(__LWS_I2C_H__)
#define __LWS_I2C_H__
#include <stdint.h>
#include <stddef.h>
typedef struct lws_i2c_ops {
int (*init)(const struct lws_i2c_ops *ctx);
int (*start)(const struct lws_i2c_ops *ctx);
void (*stop)(const struct lws_i2c_ops *ctx);
int (*write)(const struct lws_i2c_ops *ctx, uint8_t data);
int (*read)(const struct lws_i2c_ops *ctx);
void (*set_ack)(const struct lws_i2c_ops *octx, int ack);
} lws_i2c_ops_t;
/*
* These are implemented by calling the ops above, and so are generic
*/
LWS_VISIBLE LWS_EXTERN int
lws_i2c_command(const lws_i2c_ops_t *ctx, uint8_t ads7, uint8_t c);
LWS_VISIBLE LWS_EXTERN int
lws_i2c_command_list(const lws_i2c_ops_t *ctx, uint8_t ads7, const uint8_t *buf,
size_t len);
#endif

View File

@ -0,0 +1,54 @@
/*
* lws abstract display implementation for ili9341 on spi
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if !defined(__LWS_DISPLAY_ILI9341_SPI_H__)
#define __LWS_DISPLAY_ILI9341_SPI_H__
typedef struct lws_display_ili9341 {
lws_display_t disp; /* use lws_display_ili9341_ops to set */
const lws_spi_ops_t *spi; /* spi ops */
const lws_gpio_ops_t *gpio; /* NULL or gpio ops */
_lws_plat_gpio_t reset_gpio; /* if gpio ops, nReset gpio # */
uint8_t spi_index; /* cs index starting from 0 */
} lws_display_ili9341_t;
int
lws_display_ili9341_spi_init(const struct lws_display *disp);
int
lws_display_ili9341_spi_blit(const struct lws_display *disp, const uint8_t *src,
lws_display_scalar x, lws_display_scalar y,
lws_display_scalar w, lws_display_scalar h);
int
lws_display_ili9341_spi_power(const struct lws_display *disp, int state);
#define lws_display_ili9341_ops \
.init = lws_display_ili9341_spi_init, \
.blit = lws_display_ili9341_spi_blit, \
.power = lws_display_ili9341_spi_power
#endif

View File

@ -0,0 +1,212 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
enum lws_jws_jose_hdr_indexes {
LJJHI_ALG, /* REQUIRED */
LJJHI_JKU, /* Optional: string */
LJJHI_JWK, /* Optional: jwk JSON object: public key: */
LJJHI_KID, /* Optional: string */
LJJHI_X5U, /* Optional: string: url of public key cert / chain */
LJJHI_X5C, /* Optional: base64 (NOT -url): actual cert */
LJJHI_X5T, /* Optional: base64url: SHA-1 of actual cert */
LJJHI_X5T_S256, /* Optional: base64url: SHA-256 of actual cert */
LJJHI_TYP, /* Optional: string: media type */
LJJHI_CTY, /* Optional: string: content media type */
LJJHI_CRIT, /* Optional for send, REQUIRED: array of strings:
* mustn't contain standardized strings or null set */
LJJHI_RECIPS_HDR,
LJJHI_RECIPS_HDR_ALG,
LJJHI_RECIPS_HDR_KID,
LJJHI_RECIPS_EKEY,
LJJHI_ENC, /* JWE only: Optional: string */
LJJHI_ZIP, /* JWE only: Optional: string ("DEF" = deflate) */
LJJHI_EPK, /* Additional arg for JWE ECDH: ephemeral public key */
LJJHI_APU, /* Additional arg for JWE ECDH: base64url */
LJJHI_APV, /* Additional arg for JWE ECDH: base64url */
LJJHI_IV, /* Additional arg for JWE AES: base64url */
LJJHI_TAG, /* Additional arg for JWE AES: base64url */
LJJHI_P2S, /* Additional arg for JWE PBES2: base64url: salt */
LJJHI_P2C, /* Additional arg for JWE PBES2: integer: count */
LWS_COUNT_JOSE_HDR_ELEMENTS
};
enum lws_jose_algtype {
LWS_JOSE_ENCTYPE_NONE,
LWS_JOSE_ENCTYPE_RSASSA_PKCS1_1_5,
LWS_JOSE_ENCTYPE_RSASSA_PKCS1_OAEP,
LWS_JOSE_ENCTYPE_RSASSA_PKCS1_PSS,
LWS_JOSE_ENCTYPE_ECDSA,
LWS_JOSE_ENCTYPE_ECDHES,
LWS_JOSE_ENCTYPE_AES_CBC,
LWS_JOSE_ENCTYPE_AES_CFB128,
LWS_JOSE_ENCTYPE_AES_CFB8,
LWS_JOSE_ENCTYPE_AES_CTR,
LWS_JOSE_ENCTYPE_AES_ECB,
LWS_JOSE_ENCTYPE_AES_OFB,
LWS_JOSE_ENCTYPE_AES_XTS, /* care: requires double-length key */
LWS_JOSE_ENCTYPE_AES_GCM,
};
/* there's a table of these defined in lws-gencrypto-common.c */
struct lws_jose_jwe_alg {
enum lws_genhash_types hash_type;
enum lws_genhmac_types hmac_type;
enum lws_jose_algtype algtype_signing; /* the signing cipher */
enum lws_jose_algtype algtype_crypto; /* the encryption cipher */
const char *alg; /* the JWA enc alg name, eg "ES512" */
const char *curve_name; /* NULL, or, eg, "P-256" */
unsigned short keybits_min, keybits_fixed;
unsigned short ivbits;
};
/*
* For JWS, "JOSE header" is defined to be the union of...
*
* o JWS Protected Header
* o JWS Unprotected Header
*
* For JWE, the "JOSE header" is the union of...
*
* o JWE Protected Header
* o JWE Shared Unprotected Header
* o JWE Per-Recipient Unprotected Header
*/
#define LWS_JWS_MAX_RECIPIENTS 3
struct lws_jws_recpient {
/*
* JOSE per-recipient unprotected header... for JWS this contains
* protected / header / signature
*/
struct lws_gencrypto_keyelem unprot[LWS_COUNT_JOSE_HDR_ELEMENTS];
struct lws_jwk jwk_ephemeral; /* recipient ephemeral key if any */
struct lws_jwk jwk; /* recipient "jwk" key if any */
};
struct lws_jose {
/* JOSE protected and unprotected header elements */
struct lws_gencrypto_keyelem e[LWS_COUNT_JOSE_HDR_ELEMENTS];
struct lws_jws_recpient recipient[LWS_JWS_MAX_RECIPIENTS];
char typ[32];
/* information from the protected header part */
const struct lws_jose_jwe_alg *alg;
const struct lws_jose_jwe_alg *enc_alg;
int recipients; /* count of used recipient[] entries */
};
/**
* lws_jose_init() - prepare a struct lws_jose for use
*
* \param jose: the jose header struct to prepare
*/
LWS_VISIBLE LWS_EXTERN void
lws_jose_init(struct lws_jose *jose);
/**
* lws_jose_destroy() - retire a struct lws_jose from use
*
* \param jose: the jose header struct to destroy
*/
LWS_VISIBLE LWS_EXTERN void
lws_jose_destroy(struct lws_jose *jose);
/**
* lws_gencrypto_jws_alg_to_definition() - look up a jws alg name
*
* \param alg: the jws alg name
* \param jose: pointer to the pointer to the info struct to set on success
*
* Returns 0 if *jose set, else nonzero for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_gencrypto_jws_alg_to_definition(const char *alg,
const struct lws_jose_jwe_alg **jose);
/**
* lws_gencrypto_jwe_alg_to_definition() - look up a jwe alg name
*
* \param alg: the jwe alg name
* \param jose: pointer to the pointer to the info struct to set on success
*
* Returns 0 if *jose set, else nonzero for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_gencrypto_jwe_alg_to_definition(const char *alg,
const struct lws_jose_jwe_alg **jose);
/**
* lws_gencrypto_jwe_enc_to_definition() - look up a jwe enc name
*
* \param alg: the jwe enc name
* \param jose: pointer to the pointer to the info struct to set on success
*
* Returns 0 if *jose set, else nonzero for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_gencrypto_jwe_enc_to_definition(const char *enc,
const struct lws_jose_jwe_alg **jose);
/**
* lws_jws_parse_jose() - parse a JWS JOSE header
*
* \param jose: the jose struct to set to parsing results
* \param buf: the raw JOSE header
* \param len: the length of the raw JOSE header
* \param temp: parent-owned buffer to "allocate" elements into
* \param temp_len: amount of space available in temp
*
* returns the amount of temp used, or -1 for error
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_parse_jose(struct lws_jose *jose,
const char *buf, int len, char *temp, int *temp_len);
/**
* lws_jwe_parse_jose() - parse a JWE JOSE header
*
* \param jose: the jose struct to set to parsing results
* \param buf: the raw JOSE header
* \param len: the length of the raw JOSE header
* \param temp: parent-owned buffer to "allocate" elements into
* \param temp_len: amount of space available in temp
*
* returns the amount of temp used, or -1 for error
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwe_parse_jose(struct lws_jose *jose,
const char *buf, int len, char *temp, int *temp_len);

View File

@ -0,0 +1,164 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* JWE Compact Serialization consists of
*
* BASE64URL(UTF8(JWE Protected Header)) || '.' ||
* BASE64URL(JWE Encrypted Key) || '.' ||
* BASE64URL(JWE Initialization Vector) || '.' ||
* BASE64URL(JWE Ciphertext) || '.' ||
* BASE64URL(JWE Authentication Tag)
*/
#define LWS_JWE_RFC3394_OVERHEAD_BYTES 8
#define LWS_JWE_AES_IV_BYTES 16
#define LWS_JWE_LIMIT_RSA_KEY_BITS 4096
#define LWS_JWE_LIMIT_AES_KEY_BITS (512 + 64) /* RFC3394 Key Wrap adds 64b */
#define LWS_JWE_LIMIT_EC_KEY_BITS 528 /* 521 rounded to byte boundary */
#define LWS_JWE_LIMIT_HASH_BITS (LWS_GENHASH_LARGEST * 8)
/* the largest key element for any cipher */
#define LWS_JWE_LIMIT_KEY_ELEMENT_BYTES (LWS_JWE_LIMIT_RSA_KEY_BITS / 8)
struct lws_jwe {
struct lws_jose jose;
struct lws_jws jws;
struct lws_jwk jwk;
/*
* We have to keep a copy of the CEK so we can reuse it with later
* key encryptions for the multiple recipient case.
*/
uint8_t cek[LWS_JWE_LIMIT_KEY_ELEMENT_BYTES];
unsigned int cek_valid:1;
int recip;
};
LWS_VISIBLE LWS_EXTERN void
lws_jwe_init(struct lws_jwe *jwe, struct lws_context *context);
LWS_VISIBLE LWS_EXTERN void
lws_jwe_destroy(struct lws_jwe *jwe);
LWS_VISIBLE LWS_EXTERN void
lws_jwe_be64(uint64_t c, uint8_t *p8);
/*
* JWE Compact Serialization consists of
*
* BASE64URL(UTF8(JWE Protected Header)) || '.' ||
* BASE64URL(JWE Encrypted Key) || '.' ||
* BASE64URL(JWE Initialization Vector) || '.' ||
* BASE64URL(JWE Ciphertext) || '.' ||
* BASE64URL(JWE Authentication Tag)
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwe_render_compact(struct lws_jwe *jwe, char *out, size_t out_len);
LWS_VISIBLE int
lws_jwe_render_flattened(struct lws_jwe *jwe, char *out, size_t out_len);
LWS_VISIBLE LWS_EXTERN int
lws_jwe_json_parse(struct lws_jwe *jwe, const uint8_t *buf, int len,
char *temp, int *temp_len);
/**
* lws_jwe_auth_and_decrypt() - confirm and decrypt JWE
*
* \param jose: jose context
* \param jws: jws / jwe context... .map and .map_b64 must be filled already
*
* This is a high level JWE decrypt api that takes a jws with the maps
* already processed, and if the authentication passes, returns the decrypted
* plaintext in jws.map.buf[LJWE_CTXT] and its length in jws.map.len[LJWE_CTXT].
*
* In the jws, the following fields must have been set by the caller
*
* .context
* .jwk (the key encryption key)
* .map
* .map_b64
*
* Having the b64 and decoded maps filled externally makes it flexible where
* the data was picked from, eg, from a Complete JWE JSON serialization, a
* flattened one, or a Compact Serialization.
*
* Returns decrypt length, or -1 for failure.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwe_auth_and_decrypt(struct lws_jwe *jwe, char *temp, int *temp_len);
/**
* lws_jwe_encrypt() - perform JWE encryption
*
* \param jose: the JOSE header information (encryption types, etc)
* \param jws: the JWE elements, pointer to jwk etc
* \param temp: parent-owned buffer to "allocate" elements into
* \param temp_len: amount of space available in temp
*
* May be called up to LWS_JWS_MAX_RECIPIENTS times to encrypt the same CEK
* multiple ways on the same JWE payload.
*
* returns the amount of temp used, or -1 for error.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwe_encrypt(struct lws_jwe *jwe, char *temp, int *temp_len);
/**
* lws_jwe_create_packet() - add b64 sig to b64 hdr + payload
*
* \param jwe: the struct lws_jwe we are trying to render
* \param payload: unencoded payload JSON
* \param len: length of unencoded payload JSON
* \param nonce: Nonse string to include in protected header
* \param out: buffer to take signed packet
* \param out_len: size of \p out buffer
* \param conext: lws_context to get random from
*
* This creates a "flattened" JWS packet from the jwk and the plaintext
* payload, and signs it. The packet is written into \p out.
*
* This does the whole packet assembly and signing, calling through to
* lws_jws_sign_from_b64() as part of the process.
*
* Returns the length written to \p out, or -1.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwe_create_packet(struct lws_jwe *jwe,
const char *payload, size_t len, const char *nonce,
char *out, size_t out_len, struct lws_context *context);
/* only exposed because we have test vectors that need it */
LWS_VISIBLE LWS_EXTERN int
lws_jwe_auth_and_decrypt_cbc_hs(struct lws_jwe *jwe, uint8_t *enc_cek,
uint8_t *aad, int aad_len);
/* only exposed because we have test vectors that need it */
LWS_VISIBLE LWS_EXTERN int
lws_jwa_concat_kdf(struct lws_jwe *jwe, int direct,
uint8_t *out, const uint8_t *shared_secret, int sslen);

View File

@ -0,0 +1,220 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup jwk JSON Web Keys
* ## JSON Web Keys API
*
* Lws provides an API to parse JSON Web Keys into a struct lws_gencrypto_keyelem.
*
* "oct" and "RSA" type keys are supported. For "oct" keys, they are held in
* the "e" member of the struct lws_gencrypto_keyelem.
*
* Keys elements are allocated on the heap. You must destroy the allocations
* in the struct lws_gencrypto_keyelem by calling
* lws_genrsa_destroy_elements() when you are finished with it.
*/
///@{
enum enum_jwk_meta_tok {
JWK_META_KTY,
JWK_META_KID,
JWK_META_USE,
JWK_META_KEY_OPS,
JWK_META_X5C,
JWK_META_ALG,
LWS_COUNT_JWK_ELEMENTS
};
struct lws_jwk {
/* key data elements */
struct lws_gencrypto_keyelem e[LWS_GENCRYPTO_MAX_KEYEL_COUNT];
/* generic meta key elements, like KID */
struct lws_gencrypto_keyelem meta[LWS_COUNT_JWK_ELEMENTS];
int kty; /**< one of LWS_GENCRYPTO_KTY_ */
char private_key; /* nonzero = has private key elements */
};
typedef int (*lws_jwk_key_import_callback)(struct lws_jwk *s, void *user);
struct lws_jwk_parse_state {
struct lws_jwk *jwk;
char b64[(((8192 / 8) * 4) / 3) + 1]; /* enough for 8Kb key */
lws_jwk_key_import_callback per_key_cb;
void *user;
int pos;
int cose_state;
int seen;
unsigned short possible;
};
/** lws_jwk_import() - Create a JSON Web key from the textual representation
*
* \param jwk: the JWK object to create
* \param cb: callback for each jwk-processed key, or NULL if importing a single
* key with no parent "keys" JSON
* \param user: pointer to be passed to the callback, otherwise ignored by lws.
* NULL if importing a single key with no parent "keys" JSON
* \param in: a single JWK JSON stanza in utf-8
* \param len: the length of the JWK JSON stanza in bytes
*
* Creates an lws_jwk struct filled with data from the JSON representation.
*
* There are two ways to use this... with some protocols a single jwk is
* delivered with no parent "keys": [] array. If you call this with cb and
* user as NULL, then the input will be interpreted like that and the results
* placed in s.
*
* The second case is that you are dealing with a "keys":[] array with one or
* more keys in it. In this case, the function iterates through the keys using
* s as a temporary jwk, and calls the user-provided callback for each key in
* turn while it return 0 (nonzero return from the callback terminates the
* iteration through any further keys).
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_import(struct lws_jwk *jwk, lws_jwk_key_import_callback cb, void *user,
const char *in, size_t len);
/** lws_jwk_destroy() - Destroy a JSON Web key
*
* \param jwk: the JWK object to destroy
*
* All allocations in the lws_jwk are destroyed
*/
LWS_VISIBLE LWS_EXTERN void
lws_jwk_destroy(struct lws_jwk *jwk);
/** lws_jwk_dup_oct() - Set a jwk to a dup'd binary OCT key
*
* \param jwk: the JWK object to set
* \param key: the JWK object to destroy
* \param len: the JWK object to destroy
*
* Sets the kty to OCT, allocates len bytes for K and copies len bytes of key
* into the allocation.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_dup_oct(struct lws_jwk *jwk, const void *key, int len);
#define LWSJWKF_EXPORT_PRIVATE (1 << 0)
#define LWSJWKF_EXPORT_NOCRLF (1 << 1)
/** lws_jwk_export() - Export a JSON Web key to a textual representation
*
* \param jwk: the JWK object to export
* \param flags: control export options
* \param p: the buffer to write the exported JWK to
* \param len: the length of the buffer \p p in bytes... reduced by used amount
*
* Returns length of the used part of the buffer if OK, or -1 for error.
*
* \p flags can be OR-ed together
*
* LWSJWKF_EXPORT_PRIVATE: default is only public part, set this to also export
* the private part
*
* LWSJWKF_EXPORT_NOCRLF: normally adds a CRLF at the end of the export, if
* you need to suppress it, set this flag
*
* Serializes the content of the JWK into a char buffer.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_export(struct lws_jwk *jwk, int flags, char *p, int *len);
/** lws_jwk_load() - Import a JSON Web key from a file
*
* \param jwk: the JWK object to load into
* \param filename: filename to load from
* \param cb: optional callback for each key
* \param user: opaque user pointer passed to cb if given
*
* Returns 0 for OK or -1 for failure
*
* There are two ways to use this... with some protocols a single jwk is
* delivered with no parent "keys": [] array. If you call this with cb and
* user as NULL, then the input will be interpreted like that and the results
* placed in s.
*
* The second case is that you are dealing with a "keys":[] array with one or
* more keys in it. In this case, the function iterates through the keys using
* s as a temporary jwk, and calls the user-provided callback for each key in
* turn while it return 0 (nonzero return from the callback terminates the
* iteration through any further keys, leaving the last one in s).
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_load(struct lws_jwk *jwk, const char *filename,
lws_jwk_key_import_callback cb, void *user);
/** lws_jwk_save() - Export a JSON Web key to a file
*
* \param jwk: the JWK object to save from
* \param filename: filename to save to
*
* Returns 0 for OK or -1 for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_save(struct lws_jwk *jwk, const char *filename);
/** lws_jwk_rfc7638_fingerprint() - jwk to RFC7638 compliant fingerprint
*
* \param jwk: the JWK object to fingerprint
* \param digest32: buffer to take 32-byte digest
*
* Returns 0 for OK or -1 for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32);
/** lws_jwk_strdup_meta() - allocate a duplicated string meta element
*
* \param jwk: the JWK object to fingerprint
* \param idx: JWK_META_ element index
* \param in: string to copy
* \param len: length of string to copy
*
* Returns 0 for OK or -1 for failure
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx,
const char *in, int len);
LWS_VISIBLE LWS_EXTERN int
lws_jwk_dump(struct lws_jwk *jwk);
/** lws_jwk_generate() - create a new key of given type and characteristics
*
* \param context: the struct lws_context used for RNG
* \param jwk: the JWK object to fingerprint
* \param kty: One of the LWS_GENCRYPTO_KTY_ key types
* \param bits: for OCT and RSA keys, the number of bits
* \param curve: for EC keys, the name of the curve
*
* Returns 0 for OK or -1 for failure
*/
LWS_VISIBLE int
lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk,
enum lws_gencrypto_kty kty, int bits, const char *curve);
///@}

View File

@ -0,0 +1,599 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup jws JSON Web Signature
* ## JSON Web Signature API
*
* Lws provides an API to check and create RFC7515 JSON Web Signatures
*
* SHA256/384/512 HMAC, and RSA 256/384/512 are supported.
*
* The API uses your TLS library crypto, but works exactly the same no matter
* what your TLS backend is.
*/
///@{
/*
* The maps are built to work with both JWS (LJWS_) and JWE (LJWE_), and are
* sized to the slightly larger JWE case.
*/
enum enum_jws_sig_elements {
/* JWS block namespace */
LJWS_JOSE,
LJWS_PYLD,
LJWS_SIG,
LJWS_UHDR,
/* JWE block namespace */
LJWE_JOSE = 0,
LJWE_EKEY,
LJWE_IV,
LJWE_CTXT,
LJWE_ATAG,
LJWE_AAD,
LWS_JWS_MAX_COMPACT_BLOCKS
};
struct lws_jws_map {
const char *buf[LWS_JWS_MAX_COMPACT_BLOCKS];
uint32_t len[LWS_JWS_MAX_COMPACT_BLOCKS];
};
#define LWS_JWS_MAX_SIGS 3
struct lws_jws {
struct lws_jwk *jwk; /* the struct lws_jwk containing the signing key */
struct lws_context *context; /* the lws context (used to get random) */
struct lws_jws_map map, map_b64;
};
/* jws EC signatures do not have ASN.1 in them, meaning they're incompatible
* with generic signatures.
*/
/**
* lws_jws_init() - initialize a jws for use
*
* \param jws: pointer to the jws to initialize
* \param jwk: the jwk to use with this jws
* \param context: the lws_context to use
*/
LWS_VISIBLE LWS_EXTERN void
lws_jws_init(struct lws_jws *jws, struct lws_jwk *jwk,
struct lws_context *context);
/**
* lws_jws_destroy() - scrub a jws
*
* \param jws: pointer to the jws to destroy
*
* Call before the jws goes out of scope.
*
* Elements defined in the jws are zeroed.
*/
LWS_VISIBLE LWS_EXTERN void
lws_jws_destroy(struct lws_jws *jws);
/**
* lws_jws_sig_confirm_compact() - check signature
*
* \param map: pointers and lengths for each of the unencoded JWS elements
* \param jwk: public key
* \param context: lws_context
* \param temp: scratchpad
* \param temp_len: length of scratchpad
*
* Confirms the signature on a JWS. Use if you have non-b64 plain JWS elements
* in a map... it'll make a temp b64 version needed for comparison. See below
* for other variants.
*
* Returns 0 on match.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_sig_confirm_compact(struct lws_jws_map *map, struct lws_jwk *jwk,
struct lws_context *context,
char *temp, int *temp_len);
LWS_VISIBLE LWS_EXTERN int
lws_jws_sig_confirm_compact_b64_map(struct lws_jws_map *map_b64,
struct lws_jwk *jwk,
struct lws_context *context,
char *temp, int *temp_len);
/**
* lws_jws_sig_confirm_compact_b64() - check signature on b64 compact JWS
*
* \param in: pointer to b64 jose.payload[.hdr].sig
* \param len: bytes available at \p in
* \param map: map to take decoded non-b64 content
* \param jwk: public key
* \param context: lws_context
* \param temp: scratchpad
* \param temp_len: size of scratchpad
*
* Confirms the signature on a JWS. Use if you have you have b64 compact layout
* (jose.payload.hdr.sig) as an aggregated string... it'll make a temp plain
* version needed for comparison.
*
* Returns 0 on match.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_sig_confirm_compact_b64(const char *in, size_t len,
struct lws_jws_map *map,
struct lws_jwk *jwk,
struct lws_context *context,
char *temp, int *temp_len);
/**
* lws_jws_sig_confirm() - check signature on plain + b64 JWS elements
*
* \param map_b64: pointers and lengths for each of the b64-encoded JWS elements
* \param map: pointers and lengths for each of the unencoded JWS elements
* \param jwk: public key
* \param context: lws_context
*
* Confirms the signature on a JWS. Use if you have you already have both b64
* compact layout (jose.payload.hdr.sig) and decoded JWS elements in maps.
*
* If you had the b64 string and called lws_jws_compact_decode() on it, you
* will end up with both maps, and can use this api version, saving needlessly
* regenerating any temp map.
*
* Returns 0 on match.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */
struct lws_jws_map *map, /* non-b64 */
struct lws_jwk *jwk, struct lws_context *context);
/**
* lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload
*
* \param jose: jose header information
* \param jws: information to include in the signature
* \param b64_sig: output buffer for b64 signature
* \param sig_len: size of \p b64_sig output buffer
*
* This adds a b64-coded JWS signature of the b64-encoded protected header
* and b64-encoded payload, at \p b64_sig. The signature will be as large
* as the N element of the RSA key when the RSA key is used, eg, 512 bytes for
* a 4096-bit key, and then b64-encoding on top.
*
* In some special cases, there is only payload to sign and no header, in that
* case \p b64_hdr may be NULL, and only the payload will be hashed before
* signing.
*
* Returns the length of the encoded signature written to \p b64_sig, or -1.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_sign_from_b64(struct lws_jose *jose, struct lws_jws *jws, char *b64_sig,
size_t sig_len);
/**
* lws_jws_compact_decode() - converts and maps compact serialization b64 sections
*
* \param in: the incoming compact serialized b64
* \param len: the length of the incoming compact serialized b64
* \param map: pointer to the results structure
* \param map_b64: NULL, or pointer to a second results structure taking block
* information about the undecoded b64
* \param out: buffer to hold decoded results
* \param out_len: size of out in bytes
*
* Returns number of sections (2 if "none", else 3), or -1 if illegal.
*
* map is set to point to the start and hold the length of each decoded block.
* If map_b64 is non-NULL, then it's set with information about the input b64
* blocks.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_compact_decode(const char *in, int len, struct lws_jws_map *map,
struct lws_jws_map *map_b64, char *out, int *out_len);
LWS_VISIBLE LWS_EXTERN int
lws_jws_compact_encode(struct lws_jws_map *map_b64, /* b64-encoded */
const struct lws_jws_map *map, /* non-b64 */
char *buf, int *out_len);
LWS_VISIBLE LWS_EXTERN int
lws_jws_sig_confirm_json(const char *in, size_t len,
struct lws_jws *jws, struct lws_jwk *jwk,
struct lws_context *context,
char *temp, int *temp_len);
/**
* lws_jws_write_flattened_json() - create flattened JSON sig
*
* \param jws: information to include in the signature
* \param flattened: output buffer for JSON
* \param len: size of \p flattened output buffer
*
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_write_flattened_json(struct lws_jws *jws, char *flattened, size_t len);
/**
* lws_jws_write_compact() - create flattened JSON sig
*
* \param jws: information to include in the signature
* \param compact: output buffer for compact format
* \param len: size of \p flattened output buffer
*
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_write_compact(struct lws_jws *jws, char *compact, size_t len);
/*
* below apis are not normally needed if dealing with whole JWS... they're
* useful for creating from scratch
*/
/**
* lws_jws_dup_element() - allocate space for an element and copy data into it
*
* \param map: map to create the element in
* \param idx: index of element in the map to create
* \param temp: space to allocate in
* \param temp_len: available space at temp
* \param in: data to duplicate into element
* \param in_len: length of data to duplicate
* \param actual_alloc: 0 for same as in_len, else actual allocation size
*
* Copies in_len from in to temp, if temp_len is sufficient.
*
* Returns 0 or -1 if not enough space in temp / temp_len.
*
* Over-allocation can be acheived by setting actual_alloc to the real
* allocation desired... in_len will be copied into it.
*
* *temp_len is reduced by actual_alloc if successful.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_dup_element(struct lws_jws_map *map, int idx,
char *temp, int *temp_len, const void *in, size_t in_len,
size_t actual_alloc);
/**
* lws_jws_randomize_element() - create an element and fill with random
*
* \param context: lws_context used for random
* \param map: map to create the element in
* \param idx: index of element in the map to create
* \param temp: space to allocate in
* \param temp_len: available space at temp
* \param random_len: length of data to fill with random
* \param actual_alloc: 0 for same as random_len, else actual allocation size
*
* Randomize random_len bytes at temp, if temp_len is sufficient.
*
* Returns 0 or -1 if not enough space in temp / temp_len.
*
* Over-allocation can be acheived by setting actual_alloc to the real
* allocation desired... the first random_len will be filled with random.
*
* *temp_len is reduced by actual_alloc if successful.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_randomize_element(struct lws_context *context,
struct lws_jws_map *map,
int idx, char *temp, int *temp_len, size_t random_len,
size_t actual_alloc);
/**
* lws_jws_alloc_element() - create an element and reserve space for content
*
* \param map: map to create the element in
* \param idx: index of element in the map to create
* \param temp: space to allocate in
* \param temp_len: available space at temp
* \param len: logical length of element
* \param actual_alloc: 0 for same as len, else actual allocation size
*
* Allocate len bytes at temp, if temp_len is sufficient.
*
* Returns 0 or -1 if not enough space in temp / temp_len.
*
* Over-allocation can be acheived by setting actual_alloc to the real
* allocation desired... the element logical length will be set to len.
*
* *temp_len is reduced by actual_alloc if successful.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_alloc_element(struct lws_jws_map *map, int idx, char *temp,
int *temp_len, size_t len, size_t actual_alloc);
/**
* lws_jws_encode_b64_element() - create an b64-encoded element
*
* \param map: map to create the element in
* \param idx: index of element in the map to create
* \param temp: space to allocate in
* \param temp_len: available space at temp
* \param in: pointer to unencoded input
* \param in_len: length of unencoded input
*
* Allocate len bytes at temp, if temp_len is sufficient.
*
* Returns 0 or -1 if not enough space in temp / temp_len.
*
* Over-allocation can be acheived by setting actual_alloc to the real
* allocation desired... the element logical length will be set to len.
*
* *temp_len is reduced by actual_alloc if successful.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_encode_b64_element(struct lws_jws_map *map, int idx,
char *temp, int *temp_len, const void *in,
size_t in_len);
/**
* lws_jws_b64_compact_map() - find block starts and lengths in compact b64
*
* \param in: pointer to b64 jose.payload[.hdr].sig
* \param len: bytes available at \p in
* \param map: output struct with pointers and lengths for each JWS element
*
* Scans a jose.payload[.hdr].sig b64 string and notes where the blocks start
* and their length into \p map.
*
* Returns number of blocks if OK. May return <0 if malformed.
* May not fill all map entries.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_b64_compact_map(const char *in, int len, struct lws_jws_map *map);
/**
* lws_jws_base64_enc() - encode input data into b64url data
*
* \param in: the incoming plaintext
* \param in_len: the length of the incoming plaintext in bytes
* \param out: the buffer to store the b64url encoded data to
* \param out_max: the length of \p out in bytes
*
* Returns either -1 if problems, or the number of bytes written to \p out.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);
/**
* lws_jws_encode_section() - encode input data into b64url data,
* prepending . if not first
*
* \param in: the incoming plaintext
* \param in_len: the length of the incoming plaintext in bytes
* \param first: nonzero if the first section
* \param p: the buffer to store the b64url encoded data to
* \param end: just past the end of p
*
* Returns either -1 if problems, or the number of bytes written to \p out.
* If the section is not the first one, '.' is prepended.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jws_encode_section(const char *in, size_t in_len, int first, char **p,
char *end);
/**
* lws_jwt_signed_validate() - check a compact JWT against a key and alg
*
* \param ctx: the lws_context
* \param jwk: the key for checking the signature
* \param alg_list: the expected alg name, like "ES512"
* \param com: the compact JWT
* \param len: the length of com
* \param temp: a temp scratchpad
* \param tl: available length of temp scratchpad
* \param out: the output buffer to hold the validated plaintext
* \param out_len: on entry, max length of out; on exit, used length of out
*
* Returns nonzero if the JWT cannot be validated or the plaintext can't fit the
* provided output buffer, or 0 if it is validated as being signed by the
* provided jwk.
*
* If validated, the plaintext in the JWT is copied into out and out_len set to
* the used length.
*
* temp can be discarded or reused after the call returned, it's used to hold
* transformations of the B64 JWS in the JWT.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk,
const char *alg_list, const char *com, size_t len,
char *temp, int tl, char *out, size_t *out_len);
/**
* lws_jwt_sign_compact() - generate a compact JWT using a key and alg
*
* \param ctx: the lws_context
* \param jwk: the signing key
* \param alg: the signing alg name, like "ES512"
* \param out: the output buffer to hold the signed JWT in compact form
* \param out_len: on entry, the length of out; on exit, the used amount of out
* \param temp: a temp scratchpad
* \param tl: available length of temp scratchpad
* \param format: a printf style format specification
* \param ...: zero or more args for the format specification
*
* Creates a JWT in a single step, from the format string and args through to
* outputting a well-formed compact JWT representation in out.
*
* Returns 0 if all is well and *out_len is the amount of data in out, else
* nonzero if failed. Temp must be large enough to hold various intermediate
* representations.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk,
const char *alg, char *out, size_t *out_len, char *temp,
int tl, const char *format, ...) LWS_FORMAT(8);
struct lws_jwt_sign_info {
const char *alg;
/**< entry: signing alg name, like "RS256" */
const char *jose_hdr;
/**< entry: optional JOSE hdr; if present, alg field is ignored; instead the
* whole claim object has to be provided in this parameter */
size_t jose_hdr_len;
/**< entry: if jose_hdr is not NULL, JOSE header length without terminating '\0' */
char *out;
/**< exit: signed JWT in compact form*/
size_t *out_len;
/**< entry,exit: buffer size of out; actual size of JWT on exit */
char *temp;
/**< exit undefined content, used by the function as a temporary scratchpad; MUST
* be large enogh to store various intermediate representations */
int tl;
/**< entry: size of temp buffer */
};
/**
* lws_jwt_sign_compact() - generate a compact JWT using a key and JOSE header
*
* \param ctx: the lws_context
* \param jwk: the signing key
* \param info: info describing the JWT's content and output/temp buffers
* \param format: a printf style format specification of the claims object
* \param ...: zero or more args for the format specification
*
* Creates a JWT in a single step, from the format string and args through to
* outputting a well-formed compact JWT representation in out. The provided
* JOSE header's syntax is checked before it is added to the JWT.
*
* Returns 0 if all is well and *out_len is the amount of data in out, else
* nonzero if failed. Temp must be large enough to hold various intermediate
* representations.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwt_sign_via_info(struct lws_context *ctx, struct lws_jwk *jwk,
const struct lws_jwt_sign_info *info, const char *format, ...) LWS_FORMAT(4);
/**
* lws_jwt_token_sanity() - check a validated jwt payload for sanity
*
* \param in: the JWT payload
* \param in_len: the length of the JWT payload
* \param iss: the expected issuer of the token
* \param aud: the expected audience of the token
* \param csrf_in: NULL, or the csrf token that came in on a URL
* \param sub: a buffer to hold the subject name in the JWT (eg, account name)
* \param sub_len: the max length of the sub buffer
* \param secs_left: set to the number of seconds of valid auth left if valid
*
* This performs some generic sanity tests on validated JWT payload...
*
* - the issuer is as expected
* - the audience is us
* - current time is OK for nbf ("not before") in the token
* - current time is OK for exp ("expiry") in the token
* - if csrf_in is not NULL, that the JWK has a csrf and it matches it
* - if sub is not NULL, that the JWK provides a subject (and copies it to sub)
*
* If the tests pass, *secs_left is set to the number of remaining seconds the
* auth is valid.
*
* Returns 0 if no inconsistency, else nonzero.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwt_token_sanity(const char *in, size_t in_len,
const char *iss, const char *aud, const char *csrf_in,
char *sub, size_t sub_len, unsigned long *exp_unix_time);
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
struct lws_jwt_sign_set_cookie {
struct lws_jwk *jwk;
/**< entry: required signing key */
const char *alg;
/**< entry: required signing alg, eg, "ES512" */
const char *iss;
/**< entry: issuer name to use */
const char *aud;
/**< entry: audience */
const char *cookie_name;
/**< entry: the name of the cookie */
char sub[33];
/**< sign-entry, validate-exit: subject */
const char *extra_json;
/**< sign-entry, validate-exit:
* optional "ext" JSON object contents for the JWT */
size_t extra_json_len;
/**< validate-exit:
* length of optional "ext" JSON object contents for the JWT */
const char *csrf_in;
/**< validate-entry:
* NULL, or an external CSRF token to check against what is in the JWT */
unsigned long expiry_unix_time;
/**< sign-entry: seconds the JWT and cookie may live,
* validate-exit: expiry unix time */
};
/**
* lws_jwt_sign_token_set_cookie() - creates sets a JWT in a wsi cookie
*
* \param wsi: the wsi to create the cookie header on
* \param i: structure describing what should be in the JWT
* \param p: wsi headers area
* \param end: end of wsi headers area
*
* Creates a JWT specified \p i, and attaches it to the outgoing headers on
* wsi. Returns 0 if successful.
*
* Best-practice security restrictions are applied to the cookie set action,
* including forcing httponly, and __Host- prefix. As required by __Host-, the
* cookie Path is set to /. __Host- is applied by the function, the cookie_name
* should just be "xyz" for "__Host-xyz".
*
* \p extra_json should just be the bare JSON, a { } is provided around it by
* the function if it's non-NULL. For example, "\"authorization\": 1".
*
* It's recommended the secs parameter is kept as small as consistent with one
* user session on the site if possible, eg, 10 minutes or 20 minutes. At the
* server, it can determine how much time is left in the auth and inform the
* client; if the JWT validity expires, the page should reload so the UI always
* reflects what's possible to do with the authorization state correctly. If
* the JWT expires, the user can log back in using credentials usually stored in
* the browser and auto-filled-in, so this is not very inconvenient.
*
* This is a helper on top of the other JOSE and JWT apis that somewhat crosses
* over between JWT and HTTP, since it knows about cookies. So it is only built
* if both LWS_WITH_JOSE and one of the http-related roles enabled.
*/
LWS_VISIBLE LWS_EXTERN int
lws_jwt_sign_token_set_http_cookie(struct lws *wsi,
const struct lws_jwt_sign_set_cookie *i,
uint8_t **p, uint8_t *end);
LWS_VISIBLE LWS_EXTERN int
lws_jwt_get_http_cookie_validate_jwt(struct lws *wsi,
struct lws_jwt_sign_set_cookie *i,
char *out, size_t *out_len);
#endif
///@}

View File

@ -0,0 +1,542 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup lecp CBOR parser
* ##CBOR parsing related functions
* \ingroup lwsapi
*
* LECP is an extremely lightweight CBOR stream parser included in lws. It
* is aligned in approach with the LEJP JSON stream parser, with some additional
* things needed for CBOR.
*/
//@{
#ifndef LECP_MAX_PARSING_STACK_DEPTH
#define LECP_MAX_PARSING_STACK_DEPTH 5
#endif
#ifndef LECP_MAX_DEPTH
#define LECP_MAX_DEPTH 12
#endif
#ifndef LECP_MAX_INDEX_DEPTH
#define LECP_MAX_INDEX_DEPTH 8
#endif
#ifndef LECP_MAX_PATH
#define LECP_MAX_PATH 128
#endif
#ifndef LECP_STRING_CHUNK
/* must be >= 30 to assemble floats */
#define LECP_STRING_CHUNK 254
#endif
#define LECP_FLAG_CB_IS_VALUE 64
/*
* CBOR initial byte 3 x MSB bits are these
*/
enum {
LWS_CBOR_MAJTYP_UINT = 0 << 5,
LWS_CBOR_MAJTYP_INT_NEG = 1 << 5,
LWS_CBOR_MAJTYP_BSTR = 2 << 5,
LWS_CBOR_MAJTYP_TSTR = 3 << 5,
LWS_CBOR_MAJTYP_ARRAY = 4 << 5,
LWS_CBOR_MAJTYP_MAP = 5 << 5,
LWS_CBOR_MAJTYP_TAG = 6 << 5,
LWS_CBOR_MAJTYP_FLOAT = 7 << 5, /* also BREAK */
LWS_CBOR_MAJTYP_MASK = 7 << 5,
/*
* For the low 5 bits of the opcode, 0-23 are literals, unless it's
* FLOAT.
*
* 24 = 1 byte; 25 = 2..., 26 = 4... and 27 = 8 bytes following literal.
*/
LWS_CBOR_1 = 24,
LWS_CBOR_2 = 25,
LWS_CBOR_4 = 26,
LWS_CBOR_8 = 27,
LWS_CBOR_RESERVED = 28,
LWS_CBOR_SUBMASK = 0x1f,
/*
* Major type 7 discriminators in low 5 bits
* 0 - 23 is SIMPLE implicit value (like, eg, LWS_CBOR_SWK_TRUE)
*/
LWS_CBOR_SWK_FALSE = 20,
LWS_CBOR_SWK_TRUE = 21,
LWS_CBOR_SWK_NULL = 22,
LWS_CBOR_SWK_UNDEFINED = 23,
LWS_CBOR_M7_SUBTYP_SIMPLE_X8 = 24, /* simple with additional byte */
LWS_CBOR_M7_SUBTYP_FLOAT16 = 25,
LWS_CBOR_M7_SUBTYP_FLOAT32 = 26,
LWS_CBOR_M7_SUBTYP_FLOAT64 = 27,
LWS_CBOR_M7_BREAK = 31,
/* 28, 29, 30 are illegal.
*
* 31 is illegal for UINT, INT_NEG, and TAG;
* for BSTR, TSTR, ARRAY and MAP it means "indefinite length", ie,
* it's made up of an endless amount of determinite-length
* fragments terminated with a BREAK (FLOAT | 31) instead of the
* next determinite-length fragment. The second framing level
* means no need for escapes for BREAK in the data.
*/
LWS_CBOR_INDETERMINITE = 31,
/*
* Well-known tags
*/
LWS_CBOR_WKTAG_DATETIME_STD = 0, /* text */
LWS_CBOR_WKTAG_DATETIME_EPOCH = 1, /* int or float */
LWS_CBOR_WKTAG_BIGNUM_UNSIGNED = 2, /* byte string */
LWS_CBOR_WKTAG_BIGNUM_NEGATIVE = 3, /* byte string */
LWS_CBOR_WKTAG_DECIMAL_FRAC = 4, /* array */
LWS_CBOR_WKTAG_BIGFLOAT = 5, /* array */
LWS_CBOR_WKTAG_COSE_ENC0 = 16,
LWS_CBOR_WKTAG_COSE_MAC0 = 17,
LWS_CBOR_WKTAG_COSE_SIGN1 = 18,
LWS_CBOR_WKTAG_TO_B64U = 21, /* any */
LWS_CBOR_WKTAG_TO_B64 = 22, /* any */
LWS_CBOR_WKTAG_TO_B16 = 23, /* any */
LWS_CBOR_WKTAG_CBOR = 24, /* byte string */
LWS_CBOR_WKTAG_URI = 32, /* text string */
LWS_CBOR_WKTAG_B64U = 33, /* text string */
LWS_CBOR_WKTAG_B64 = 34, /* text string */
LWS_CBOR_WKTAG_MIME = 36, /* text string */
LWS_CBOR_WKTAG_COSE_ENC = 96,
LWS_CBOR_WKTAG_COSE_MAC = 97,
LWS_CBOR_WKTAG_COSE_SIGN = 98,
LWS_CBOR_WKTAG_SELFDESCCBOR = 55799
};
enum lecp_callbacks {
LECPCB_CONSTRUCTED = 0,
LECPCB_DESTRUCTED = 1,
LECPCB_COMPLETE = 3,
LECPCB_FAILED = 4,
LECPCB_PAIR_NAME = 5,
LECPCB_VAL_TRUE = LECP_FLAG_CB_IS_VALUE | 6,
LECPCB_VAL_FALSE = LECP_FLAG_CB_IS_VALUE | 7,
LECPCB_VAL_NULL = LECP_FLAG_CB_IS_VALUE | 8,
LECPCB_VAL_NUM_INT = LECP_FLAG_CB_IS_VALUE | 9,
LECPCB_VAL_RESERVED = LECP_FLAG_CB_IS_VALUE | 10,
LECPCB_VAL_STR_START = 11, /* notice handle separately */
LECPCB_VAL_STR_CHUNK = LECP_FLAG_CB_IS_VALUE | 12,
LECPCB_VAL_STR_END = LECP_FLAG_CB_IS_VALUE | 13,
LECPCB_ARRAY_START = 14,
LECPCB_ARRAY_END = 15,
LECPCB_OBJECT_START = 16,
LECPCB_OBJECT_END = 17,
LECPCB_TAG_START = 18,
LECPCB_TAG_END = 19,
LECPCB_VAL_NUM_UINT = LECP_FLAG_CB_IS_VALUE | 20,
LECPCB_VAL_UNDEFINED = LECP_FLAG_CB_IS_VALUE | 21,
LECPCB_VAL_FLOAT16 = LECP_FLAG_CB_IS_VALUE | 22,
LECPCB_VAL_FLOAT32 = LECP_FLAG_CB_IS_VALUE | 23,
LECPCB_VAL_FLOAT64 = LECP_FLAG_CB_IS_VALUE | 24,
LECPCB_VAL_SIMPLE = LECP_FLAG_CB_IS_VALUE | 25,
LECPCB_VAL_BLOB_START = 26, /* notice handle separately */
LECPCB_VAL_BLOB_CHUNK = LECP_FLAG_CB_IS_VALUE | 27,
LECPCB_VAL_BLOB_END = LECP_FLAG_CB_IS_VALUE | 28,
LECPCB_ARRAY_ITEM_START = 29,
LECPCB_ARRAY_ITEM_END = 30,
LECPCB_LITERAL_CBOR = 31,
};
enum lecp_reasons {
LECP_CONTINUE = -1,
LECP_REJECT_BAD_CODING = -2,
LECP_REJECT_UNKNOWN = -3,
LECP_REJECT_CALLBACK = -4,
LECP_STACK_OVERFLOW = -5,
};
struct lecp_item {
union {
uint64_t u64;
int64_t i64;
uint64_t u32;
uint16_t hf;
#if defined(LWS_WITH_CBOR_FLOAT)
float f;
double d;
#else
uint32_t f;
uint64_t d;
#endif
} u;
uint8_t opcode;
};
struct lecp_ctx;
typedef signed char (*lecp_callback)(struct lecp_ctx *ctx, char reason);
struct _lecp_stack {
char s; /* lejp_state stack*/
uint8_t p; /* path length */
char i; /* index array length */
char indet; /* indeterminite */
char intermediate; /* in middle of string */
char pop_iss;
uint64_t tag;
uint64_t collect_rem;
uint32_t ordinal;
uint8_t opcode;
uint8_t send_new_array_item;
uint8_t barrier;
};
struct _lecp_parsing_stack {
void *user; /* private to the stack level */
lecp_callback cb;
const char * const *paths;
uint8_t count_paths;
uint8_t ppos;
uint8_t path_match;
};
struct lecp_ctx {
/* sorted by type for most compact alignment
*
* pointers
*/
void *user;
uint8_t *collect_tgt;
/* arrays */
struct _lecp_parsing_stack pst[LECP_MAX_PARSING_STACK_DEPTH];
struct _lecp_stack st[LECP_MAX_DEPTH];
uint16_t i[LECP_MAX_INDEX_DEPTH]; /* index array */
uint16_t wild[LECP_MAX_INDEX_DEPTH]; /* index array */
char path[LECP_MAX_PATH];
uint8_t cbor[64]; /* literal cbor capture */
struct lecp_item item;
/* size_t */
size_t path_stride; /* 0 means default ptr size, else
* stride... allows paths to be
* provided composed inside a
* larger user struct instead of a
* duplicated array */
size_t used_in; /* bytes of input consumed */
/* short */
uint16_t uni;
/* char */
uint8_t npos;
uint8_t dcount;
uint8_t f;
uint8_t sp; /* stack head */
uint8_t ipos; /* index stack depth */
uint8_t count_paths;
uint8_t path_match;
uint8_t path_match_len;
uint8_t wildcount;
uint8_t pst_sp; /* parsing stack head */
uint8_t outer_array;
uint8_t cbor_pos;
uint8_t literal_cbor_report;
char present; /* temp for cb reason to use */
uint8_t be; /* big endian */
/* at end so we can memset the rest of it */
char buf[LECP_STRING_CHUNK + 1];
};
struct lws_lec_pctx;
typedef struct lws_lec_pctx lws_lec_pctx_t;
enum lws_lec_pctx_ret {
LWS_LECPCTX_RET_FINISHED = 0,
LWS_LECPCTX_RET_AGAIN, /* call again to continue writing buffer */
LWS_LECPCTX_RET_FAIL /* something broken, eg, format string */
};
enum cbp_state {
CBPS_IDLE,
CBPS_PC1,
CBPS_PC2,
CBPS_PC3,
CBPS_STRING_BODY,
CBPS_NUM_LIT,
CBPS_STRING_LIT,
CBPS_CONTYPE,
};
typedef struct lws_lec_pctx {
uint8_t stack[16];
uint8_t vaa[16];
uint8_t indet[16];
uint8_t scratch[24];
uint8_t *start; /* the beginning of the out buf */
uint8_t *buf; /* cur pos in output buf */
uint8_t *end; /* the end of the output buf */
const uint8_t *ongoing_src;
uint64_t ongoing_len;
uint64_t ongoing_done;
struct lecp_item item;
size_t used; /* number of bytes valid from start */
int opaque[4]; /* ignored by lws, caller may use */
enum cbp_state state;
unsigned int fmt_pos;
uint8_t sp;
uint8_t scratch_len;
uint8_t escflag;
uint8_t _long;
uint8_t vaa_pos;
uint8_t dotstar;
} lws_lec_pctx_t;
LWS_VISIBLE LWS_EXTERN void
lws_lec_int(lws_lec_pctx_t *ctx, uint8_t opcode, uint8_t indet, uint64_t num);
LWS_VISIBLE LWS_EXTERN int
lws_lec_scratch(lws_lec_pctx_t *ctx);
/*
* lws_lec_init() - prepare a cbor writing context
*
* \param ctx: the cbor writing context to prepare
* \param buf: the output buffer start
* \param len: the amount of the output buffer we can use
*
* Prepares a cbor writing context so that les_lec_printf can be used to
* write into it.
*/
LWS_VISIBLE LWS_EXTERN void
lws_lec_init(lws_lec_pctx_t *ctx, uint8_t *buf, size_t len);
/*
* lws_lec_setbuf() - update the output buffer for an initialized cbor writing ctx
*
* \param ctx: the cbor writing context to prepare
* \param buf: the output buffer start
* \param len: the amount of the output buffer we can use
*
* Leaves the cbor writing context state as it is, but resets the output buffer
* it writes into as given in \p buf and \p len
*/
LWS_VISIBLE LWS_EXTERN void
lws_lec_setbuf(lws_lec_pctx_t *ctx, uint8_t *buf, size_t len);
/*
* lws_lec_vsprintf() - write into a cbor writing context
*
* \param ctx: the cbor writing context to prepare
* \param format: a printf style argument map
* \param args: the va args
*
* CBOR-aware vsprintf which pauses output when it fills the output buffer. You
* can call it again with the same args and same lws_lex_pctx to resume filling
*
* Returns either LWS_LECPCTX_RET_FINISHED if we have nothing left over that we
* want to put in the buffer, or LWS_LECPCTX_RET_AGAIN if the function should
* be called again with the same arguments (perhaps into a different output
* buffer) to continue emitting output from where it left off.
*
* If LWS_LECPCTX_RET_AGAIN is returned, lws_lec_setbuf() must be used on the
* context to reset or change the output buffer before calling again.
*
* The number of bytes placed in the output buffer is available in ctx->used.
*
* \p format is a printf-type format string that is specialized for CBOR
* generation. It understands the following specifiers
*
* |`123`||unsigned literal number|
* |`-123`||signed literal number|
* |`%u`|`unsigned int`|number|
* |`%lu`|`unsigned long int`|number|
* |`%llu`|`unsigned long long int`|number|
* |`%d`|`signed int`|number|
* |`%ld`|`signed long int`|number|
* |`%lld`|`signed long long int`|number|
* |`%f`|`double`|floating point number|
* |`123(...)`||literal tag and scope|
* |`%t(...)`|`unsigned int`|tag and scope|
* |`%lt(...)`|`unsigned long int`|tag and scope|
* |`%llt(...)`|`unsigned long long int`|tag and scope|
* |`[...]`||Array (fixed len if `]` in same format string)|
* |`{...}`||Map (fixed len if `}` in same format string)|
* |`<t...>`||Container for indeterminite text string frags|
* |`<b...>`||Container for indeterminite binary string frags|
* |`'string'`||Literal text of known length|
* |`%s`|`const char *`|NUL-terminated string|
* |`%.*s`|`int`, `const char *`|length-specified string|
* |`%.*b`|`int`, `const uint8_t *`|length-specified binary|
* |`:`||separator between Map items (a:b)|
* |`,`||separator between Map pairs or array items|
*
* See READMEs/README.cbor-lecp.md for more details.
*/
LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
lws_lec_vsprintf(lws_lec_pctx_t *ctx, const char *format, va_list args);
/*
* lws_lec_printf() - write into a cbor writing context
*
* \param ctx: the cbor writing context to prepare
* \param format: a printf style argument map
* \param ...: format args
*
* See lws_lec_vsprintf() for format details. This is the most common way
* to format the CBOR output.
*
* See READMEs/README.cbor-lecp.md for more details.
*/
LWS_VISIBLE LWS_EXTERN enum lws_lec_pctx_ret
lws_lec_printf(lws_lec_pctx_t *ctx, const char *format, ...);
/**
* lecp_construct() - Construct an LECP parser context
*
* \param ctx: the parser context object to be initialized
* \param cb: the user callback to receive the parsing events
* \param user: an opaque user pointer available at \p cb
* \param paths: an optional array of parsing paths
* \param paths_count: how many paths in \p paths
*
* Prepares an LECP parser context for parsing.
*/
LWS_VISIBLE LWS_EXTERN void
lecp_construct(struct lecp_ctx *ctx, lecp_callback cb, void *user,
const char * const *paths, unsigned char paths_count);
/**
* lecp_destruct() - Destroys an LECP parser context
*
* \param ctx: the parser context object to be destroyed
*/
LWS_VISIBLE LWS_EXTERN void
lecp_destruct(struct lecp_ctx *ctx);
/**
* lecp_parse() - parses a chunk of input CBOR
*
* \p ctx: the parsing context
* \p cbor: the start of the chunk of CBOR
* \p len: the number of bytes of CBOR available at \p cbor
*
* Returns LECP_CONTINUE if more input needed, one of enum lecp_reasons for a
* fatal error, else 0 for successful parsing completion.
*
* On success or _CONTINUE, ctx->used_in is set to the number of input bytes
* consumed.
*/
LWS_VISIBLE LWS_EXTERN int
lecp_parse(struct lecp_ctx *ctx, const uint8_t *cbor, size_t len);
LWS_VISIBLE LWS_EXTERN void
lecp_change_callback(struct lecp_ctx *ctx, lecp_callback cb);
LWS_VISIBLE LWS_EXTERN const char *
lecp_error_to_string(int e);
/**
* lecp_parse_report_raw() - turn cbor raw reporting on and off
*
* \param ctx: the lecp context
* \param on: 0 to disable (defaults disabled), 1 to enable
*
* For cose_sign, it needs access to raw cbor subtrees for the hash input.
* This api causes LECPCB_LITERAL_CBOR parse callbacks when there are
* ctx->cbor_pos bytes of raw cbor available in ctx->cbor[]. the callbacks
* occur when the ctx->cbor[] buffer fills or if it holds anything when this
* spi is used to stop the reports.
*
* The same CBOR that is being captured continues to be passed for parsing.
*/
LWS_VISIBLE LWS_EXTERN void
lecp_parse_report_raw(struct lecp_ctx *ctx, int on);
/**
* lecp_parse_map_is_key() - return nonzero if we're in a map and this is a key
*
* \param ctx: the lwcp context
*
* Checks if the current value is a key in a map, ie, that you are on a "key" in
* a list of "{key: value}" pairs. Zero means you're either not in a map or not
* on the key part, and nonzero means you are in a map and on a key part.
*/
LWS_VISIBLE LWS_EXTERN int
lecp_parse_map_is_key(struct lecp_ctx *ctx);
LWS_VISIBLE LWS_EXTERN int
lecp_parse_subtree(struct lecp_ctx *ctx, const uint8_t *in, size_t len);
/*
* Helpers for half-float
*/
LWS_VISIBLE LWS_EXTERN void
lws_singles2halfp(uint16_t *hp, uint32_t x);
LWS_VISIBLE LWS_EXTERN void
lws_halfp2singles(uint32_t *xp, uint16_t h);
//@}

View File

@ -0,0 +1,146 @@
/*
* Generic LED controller ops
*
* Copyright (C) 2019 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* This is like an abstract class for leds, a real implementation provides
* functions for the ops that use the underlying, eg, OS gpio arrangements.
*/
/* only b15 significant for GPIO */
typedef uint16_t lws_led_intensity_t;
typedef uint16_t lws_led_seq_phase_t;
/* the normalized max intensity */
#define LWS_LED_MAX_INTENSITY (0xffff)
/* the normalized 360 degree phase count for intensity functions */
#define LWS_LED_FUNC_PHASE 65536
/* used when the sequence doesn't stop by itself and goes around forever */
#define LWS_SEQ_LEDPHASE_TOTAL_ENDLESS (-1)
#define LWS_LED_SEQUENCER_UPDATE_INTERVAL_MS 33
struct lws_led_state; /* opaque */
struct lws_pwm_ops; /* forward ref */
typedef lws_led_intensity_t (*lws_led_lookup_t)(lws_led_seq_phase_t ph);
typedef struct lws_led_sequence_def_t {
lws_led_lookup_t func;
lws_led_seq_phase_t ledphase_offset;
int ledphase_total; /* 65536= one cycle */
uint16_t ms;
uint8_t flags;
} lws_led_sequence_def_t;
enum {
LLSI_CURR,
LLSI_NEXT,
LLSI_TRANS
};
typedef struct lws_led_state_ch
{
const lws_led_sequence_def_t *seq; /* NULL = inactive */
lws_led_seq_phase_t ph;
lws_led_seq_phase_t step;
int phase_budget;
lws_led_intensity_t last;
/**< at the end of the sequence we decouple the sequencer, but leave
* the last computed sample behind for further transitions to base off
*/
} lws_led_state_ch_t;
typedef struct lws_led_state_chs
{
lws_led_state_ch_t seqs[3];
} lws_led_state_chs_t;
/* this should always be first in the subclassed implementation types */
typedef struct lws_led_ops {
void (*intensity)(const struct lws_led_ops *lo, const char *name,
lws_led_intensity_t inten);
/**< for BOOL led control like GPIO, only inten b15 is significant */
struct lws_led_state * (*create)(const struct lws_led_ops *led_ops);
void (*destroy)(struct lws_led_state *);
} lws_led_ops_t;
typedef struct lws_led_gpio_map {
const char *name;
_lws_plat_gpio_t gpio;
lws_led_lookup_t intensity_correction;
/**< May be NULL. If GPIO-based LED, ignored. If pwm_ops provided,
* NULL means use default CIE 100% correction function. If non-NULL,
* use the pointed-to correction function. This is useful to provide
* LED-specific intensity correction / scaling so different types of
* LED can "look the same". */
const struct lws_pwm_ops *pwm_ops;
/**< if NULL, gpio controls the led directly. If set to a pwm_ops,
* the led control is outsourced to the pwm controller. */
uint8_t active_level;
} lws_led_gpio_map_t;
typedef struct lws_led_gpio_controller {
const lws_led_ops_t led_ops;
const lws_gpio_ops_t *gpio_ops;
const lws_led_gpio_map_t *led_map;
uint8_t count_leds;
} lws_led_gpio_controller_t;
/* ops */
LWS_VISIBLE LWS_EXTERN struct lws_led_state *
lws_led_gpio_create(const lws_led_ops_t *led_ops);
LWS_VISIBLE LWS_EXTERN void
lws_led_gpio_destroy(struct lws_led_state *lcs);
/**
* lws_led_gpio_intensity() - set the static intensity of an led
*
* \param lo: the base class of the led controller
* \param index: which led in the controller set
* \param inten: 16-bit unsigned intensity
*
* For LEDs controlled by a BOOL like GPIO, only inten b15 is significant.
* For PWM type LED control, as many bits as the hardware can support from b15
* down are significant.
*/
LWS_VISIBLE LWS_EXTERN void
lws_led_gpio_intensity(const struct lws_led_ops *lo, const char *name,
lws_led_intensity_t inten);
LWS_VISIBLE LWS_EXTERN int
lws_led_transition(struct lws_led_state *lcs, const char *name,
const lws_led_sequence_def_t *next,
const lws_led_sequence_def_t *trans);
#define lws_led_gpio_ops \
{ \
.create = lws_led_gpio_create, \
.destroy = lws_led_gpio_destroy, \
.intensity = lws_led_gpio_intensity, \
}

View File

@ -0,0 +1,301 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup lejp JSON parser
* ##JSON parsing related functions
* \ingroup lwsapi
*
* LEJP is an extremely lightweight JSON stream parser included in lws.
*/
//@{
struct lejp_ctx;
#if !defined(LWS_ARRAY_SIZE)
#define LWS_ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0]))
#endif
#define LEJP_FLAG_WS_KEEP 64
#define LEJP_FLAG_WS_COMMENTLINE 32
enum lejp_states {
LEJP_IDLE = 0,
LEJP_MEMBERS = 1,
LEJP_M_P = 2,
LEJP_MP_STRING = LEJP_FLAG_WS_KEEP | 3,
LEJP_MP_STRING_ESC = LEJP_FLAG_WS_KEEP | 4,
LEJP_MP_STRING_ESC_U1 = LEJP_FLAG_WS_KEEP | 5,
LEJP_MP_STRING_ESC_U2 = LEJP_FLAG_WS_KEEP | 6,
LEJP_MP_STRING_ESC_U3 = LEJP_FLAG_WS_KEEP | 7,
LEJP_MP_STRING_ESC_U4 = LEJP_FLAG_WS_KEEP | 8,
LEJP_MP_DELIM = 9,
LEJP_MP_VALUE = 10,
LEJP_MP_VALUE_NUM_INT = LEJP_FLAG_WS_KEEP | 11,
LEJP_MP_VALUE_NUM_EXP = LEJP_FLAG_WS_KEEP | 12,
LEJP_MP_VALUE_TOK = LEJP_FLAG_WS_KEEP | 13,
LEJP_MP_COMMA_OR_END = 14,
LEJP_MP_ARRAY_END = 15,
};
enum lejp_reasons {
LEJP_CONTINUE = -1,
LEJP_REJECT_IDLE_NO_BRACE = -2,
LEJP_REJECT_MEMBERS_NO_CLOSE = -3,
LEJP_REJECT_MP_NO_OPEN_QUOTE = -4,
LEJP_REJECT_MP_STRING_UNDERRUN = -5,
LEJP_REJECT_MP_ILLEGAL_CTRL = -6,
LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC = -7,
LEJP_REJECT_ILLEGAL_HEX = -8,
LEJP_REJECT_MP_DELIM_MISSING_COLON = -9,
LEJP_REJECT_MP_DELIM_BAD_VALUE_START = -10,
LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC = -11,
LEJP_REJECT_MP_VAL_NUM_FORMAT = -12,
LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP = -13,
LEJP_REJECT_MP_VAL_TOK_UNKNOWN = -14,
LEJP_REJECT_MP_C_OR_E_UNDERF = -15,
LEJP_REJECT_MP_C_OR_E_NOTARRAY = -16,
LEJP_REJECT_MP_ARRAY_END_MISSING = -17,
LEJP_REJECT_STACK_OVERFLOW = -18,
LEJP_REJECT_MP_DELIM_ISTACK = -19,
LEJP_REJECT_NUM_TOO_LONG = -20,
LEJP_REJECT_MP_C_OR_E_NEITHER = -21,
LEJP_REJECT_UNKNOWN = -22,
LEJP_REJECT_CALLBACK = -23
};
#define LEJP_FLAG_CB_IS_VALUE 64
enum lejp_callbacks {
LEJPCB_CONSTRUCTED = 0,
LEJPCB_DESTRUCTED = 1,
LEJPCB_START = 2,
LEJPCB_COMPLETE = 3,
LEJPCB_FAILED = 4,
LEJPCB_PAIR_NAME = 5,
LEJPCB_VAL_TRUE = LEJP_FLAG_CB_IS_VALUE | 6,
LEJPCB_VAL_FALSE = LEJP_FLAG_CB_IS_VALUE | 7,
LEJPCB_VAL_NULL = LEJP_FLAG_CB_IS_VALUE | 8,
LEJPCB_VAL_NUM_INT = LEJP_FLAG_CB_IS_VALUE | 9,
LEJPCB_VAL_NUM_FLOAT = LEJP_FLAG_CB_IS_VALUE | 10,
LEJPCB_VAL_STR_START = 11, /* notice handle separately */
LEJPCB_VAL_STR_CHUNK = LEJP_FLAG_CB_IS_VALUE | 12,
LEJPCB_VAL_STR_END = LEJP_FLAG_CB_IS_VALUE | 13,
LEJPCB_ARRAY_START = 14,
LEJPCB_ARRAY_END = 15,
LEJPCB_OBJECT_START = 16,
LEJPCB_OBJECT_END = 17,
};
/**
* _lejp_callback() - User parser actions
* \param ctx: LEJP context
* \param reason: Callback reason
*
* Your user callback is associated with the context at construction time,
* and receives calls as the parsing progresses.
*
* All of the callbacks may be ignored and just return 0.
*
* The reasons it might get called, found in @reason, are:
*
* LEJPCB_CONSTRUCTED: The context was just constructed... you might want to
* perform one-time allocation for the life of the context.
*
* LEJPCB_DESTRUCTED: The context is being destructed... if you made any
* allocations at construction-time, you can free them now
*
* LEJPCB_START: Parsing is beginning at the first byte of input
*
* LEJPCB_COMPLETE: Parsing has completed successfully. You'll get a 0 or
* positive return code from lejp_parse indicating the
* amount of unused bytes left in the input buffer
*
* LEJPCB_FAILED: Parsing failed. You'll get a negative error code
* returned from lejp_parse
*
* LEJPCB_PAIR_NAME: When a "name":"value" pair has had the name parsed,
* this callback occurs. You can find the new name at
* the end of ctx->path[]
*
* LEJPCB_VAL_TRUE: The "true" value appeared
*
* LEJPCB_VAL_FALSE: The "false" value appeared
*
* LEJPCB_VAL_NULL: The "null" value appeared
*
* LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx->buf
*
* LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf
*
* LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet
*
* LEJPCB_VAL_STR_CHUNK: We filled the string buffer in the ctx, but it's not
* the end of the string. We produce this to spill the
* intermediate buffer to the user code, so we can handle
* huge JSON strings using only the small buffer in the
* ctx. If the whole JSON string fits in the ctx buffer,
* you won't get these callbacks.
*
* LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the
* string is in ctx->buf.
*
* LEJPCB_ARRAY_START: An array started
*
* LEJPCB_ARRAY_END: An array ended
*
* LEJPCB_OBJECT_START: An object started
*
* LEJPCB_OBJECT_END: An object ended
*/
LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason);
typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason);
#ifndef LEJP_MAX_PARSING_STACK_DEPTH
#define LEJP_MAX_PARSING_STACK_DEPTH 5
#endif
#ifndef LEJP_MAX_DEPTH
#define LEJP_MAX_DEPTH 12
#endif
#ifndef LEJP_MAX_INDEX_DEPTH
#define LEJP_MAX_INDEX_DEPTH 8
#endif
#ifndef LEJP_MAX_PATH
#define LEJP_MAX_PATH 128
#endif
#ifndef LEJP_STRING_CHUNK
/* must be >= 30 to assemble floats */
#define LEJP_STRING_CHUNK 254
#endif
enum num_flags {
LEJP_SEEN_MINUS = (1 << 0),
LEJP_SEEN_POINT = (1 << 1),
LEJP_SEEN_POST_POINT = (1 << 2),
LEJP_SEEN_EXP = (1 << 3)
};
struct _lejp_stack {
char s; /* lejp_state stack*/
char p; /* path length */
char i; /* index array length */
char b; /* user bitfield */
};
struct _lejp_parsing_stack {
void *user; /* private to the stack level */
signed char (*callback)(struct lejp_ctx *ctx, char reason);
const char * const *paths;
uint8_t count_paths;
uint8_t ppos;
uint8_t path_match;
};
struct lejp_ctx {
/* sorted by type for most compact alignment
*
* pointers
*/
void *user;
/* arrays */
struct _lejp_parsing_stack pst[LEJP_MAX_PARSING_STACK_DEPTH];
struct _lejp_stack st[LEJP_MAX_DEPTH];
uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */
uint16_t wild[LEJP_MAX_INDEX_DEPTH]; /* index array */
char path[LEJP_MAX_PATH];
char buf[LEJP_STRING_CHUNK + 1];
/* size_t */
size_t path_stride; /* 0 means default ptr size, else stride */
/* int */
uint32_t line;
/* short */
uint16_t uni;
/* char */
uint8_t npos;
uint8_t dcount;
uint8_t f;
uint8_t sp; /* stack head */
uint8_t ipos; /* index stack depth */
uint8_t count_paths;
uint8_t path_match;
uint8_t path_match_len;
uint8_t wildcount;
uint8_t pst_sp; /* parsing stack head */
uint8_t outer_array;
};
LWS_VISIBLE LWS_EXTERN void
lejp_construct(struct lejp_ctx *ctx,
signed char (*callback)(struct lejp_ctx *ctx, char reason),
void *user, const char * const *paths, unsigned char paths_count);
LWS_VISIBLE LWS_EXTERN void
lejp_destruct(struct lejp_ctx *ctx);
LWS_VISIBLE LWS_EXTERN int
lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len);
LWS_VISIBLE LWS_EXTERN void
lejp_change_callback(struct lejp_ctx *ctx,
signed char (*callback)(struct lejp_ctx *ctx, char reason));
/*
* push the current paths / paths_count and lejp_cb to a stack in the ctx, and
* start using the new ones
*/
LWS_VISIBLE LWS_EXTERN int
lejp_parser_push(struct lejp_ctx *ctx, void *user, const char * const *paths,
unsigned char paths_count, lejp_callback lejp_cb);
/*
* pop the previously used paths / paths_count and lejp_cb, and continue
* parsing using those as before
*/
LWS_VISIBLE LWS_EXTERN int
lejp_parser_pop(struct lejp_ctx *ctx);
/* exported for use when reevaluating a path for use with a subcontext */
LWS_VISIBLE LWS_EXTERN void
lejp_check_path_match(struct lejp_ctx *ctx);
LWS_VISIBLE LWS_EXTERN int
lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
LWS_VISIBLE LWS_EXTERN const char *
lejp_error_to_string(int e);
//@}

View File

@ -0,0 +1,786 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup log Logging
*
* ##Logging
*
* Lws provides flexible and filterable logging facilities, which can be
* used inside lws and in user code.
*
* Log categories may be individually filtered bitwise, and directed to built-in
* sinks for syslog-compatible logging, or a user-defined function.
*
* Traditional logs use a single, processwide logging context. New style log
* apis (lws_xxx_cx()) can pass the logging context to use in.
*/
///@{
#define LLL_ERR (1 << 0)
#define LLL_WARN (1 << 1)
#define LLL_NOTICE (1 << 2)
#define LLL_INFO (1 << 3)
#define LLL_DEBUG (1 << 4)
#define LLL_PARSER (1 << 5)
#define LLL_HEADER (1 << 6)
#define LLL_EXT (1 << 7)
#define LLL_CLIENT (1 << 8)
#define LLL_LATENCY (1 << 9)
#define LLL_USER (1 << 10)
#define LLL_THREAD (1 << 11)
#define LLL_COUNT (12) /* set to count of valid flags */
#define LLLF_SECRECY_PII (1 << 16)
/**< contains Personally Identifiable Information */
#define LLLF_SECRECY_BEARER (1 << 17)
/**< possession of this data allows impersonation */
#define LLLF_LOG_TIMESTAMP (1 << 18)
/**< set to prepend logs with timestamp */
#define LLLF_LOG_CONTEXT_AWARE (1 << 30)
/**< set if the context uses an emit function that takes the logctx, auto-
* applied when setting emit using lws_set_log_level_cx() api */
struct lws_log_cx;
typedef void (*lws_log_emit_t)(int level, const char *line);
typedef void (*lws_log_emit_cx_t)(struct lws_log_cx *cx, int level,
const char *line, size_t len);
typedef void (*lws_log_prepend_cx_t)(struct lws_log_cx *cx, void *obj,
char **p, char *e);
typedef void (*lws_log_use_cx_t)(struct lws_log_cx *cx, int _new);
/*
* This is the logging context
*/
typedef struct lws_log_cx {
union {
lws_log_emit_t emit; /* legacy emit function */
lws_log_emit_cx_t emit_cx; /* LLLF_LOG_CONTEXT_AWARE */
} u;
lws_log_use_cx_t refcount_cb;
/**< NULL, or a function called after each change to .refcount below,
* this enables implementing side-effects like opening and closing
* log files when the first and last object binds / unbinds */
lws_log_prepend_cx_t prepend;
/**< NULL, or a cb to optionally prepend a string to logs we are a
* parent of */
struct lws_log_cx *parent;
/**< NULL, or points to log ctx we are a child of */
void *opaque;
/**< ignored by lws, used to pass config to emit_cx, eg, filepath */
void *stg;
/**< ignored by lws, may be used a storage by refcount_cb / emit_cx */
uint32_t lll_flags;
/**< mask of log levels we want to emit in this context */
int32_t refcount;
/**< refcount of objects bound to this log context */
} lws_log_cx_t;
/**
* lwsl_timestamp: generate logging timestamp string
*
* \param level: logging level
* \param p: char * buffer to take timestamp
* \param len: length of p
*
* returns length written in p
*/
LWS_VISIBLE LWS_EXTERN int
lwsl_timestamp(int level, char *p, size_t len);
#if defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_NETWORK)
#define _lws_log(aaa, ...) SMSG(__VA_ARGS__)
#else
LWS_VISIBLE LWS_EXTERN void
_lws_log(int filter, const char *format, ...) LWS_FORMAT(2);
LWS_VISIBLE LWS_EXTERN void
_lws_logv(int filter, const char *format, va_list vl);
#endif
struct lws_vhost;
struct lws;
LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
lwsl_context_get_cx(struct lws_context *cx);
LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
lwsl_vhost_get_cx(struct lws_vhost *vh);
LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
lwsl_wsi_get_cx(struct lws *wsi);
#if defined(LWS_WITH_SECURE_STREAMS)
struct lws_ss_handle;
struct lws_sspc_handle;
LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
lwsl_ss_get_cx(struct lws_ss_handle *ss);
LWS_VISIBLE LWS_EXTERN struct lws_log_cx *
lwsl_sspc_get_cx(struct lws_sspc_handle *ss);
#endif
LWS_VISIBLE LWS_EXTERN void
lws_log_emit_cx_file(struct lws_log_cx *cx, int level, const char *line,
size_t len);
LWS_VISIBLE LWS_EXTERN void
lws_log_use_cx_file(struct lws_log_cx *cx, int _new);
LWS_VISIBLE LWS_EXTERN void
lws_log_prepend_context(struct lws_log_cx *cx, void *obj, char **p, char *e);
LWS_VISIBLE LWS_EXTERN void
lws_log_prepend_vhost(struct lws_log_cx *cx, void *obj, char **p, char *e);
LWS_VISIBLE LWS_EXTERN void
lws_log_prepend_wsi(struct lws_log_cx *cx, void *obj, char **p, char *e);
#if defined(LWS_WITH_SECURE_STREAMS)
LWS_VISIBLE LWS_EXTERN void
lws_log_prepend_ss(struct lws_log_cx *cx, void *obj, char **p, char *e);
LWS_VISIBLE LWS_EXTERN void
lws_log_prepend_sspc(struct lws_log_cx *cx, void *obj, char **p, char *e);
#endif
LWS_VISIBLE LWS_EXTERN void
_lws_log_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj,
int filter, const char *_fun, const char *format, ...) LWS_FORMAT(6);
#define lwsl_cx(_c, _fil, ...) \
_lws_log_cx(lwsl_context_get_cx(_c), lws_log_prepend_context, \
_c, _fil, __func__, __VA_ARGS__)
#define lwsl_vhost(_v, _fil, ...) \
_lws_log_cx(lwsl_vhost_get_cx(_v), lws_log_prepend_vhost, _v, \
_fil, __func__, __VA_ARGS__)
#define lwsl_wsi(_w, _fil, ...) \
_lws_log_cx(lwsl_wsi_get_cx(_w), lws_log_prepend_wsi, _w, \
_fil, __func__, __VA_ARGS__)
#define lwsl_ss(_h, _fil, ...) \
_lws_log_cx(lwsl_ss_get_cx(_h), lws_log_prepend_ss, _h, \
_fil, __func__, __VA_ARGS__)
#define lwsl_hexdump_context(_c, _fil, _buf, _len) \
lwsl_hexdump_level_cx(lwsl_context_get_cx(_c), \
lws_log_prepend_context, \
_c, _fil, _buf, _len)
#define lwsl_hexdump_vhost(_v, _fil, _buf, _len) \
lwsl_hexdump_level_cx(lwsl_vhost_get_cx(_v), \
lws_log_prepend_vhost, \
_v, _fil, _buf, _len)
#define lwsl_hexdump_wsi(_w, _fil, _buf, _len) \
lwsl_hexdump_level_cx(lwsl_wsi_get_cx(_w), \
lws_log_prepend_wsi, \
_w, _fil, _buf, _len)
#define lwsl_hexdump_ss(_h, _fil, _buf, _len) \
lwsl_hexdump_level_cx(lwsl_ss_get_cx(_h), \
lws_log_prepend_ss, \
_h, _fil, _buf, _len)
/*
* Figure out which logs to build in or not
*/
#if defined(_DEBUG)
/*
* In DEBUG build, select all logs unless NO_LOGS
*/
#if defined(LWS_WITH_NO_LOGS)
#define _LWS_LINIT (LLL_ERR | LLL_USER)
#else
#define _LWS_LINIT ((1 << LLL_COUNT) - 1)
#endif
#else /* not _DEBUG */
#if defined(LWS_WITH_NO_LOGS)
#define _LWS_LINIT (LLL_ERR | LLL_USER)
#else
#define _LWS_LINIT (LLL_ERR | LLL_USER | LLL_WARN | LLL_NOTICE)
#endif
#endif /* _DEBUG */
/*
* Create either empty overrides or the ones forced at build-time.
* These overrides have the final say... any bits set in
* LWS_LOGGING_BITFIELD_SET force the build of those logs, any bits
* set in LWS_LOGGING_BITFIELD_CLEAR disable the build of those logs.
*
* If not defined lws decides based on CMAKE_BUILD_TYPE=DEBUG or not
*/
#if defined(LWS_LOGGING_BITFIELD_SET)
#define _LWS_LBS (LWS_LOGGING_BITFIELD_SET)
#else
#define _LWS_LBS 0
#endif
#if defined(LWS_LOGGING_BITFIELD_CLEAR)
#define _LWS_LBC (LWS_LOGGING_BITFIELD_CLEAR)
#else
#define _LWS_LBC 0
#endif
/*
* Compute the final active logging bitfield for build
*/
#define _LWS_ENABLED_LOGS (((_LWS_LINIT) | (_LWS_LBS)) & ~(_LWS_LBC))
/*
* Individually enable or disable log levels for build
* depending on what was computed
*/
/*
* Process scope logs
*/
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__)
#else
#define lwsl_err(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_WARN)
#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__)
#else
#define lwsl_warn(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__)
#else
#define lwsl_notice(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_INFO)
#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__)
#else
#define lwsl_info(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__)
#else
#define lwsl_debug(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_PARSER)
#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__)
#else
#define lwsl_parser(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_HEADER)
#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__)
#else
#define lwsl_header(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_EXT)
#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__)
#else
#define lwsl_ext(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__)
#else
#define lwsl_client(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__)
#else
#define lwsl_latency(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_THREAD)
#define lwsl_thread(...) _lws_log(LLL_THREAD, __VA_ARGS__)
#else
#define lwsl_thread(...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_USER)
#define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__)
#else
#define lwsl_user(...) do {} while(0)
#endif
#define lwsl_hexdump_err(...) lwsl_hexdump_level(LLL_ERR, __VA_ARGS__)
#define lwsl_hexdump_warn(...) lwsl_hexdump_level(LLL_WARN, __VA_ARGS__)
#define lwsl_hexdump_notice(...) lwsl_hexdump_level(LLL_NOTICE, __VA_ARGS__)
#define lwsl_hexdump_info(...) lwsl_hexdump_level(LLL_INFO, __VA_ARGS__)
#define lwsl_hexdump_debug(...) lwsl_hexdump_level(LLL_DEBUG, __VA_ARGS__)
/*
* lws_context scope logs
*/
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_cx_err(_c, ...) lwsl_cx(_c, LLL_ERR, __VA_ARGS__)
#else
#define lwsl_cx_err(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_WARN)
#define lwsl_cx_warn(_c, ...) lwsl_cx(_c, LLL_WARN, __VA_ARGS__)
#else
#define lwsl_cx_warn(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
#define lwsl_cx_notice(_c, ...) lwsl_cx(_c, LLL_NOTICE, __VA_ARGS__)
#else
#define lwsl_cx_notice(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_INFO)
#define lwsl_cx_info(_c, ...) lwsl_cx(_c, LLL_INFO, __VA_ARGS__)
#else
#define lwsl_cx_info(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
#define lwsl_cx_debug(_c, ...) lwsl_cx(_c, LLL_DEBUG, __VA_ARGS__)
#else
#define lwsl_cx_debug(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_PARSER)
#define lwsl_cx_parser(_c, ...) lwsl_cx(_c, LLL_PARSER, __VA_ARGS__)
#else
#define lwsl_cx_parser(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_HEADER)
#define lwsl_cx_header(_c, ...) lwsl_cx(_c, LLL_HEADER, __VA_ARGS__)
#else
#define lwsl_cx_header(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_EXT)
#define lwsl_cx_ext(_c, ...) lwsl_cx(_c, LLL_EXT, __VA_ARGS__)
#else
#define lwsl_cx_ext(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
#define lwsl_cx_client(_c, ...) lwsl_cx(_c, LLL_CLIENT, __VA_ARGS__)
#else
#define lwsl_cx_client(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
#define lwsl_cx_latency(_c, ...) lwsl_cx(_c, LLL_LATENCY, __VA_ARGS__)
#else
#define lwsl_cx_latency(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_THREAD)
#define lwsl_cx_thread(_c, ...) lwsl_cx(_c, LLL_THREAD, __VA_ARGS__)
#else
#define lwsl_cx_thread(_c, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_USER)
#define lwsl_cx_user(_c, ...) lwsl_cx(_c, LLL_USER, __VA_ARGS__)
#else
#define lwsl_cx_user(_c, ...) do {} while(0)
#endif
#define lwsl_hexdump_cx_err(_c, ...) lwsl_hexdump_context(_c, LLL_ERR, __VA_ARGS__)
#define lwsl_hexdump_cx_warn(_c, ...) lwsl_hexdump_context(_c, LLL_WARN, __VA_ARGS__)
#define lwsl_hexdump_cx_notice(_c, ...) lwsl_hexdump_context(_c, LLL_NOTICE, __VA_ARGS__)
#define lwsl_hexdump_cx_info(_c, ...) lwsl_hexdump_context(_c, LLL_INFO, __VA_ARGS__)
#define lwsl_hexdump_cx_debug(_c, ...) lwsl_hexdump_context(_c, LLL_DEBUG, __VA_ARGS__)
/*
* lws_vhost
*/
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_vhost_err(_v, ...) lwsl_vhost(_v, LLL_ERR, __VA_ARGS__)
#else
#define lwsl_vhost_err(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_WARN)
#define lwsl_vhost_warn(_v, ...) lwsl_vhost(_v, LLL_WARN, __VA_ARGS__)
#else
#define lwsl_vhost_warn(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
#define lwsl_vhost_notice(_v, ...) lwsl_vhost(_v, LLL_NOTICE, __VA_ARGS__)
#else
#define lwsl_vhost_notice(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_INFO)
#define lwsl_vhost_info(_v, ...) lwsl_vhost(_v, LLL_INFO, __VA_ARGS__)
#else
#define lwsl_vhost_info(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
#define lwsl_vhost_debug(_v, ...) lwsl_vhost(_v, LLL_DEBUG, __VA_ARGS__)
#else
#define lwsl_vhost_debug(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_PARSER)
#define lwsl_vhost_parser(_v, ...) lwsl_vhost(_v, LLL_PARSER, __VA_ARGS__)
#else
#define lwsl_vhost_parser(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_HEADER)
#define lwsl_vhost_header(_v, ...) lwsl_vhost(_v, LLL_HEADER, __VA_ARGS__)
#else
#define lwsl_vhost_header(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_EXT)
#define lwsl_vhost_ext(_v, ...) lwsl_vhost(_v, LLL_EXT, __VA_ARGS__)
#else
#define lwsl_vhost_ext(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
#define lwsl_vhost_client(_v, ...) lwsl_vhost(_v, LLL_CLIENT, __VA_ARGS__)
#else
#define lwsl_vhost_client(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
#define lwsl_vhost_latency(_v, ...) lwsl_vhost(_v, LLL_LATENCY, __VA_ARGS__)
#else
#define lwsl_vhost_latency(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_THREAD)
#define lwsl_vhost_thread(_v, ...) lwsl_vhost(_v, LLL_THREAD, __VA_ARGS__)
#else
#define lwsl_vhost_thread(_v, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_USER)
#define lwsl_vhost_user(_v, ...) lwsl_vhost(_v, LLL_USER, __VA_ARGS__)
#else
#define lwsl_vhost_user(_v, ...) do {} while(0)
#endif
#define lwsl_hexdump_vhost_err(_v, ...) lwsl_hexdump_vhost(_v, LLL_ERR, __VA_ARGS__)
#define lwsl_hexdump_vhost_warn(_v, ...) lwsl_hexdump_vhost(_v, LLL_WARN, __VA_ARGS__)
#define lwsl_hexdump_vhost_notice(_v, ...) lwsl_hexdump_vhost(_v, LLL_NOTICE, __VA_ARGS__)
#define lwsl_hexdump_vhost_info(_v, ...) lwsl_hexdump_vhost(_v, LLL_INFO, __VA_ARGS__)
#define lwsl_hexdump_vhost_debug(_v, ...) lwsl_hexdump_vhost(_v, LLL_DEBUG, __VA_ARGS__)
/*
* lws_wsi
*/
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_wsi_err(_w, ...) lwsl_wsi(_w, LLL_ERR, __VA_ARGS__)
#else
#define lwsl_wsi_err(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_WARN)
#define lwsl_wsi_warn(_w, ...) lwsl_wsi(_w, LLL_WARN, __VA_ARGS__)
#else
#define lwsl_wsi_warn(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
#define lwsl_wsi_notice(_w, ...) lwsl_wsi(_w, LLL_NOTICE, __VA_ARGS__)
#else
#define lwsl_wsi_notice(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_INFO)
#define lwsl_wsi_info(_w, ...) lwsl_wsi(_w, LLL_INFO, __VA_ARGS__)
#else
#define lwsl_wsi_info(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
#define lwsl_wsi_debug(_w, ...) lwsl_wsi(_w, LLL_DEBUG, __VA_ARGS__)
#else
#define lwsl_wsi_debug(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_PARSER)
#define lwsl_wsi_parser(_w, ...) lwsl_wsi(_w, LLL_PARSER, __VA_ARGS__)
#else
#define lwsl_wsi_parser(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_HEADER)
#define lwsl_wsi_header(_w, ...) lwsl_wsi(_w, LLL_HEADER, __VA_ARGS__)
#else
#define lwsl_wsi_header(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_EXT)
#define lwsl_wsi_ext(_w, ...) lwsl_wsi(_w, LLL_EXT, __VA_ARGS__)
#else
#define lwsl_wsi_ext(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
#define lwsl_wsi_client(_w, ...) lwsl_wsi(_w, LLL_CLIENT, __VA_ARGS__)
#else
#define lwsl_wsi_client(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
#define lwsl_wsi_latency(_w, ...) lwsl_wsi(_w, LLL_LATENCY, __VA_ARGS__)
#else
#define lwsl_wsi_latency(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_THREAD)
#define lwsl_wsi_thread(_w, ...) lwsl_wsi(_w, LLL_THREAD, __VA_ARGS__)
#else
#define lwsl_wsi_thread(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_USER)
#define lwsl_wsi_user(_w, ...) lwsl_wsi(_w, LLL_USER, __VA_ARGS__)
#else
#define lwsl_wsi_user(_w, ...) do {} while(0)
#endif
#define lwsl_hexdump_wsi_err(_v, ...) lwsl_hexdump_wsi(_v, LLL_ERR, __VA_ARGS__)
#define lwsl_hexdump_wsi_warn(_v, ...) lwsl_hexdump_wsi(_v, LLL_WARN, __VA_ARGS__)
#define lwsl_hexdump_wsi_notice(_v, ...) lwsl_hexdump_wsi(_v, LLL_NOTICE, __VA_ARGS__)
#define lwsl_hexdump_wsi_info(_v, ...) lwsl_hexdump_wsi(_v, LLL_INFO, __VA_ARGS__)
#define lwsl_hexdump_wsi_debug(_v, ...) lwsl_hexdump_wsi(_v, LLL_DEBUG, __VA_ARGS__)
/*
* lwsl_ss
*/
#if (_LWS_ENABLED_LOGS & LLL_ERR)
#define lwsl_ss_err(_w, ...) lwsl_ss(_w, LLL_ERR, __VA_ARGS__)
#else
#define lwsl_ss_err(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_WARN)
#define lwsl_ss_warn(_w, ...) lwsl_ss(_w, LLL_WARN, __VA_ARGS__)
#else
#define lwsl_ss_warn(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_NOTICE)
#define lwsl_ss_notice(_w, ...) lwsl_ss(_w, LLL_NOTICE, __VA_ARGS__)
#else
#define lwsl_ss_notice(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_INFO)
#define lwsl_ss_info(_w, ...) lwsl_ss(_w, LLL_INFO, __VA_ARGS__)
#else
#define lwsl_ss_info(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_DEBUG)
#define lwsl_ss_debug(_w, ...) lwsl_ss(_w, LLL_DEBUG, __VA_ARGS__)
#else
#define lwsl_ss_debug(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_PARSER)
#define lwsl_ss_parser(_w, ...) lwsl_ss(_w, LLL_PARSER, __VA_ARGS__)
#else
#define lwsl_ss_parser(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_HEADER)
#define lwsl_ss_header(_w, ...) lwsl_ss(_w, LLL_HEADER, __VA_ARGS__)
#else
#define lwsl_ss_header(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_EXT)
#define lwsl_ss_ext(_w, ...) lwsl_ss(_w, LLL_EXT, __VA_ARGS__)
#else
#define lwsl_ss_ext(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_CLIENT)
#define lwsl_ss_client(_w, ...) lwsl_ss(_w, LLL_CLIENT, __VA_ARGS__)
#else
#define lwsl_ss_client(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_LATENCY)
#define lwsl_ss_latency(_w, ...) lwsl_ss(_w, LLL_LATENCY, __VA_ARGS__)
#else
#define lwsl_ss_latency(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_THREAD)
#define lwsl_ss_thread(_w, ...) lwsl_ss(_w, LLL_THREAD, __VA_ARGS__)
#else
#define lwsl_ss_thread(_w, ...) do {} while(0)
#endif
#if (_LWS_ENABLED_LOGS & LLL_USER)
#define lwsl_ss_user(_w, ...) lwsl_ss(_w, LLL_USER, __VA_ARGS__)
#else
#define lwsl_ss_user(_w, ...) do {} while(0)
#endif
#define lwsl_hexdump_ss_err(_v, ...) lwsl_hexdump_ss(_v, LLL_ERR, __VA_ARGS__)
#define lwsl_hexdump_ss_warn(_v, ...) lwsl_hexdump_ss(_v, LLL_WARN, __VA_ARGS__)
#define lwsl_hexdump_ss_notice(_v, ...) lwsl_hexdump_ss(_v, LLL_NOTICE, __VA_ARGS__)
#define lwsl_hexdump_ss_info(_v, ...) lwsl_hexdump_ss(_v, LLL_INFO, __VA_ARGS__)
#define lwsl_hexdump_ss_debug(_v, ...) lwsl_hexdump_ss(_v, LLL_DEBUG, __VA_ARGS__)
/**
* lwsl_hexdump_level() - helper to hexdump a buffer at a selected debug level
*
* \param level: one of LLL_ constants
* \param vbuf: buffer start to dump
* \param len: length of buffer to dump
*
* If \p level is visible, does a nice hexdump -C style dump of \p vbuf for
* \p len bytes. This can be extremely convenient while debugging.
*/
LWS_VISIBLE LWS_EXTERN void
lwsl_hexdump_level(int level, const void *vbuf, size_t len);
LWS_VISIBLE LWS_EXTERN void
lwsl_hexdump_level_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj,
int hexdump_level, const void *vbuf, size_t len);
/**
* lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only)
*
* \param buf: buffer start to dump
* \param len: length of buffer to dump
*
* Calls through to lwsl_hexdump_level(LLL_DEBUG, ... for compatability.
* It's better to use lwsl_hexdump_level(level, ... directly so you can control
* the visibility.
*/
LWS_VISIBLE LWS_EXTERN void
lwsl_hexdump(const void *buf, size_t len);
/**
* lws_is_be() - returns nonzero if the platform is Big Endian
*/
static LWS_INLINE int lws_is_be(void) {
const int probe = ~0xff;
return *(const char *)&probe;
}
/**
* lws_set_log_level() - Set the logging bitfield
* \param level: OR together the LLL_ debug contexts you want output from
* \param log_emit_function: NULL to leave it as it is, or a user-supplied
* function to perform log string emission instead of
* the default stderr one.
*
* log level defaults to "err", "warn" and "notice" contexts enabled and
* emission on stderr. If stderr is a tty (according to isatty()) then
* the output is coloured according to the log level using ANSI escapes.
*
* You can set the default security level for logging using the
* secrecy_and_log_level() macro to set the \p level parameter, eg
*
* lws_set_log_level(secrecy_and_log_level(LWS_SECRECY_PII, LLL_ERR | LLL_WARN),
* my_emit_function);
*
* Normally you can just leave it at the default.
*/
LWS_VISIBLE LWS_EXTERN void
lws_set_log_level(int level, lws_log_emit_t log_emit_function);
/**
* lwsl_emit_syslog() - helper log emit function writes to system log
*
* \param level: one of LLL_ log level indexes
* \param line: log string
*
* You use this by passing the function pointer to lws_set_log_level(), to set
* it as the log emit function, it is not called directly.
*/
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_syslog(int level, const char *line);
/**
* lwsl_emit_stderr() - helper log emit function writes to stderr
*
* \param level: one of LLL_ log level indexes
* \param line: log string
*
* You use this by passing the function pointer to lws_set_log_level(), to set
* it as the log emit function, it is not called directly.
*
* It prepends a system timestamp like [2018/11/13 07:41:57:3989]
*
* If stderr is a tty, then ansi colour codes are added.
*/
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_stderr(int level, const char *line);
/**
* lwsl_emit_stderr_notimestamp() - helper log emit function writes to stderr
*
* \param level: one of LLL_ log level indexes
* \param line: log string
*
* You use this by passing the function pointer to lws_set_log_level(), to set
* it as the log emit function, it is not called directly.
*
* If stderr is a tty, then ansi colour codes are added.
*/
LWS_VISIBLE LWS_EXTERN void
lwsl_emit_stderr_notimestamp(int level, const char *line);
/**
* lwsl_visible() - returns true if the log level should be printed
*
* \param level: one of LLL_ log level indexes
*
* This is useful if you have to do work to generate the log content, you
* can skip the work if the log level used to print it is not actually
* enabled at runtime.
*/
LWS_VISIBLE LWS_EXTERN int
lwsl_visible(int level);
struct lws;
LWS_VISIBLE LWS_EXTERN const char *
lws_wsi_tag(struct lws *wsi);
LWS_VISIBLE LWS_EXTERN void
lwsl_refcount_cx(lws_log_cx_t *cx, int _new);
///@}

View File

@ -0,0 +1,290 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup lwsac lwsac
*
* ##Allocated Chunks
*
* If you know you will be allocating a large, unknown number of same or
* differently sized objects, it's certainly possible to do it with libc
* malloc. However the allocation cost in time and memory overhead can
* add up, and deallocation means walking the structure of every object and
* freeing them in turn.
*
* lwsac (LWS Allocated Chunks) allocates chunks intended to be larger
* than your objects (4000 bytes by default) which you linearly allocate from
* using lwsac_use().
*
* If your next request won't fit in the current chunk, a new chunk is added
* to the chain of chunks and the allocaton done from there. If the request
* is larger than the chunk size, an oversize chunk is created to satisfy it.
*
* When you are finished with the allocations, you call lwsac_free() and
* free all the *chunks*. So you may have thousands of objects in the chunks,
* but they are all destroyed with the chunks without having to deallocate them
* one by one pointlessly.
*/
///@{
struct lwsac;
typedef unsigned char * lwsac_cached_file_t;
#define lws_list_ptr_container(P,T,M) ((T *)((char *)(P) - offsetof(T, M)))
/*
* linked-list helper that's commonly useful to manage lists of things
* allocated using lwsac.
*
* These lists point to their corresponding "next" member in the target, NOT
* the original containing struct. To get the containing struct, you must use
* lws_list_ptr_container() to convert.
*
* It's like that because it means we no longer have to have the next pointer
* at the start of the struct, and we can have the same struct on multiple
* linked-lists with everything held in the struct itself.
*/
typedef void * lws_list_ptr;
/*
* optional sorting callback called by lws_list_ptr_insert() to sort the right
* things inside the opqaue struct being sorted / inserted on the list.
*/
typedef int (*lws_list_ptr_sort_func_t)(lws_list_ptr a, lws_list_ptr b);
#define lws_list_ptr_advance(_lp) _lp = *((void **)_lp)
/* sort may be NULL if you don't care about order */
LWS_VISIBLE LWS_EXTERN void
lws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add,
lws_list_ptr_sort_func_t sort);
/**
* lwsac_use - allocate / use some memory from a lwsac
*
* \param head: pointer to the lwsac list object
* \param ensure: the number of bytes we want to use
* \param chunk_size: 0, or the size of the chunk to (over)allocate if
* what we want won't fit in the current tail chunk. If
* 0, the default value of 4000 is used. If ensure is
* larger, it is used instead.
*
* This also serves to init the lwsac if *head is NULL. Basically it does
* whatever is necessary to return you a pointer to ensure bytes of memory
* reserved for the caller.
*
* This always allocates in the current chunk or a new chunk... see the
* lwsac_use_backfill() variant to try first to find space in earlier chunks.
*
* Returns NULL if OOM.
*/
LWS_VISIBLE LWS_EXTERN void *
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size);
/**
* lwsac_use_backfill - allocate / use some memory from a lwsac
*
* \param head: pointer to the lwsac list object
* \param ensure: the number of bytes we want to use
* \param chunk_size: 0, or the size of the chunk to (over)allocate if
* what we want won't fit in the current tail chunk. If
* 0, the default value of 4000 is used. If ensure is
* larger, it is used instead.
*
* This also serves to init the lwsac if *head is NULL. Basically it does
* whatever is necessary to return you a pointer to ensure bytes of memory
* reserved for the caller.
*
* Also checks if earlier blocks have enough remaining space to take the
* allocation before making a new allocation.
*
* Returns NULL if OOM.
*/
LWS_VISIBLE LWS_EXTERN void *
lwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size);
/**
* lwsac_use - allocate / use some memory from a lwsac
*
* \param head: pointer to the lwsac list object
* \param ensure: the number of bytes we want to use, which must be zeroed
* \param chunk_size: 0, or the size of the chunk to (over)allocate if
* what we want won't fit in the current tail chunk. If
* 0, the default value of 4000 is used. If ensure is
* larger, it is used instead.
*
* Same as lwsac_use(), but \p ensure bytes of memory at the return address
* are zero'd before returning.
*
* Returns NULL if OOM.
*/
LWS_VISIBLE LWS_EXTERN void *
lwsac_use_zero(struct lwsac **head, size_t ensure, size_t chunk_size);
#define lwsac_use_zeroed lwsac_use_zero
/**
* lwsac_free - deallocate all chunks in the lwsac and set head NULL
*
* \param head: pointer to the lwsac list object
*
* This deallocates all chunks in the lwsac, then sets *head to NULL. All
* lwsac_use() pointers are invalidated in one hit without individual frees.
*/
LWS_VISIBLE LWS_EXTERN void
lwsac_free(struct lwsac **head);
/*
* Optional helpers useful for where consumers may need to defer destruction
* until all consumers are finished with the lwsac
*/
/**
* lwsac_detach() - destroy an lwsac unless somebody else is referencing it
*
* \param head: pointer to the lwsac list object
*
* The creator of the lwsac can all this instead of lwsac_free() when it itself
* has finished with the lwsac, but other code may be consuming it.
*
* If there are no other references, the lwsac is destroyed, *head is set to
* NULL and that's the end; however if something else has called
* lwsac_reference() on the lwsac, it simply returns. When lws_unreference()
* is called and no references are left, it will be destroyed then.
*/
LWS_VISIBLE LWS_EXTERN void
lwsac_detach(struct lwsac **head);
/**
* lwsac_reference() - increase the lwsac reference count
*
* \param head: pointer to the lwsac list object
*
* Increment the reference count on the lwsac to defer destruction.
*/
LWS_VISIBLE LWS_EXTERN void
lwsac_reference(struct lwsac *head);
/**
* lwsac_unreference() - decrease the lwsac reference count
*
* \param head: pointer to the lwsac list object
*
* Decrement the reference count on the lwsac... if it reached 0 on a detached
* lwsac then the lwsac is immediately destroyed and *head set to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lwsac_unreference(struct lwsac **head);
/**
* lwsac_extend() - try to increase the size of the last block
*
* \param head: pointer to the lwsac list object
* \param amount: amount to try to increase usage for
*
* This will either increase the usage reservation of the last allocated block
* by amount and return 0, or fail and return 1.
*
* This is very cheap to call and is designed to optimize usage after a static
* struct for vari-sized additional content which may flow into an additional
* block in a new chunk if necessary, but wants to make the most of the space
* in front of it first to try to avoid gaps and the new chunk if it can.
*
* The additional area if the call succeeds will have been memset to 0.
*
* To use it, the following must be true:
*
* - only the last lwsac use can be extended
*
* - if another use happens inbetween the use and extend, it will break
*
* - the use cannot have been using backfill
*
* - a user object must be tracking the current allocated size of the last use
* (lwsac doesn't know it) and increment by amount if the extend call succeeds
*
* Despite these restrictions this can be an important optimization for some
* cases
*/
LWS_VISIBLE LWS_EXTERN int
lwsac_extend(struct lwsac *head, size_t amount);
/* helpers to keep a file cached in memory */
LWS_VISIBLE LWS_EXTERN void
lwsac_use_cached_file_start(lwsac_cached_file_t cache);
LWS_VISIBLE LWS_EXTERN void
lwsac_use_cached_file_end(lwsac_cached_file_t *cache);
LWS_VISIBLE LWS_EXTERN void
lwsac_use_cached_file_detach(lwsac_cached_file_t *cache);
LWS_VISIBLE LWS_EXTERN int
lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache,
size_t *len);
/* more advanced helpers */
/* offset from lac to start of payload, first = 1 = first lac in chain */
LWS_VISIBLE LWS_EXTERN size_t
lwsac_sizeof(int first);
LWS_VISIBLE LWS_EXTERN size_t
lwsac_get_tail_pos(struct lwsac *lac);
LWS_VISIBLE LWS_EXTERN struct lwsac *
lwsac_get_next(struct lwsac *lac);
LWS_VISIBLE LWS_EXTERN size_t
lwsac_align(size_t length);
LWS_VISIBLE LWS_EXTERN void
lwsac_info(struct lwsac *head);
LWS_VISIBLE LWS_EXTERN uint64_t
lwsac_total_alloc(struct lwsac *head);
LWS_VISIBLE LWS_EXTERN uint64_t
lwsac_total_overhead(struct lwsac *head);
/**
* lwsac_scan_extant() - returns existing copy of blob, or NULL
*
* \param head: the lwsac to scan
* \param find: the blob to look for
* \param len: the length of the blob to look for
* \param nul: nonzero if the next byte must be NUL
*
* Helper that looks through a whole lwsac for a given binary blob already
* present. Used in the case that lwsac contents are const once written, and
* strings or blobs may be repeated in the input: this allows the earlier
* copy to be pointed to by subsequent references without repeating the string
* or blob redundantly.
*/
LWS_VISIBLE LWS_EXTERN uint8_t *
lwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul);
///@}

View File

@ -0,0 +1,188 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup lws_map generic map apis
* ##Generic map structures and apis
* \ingroup lwsapi
*
* lws_map
*
* Discrete owner object represents the whole map, created with key-specific
* ops for hashing the key to a uint32_t and comparing two keys. Owns a list
* of hash tables whose size / modulo it set at creation time.
*
* Items in the map are contained in a lws_map_item_t that is indexed in a
* hash table.
*
* It's difficult to make a single compact map abstraction that fits all cases,
* this is useful to the extent you have the memory to trade off the number of
* hashtables needed for the amount of items and the lookup latency limit for
* your application, typically for hundreds or low thousands of items.
*/
//@{
typedef struct lws_map lws_map_t;
typedef struct lws_map_item lws_map_item_t;
typedef void * lws_map_key_t;
typedef void * lws_map_value_t;
typedef uint32_t lws_map_hash_t;
typedef lws_map_hash_t (*lws_map_hash_from_key_t)(const lws_map_key_t key,
size_t kl);
typedef int (*lws_map_compare_key_t)(const lws_map_key_t key1, size_t kl1,
const lws_map_value_t key2, size_t kl2);
typedef void * (*lws_map_alloc_t)(struct lws_map *mo, size_t x);
typedef void (*lws_map_free_t)(void *);
/*
* Creation parameters for the map, copied into the map owner
*/
typedef struct lws_map_info {
lws_map_hash_from_key_t _hash;
lws_map_compare_key_t _compare;
lws_map_alloc_t _alloc; /* NULL = lws_malloc */
lws_map_free_t _free; /* NULL = lws_free */
void *opaque;
/**< &lwsac if using lwsac allocator */
void *aux;
/**< chunk size if using lwsac allocator */
/**< this can be used by the alloc handler, eg for lws_ac */
size_t modulo;
/**< number of hashed owner lists to create */
} lws_map_info_t;
LWS_VISIBLE LWS_EXTERN const void *
lws_map_item_key(lws_map_item_t *_item);
LWS_VISIBLE LWS_EXTERN const void *
lws_map_item_value(lws_map_item_t *_item);
LWS_VISIBLE LWS_EXTERN size_t
lws_map_item_key_len(lws_map_item_t *_item);
LWS_VISIBLE LWS_EXTERN size_t
lws_map_item_value_len(lws_map_item_t *_item);
/*
* Helpers for C string keys case
*/
#define lws_map_item_create_ks(_map, _str, _v, _vl) \
lws_map_item_create(_map, (const lws_map_key_t)_str, \
strlen(_str), (const lws_map_value_t)_v, \
_vl)
#define lws_map_item_lookup_ks(_map, _str) \
lws_map_item_lookup(_map, (const lws_map_key_t)_str, strlen(_str))
/**
* lws_map_create() - create a map object and hashtables on heap
*
* \param info: description of map to create
*
* Creates a map object on heap, using lws_malloc().
*
* \p info may be all zeros inside, if so, modulo defaults to 8, and the
* operation callbacks default to using lws_malloc() / _free() for item alloc,
* a default xor / shift based hash and simple linear memory key compare.
*
* For less typical use-cases, the provided \p info members can be tuned to
* control how the allocation of mapped items is done, lws provides two exports
* lws_map_alloc_lwsac() and lws_map_free_lwsac() that can be used for _alloc
* and _free to have items allocated inside an lwsac.
*
* The map itself is created on the heap directly, the info._alloc() op is only
* used when creating items.
*
* keys have individual memory sizes and do not need to all be the same length.
*/
LWS_VISIBLE LWS_EXTERN lws_map_t *
lws_map_create(const lws_map_info_t *info);
/*
* helpers that can be used for info._alloc and info._free if using lwsac
* allocation for items, set info.opaque to point to the lwsac pointer, and
* aux to (void *)chunksize, or leave zero / NULL for the default
*/
LWS_VISIBLE LWS_EXTERN void *
lws_map_alloc_lwsac(struct lws_map *map, size_t x);
LWS_VISIBLE LWS_EXTERN void
lws_map_free_lwsac(void *v);
/**
* lws_map_destroy() - deallocate all items and free map
*
* \param pmap: pointer to pointer map object to deallocate
*
* Frees all items in the map, using info._free(), and then frees the map
* from heap directly. \p *pmap is set to NULL.
*/
LWS_VISIBLE LWS_EXTERN void
lws_map_destroy(lws_map_t **pmap);
/**
* lws_map_item_create() - allocate and map an item into an existing map
*
* \param map: the map to add items into
* \param key: the key, may be any kind of object
* \param keylen: the length of the key in bytes
* \param value: the value, may be any kind of object
* \param valuelen: the length of value
*
* Allocates space for the item, key and value using the map allocator, and
* if non-NULL, copies the key and value into the item.
*
* If an item with the same key exists, it is removed and destroyed before
* creating and adding the new one.
*/
LWS_VISIBLE LWS_EXTERN lws_map_item_t *
lws_map_item_create(lws_map_t *map,
const lws_map_key_t key, size_t keylen,
const lws_map_value_t value, size_t valuelen);
/**
* lws_map_item_destroy() - remove item from map and free
*
* \param item: the item in the map to remove and free
*/
LWS_VISIBLE LWS_EXTERN void
lws_map_item_destroy(lws_map_item_t *item);
/**
* lws_map_item_lookup() - look for a item with the given key in the map
*
* \param map: the map
* \param key: the key to look for
* \param keylen: the length of the key to look for
*
* Searches for the key in the map, using the map's key hash and key compare
* functions.
*/
LWS_VISIBLE LWS_EXTERN lws_map_item_t *
lws_map_item_lookup(lws_map_t *map, const lws_map_key_t key, size_t keylen);
//@}

View File

@ -0,0 +1,329 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Public apis related to metric collection and reporting
*/
/* lws_metrics public part */
typedef uint64_t u_mt_t;
enum {
LWSMTFL_REPORT_OUTLIERS = (1 << 0),
/**< track outliers and report them internally */
LWSMTFL_REPORT_OOB = (1 << 1),
/**< report events as they happen */
LWSMTFL_REPORT_INACTIVITY_AT_PERIODIC = (1 << 2),
/**< explicitly externally report no activity at periodic cb, by
* default no events in the period is just not reported */
LWSMTFL_REPORT_MEAN = (1 << 3),
/**< average/min/max is meaningful, else only sum is meaningful */
LWSMTFL_REPORT_ONLY_GO = (1 << 4),
/**< no-go pieces invalid */
LWSMTFL_REPORT_DUTY_WALLCLOCK_US = (1 << 5),
/**< aggregate compares to wallclock us for duty cycle */
LWSMTFL_REPORT_HIST = (1 << 6),
/**< our type is histogram (otherwise, sum / mean aggregation) */
};
/*
* lws_metrics_tag allows your object to accumulate OpenMetrics-style
* descriptive tags before accounting for it with a metrics object at the end.
*
* Tags should represent low entropy information that is likely to repeat
* identically, so, eg, http method name, not eg, latency in us which is
* unlikely to be seen the same twice.
*
* Tags are just a list of name=value pairs, used for qualifying the final
* metrics entry with decorations in additional dimensions. For example,
* rather than keep individual metrics on methods, scheme, mountpoint, result
* code, you can keep metrics on http transactions only, and qualify the
* transaction metrics entries with tags that can be queried on the metrics
* backend to get the finer-grained information.
*
* http_srv{code="404",mount="/",method="GET",scheme="http"} 3
*
* For OpenMetrics the tags are converted to a { list } and appended to the base
* metrics name before using with actual metrics objects, the same set of tags
* on different transactions resolve to the same qualification string.
*/
typedef struct lws_metrics_tag {
lws_dll2_t list;
const char *name; /* tag, intended to be in .rodata, not copied */
/* overallocated value */
} lws_metrics_tag_t;
LWS_EXTERN LWS_VISIBLE int
lws_metrics_tag_add(lws_dll2_owner_t *owner, const char *name, const char *val);
#if defined(LWS_WITH_SYS_METRICS)
/*
* wsi-specific version that also appends the tag value to the lifecycle tag
* used for logging the wsi identity
*/
LWS_EXTERN LWS_VISIBLE int
lws_metrics_tag_wsi_add(struct lws *wsi, const char *name, const char *val);
#else
#define lws_metrics_tag_wsi_add(_a, _b, _c)
#endif
#if defined(LWS_WITH_SECURE_STREAMS)
/*
* ss-specific version that also appends the tag value to the lifecycle tag
* used for logging the ss identity
*/
#if defined(LWS_WITH_SYS_METRICS)
LWS_EXTERN LWS_VISIBLE int
lws_metrics_tag_ss_add(struct lws_ss_handle *ss, const char *name, const char *val);
#else
#define lws_metrics_tag_ss_add(_a, _b, _c)
#endif
#endif
LWS_EXTERN LWS_VISIBLE void
lws_metrics_tags_destroy(lws_dll2_owner_t *owner);
LWS_EXTERN LWS_VISIBLE size_t
lws_metrics_tags_serialize(lws_dll2_owner_t *owner, char *buf, size_t len);
LWS_EXTERN LWS_VISIBLE const char *
lws_metrics_tag_get(lws_dll2_owner_t *owner, const char *name);
/* histogram bucket */
typedef struct lws_metric_bucket {
struct lws_metric_bucket *next;
uint64_t count;
/* name + NUL is overallocated */
} lws_metric_bucket_t;
/* get overallocated name of bucket from bucket pointer */
#define lws_metric_bucket_name_len(_b) (*((uint8_t *)&(_b)[1]))
#define lws_metric_bucket_name(_b) (((const char *)&(_b)[1]) + 1)
/*
* These represent persistent local event measurements. They may aggregate
* a large number of events inbetween external dumping of summaries of the
* period covered, in two different ways
*
* 1) aggregation by sum or mean, to absorb multiple scalar readings
*
* - go / no-go ratio counting
* - mean averaging for, eg, latencies
* - min / max for averaged values
* - period the stats covers
*
* 2) aggregation by histogram, to absorb a range of outcomes that may occur
* multiple times
*
* - add named buckets to histogram
* - bucket has a 64-bit count
* - bumping a bucket just increments the count if already exists, else adds
* a new one with count set to 1
*
* The same type with a union covers both cases.
*
* The lws_system ops api that hooks lws_metrics up to a metrics backend is
* given a pointer to these according to the related policy, eg, hourly, or
* every event passed straight through.
*/
typedef struct lws_metric_pub {
const char *name;
/**< eg, "n.cn.dns", "vh.myendpoint" */
void *backend_opaque;
/**< ignored by lws, backend handler completely owns it */
lws_usec_t us_first;
/**< us time metric started collecting, reset to us_dumped at dump */
lws_usec_t us_last;
/**< 0, or us time last event, reset to 0 at last dump */
lws_usec_t us_dumped;
/**< 0 if never, else us time of last dump to external api */
/* scope of data in .u is "since last dump" --> */
union {
/* aggregation, by sum or mean */
struct {
u_mt_t sum[2];
/**< go, no-go summed for mean or plan sum */
u_mt_t min;
/**< smallest individual measurement */
u_mt_t max;
/**< largest individual measurement */
uint32_t count[2];
/**< go, no-go count of measurements in sum */
} agg;
/* histogram with dynamic named buckets */
struct {
lws_metric_bucket_t *head;
/**< first bucket in our bucket list */
uint64_t total_count;
/**< total count in all of our buckets */
uint32_t list_size;
/**< number of buckets in our bucket list */
} hist;
} u;
uint8_t flags;
} lws_metric_pub_t;
LWS_EXTERN LWS_VISIBLE void
lws_metrics_hist_bump_priv_tagged(lws_metric_pub_t *mt, lws_dll2_owner_t *tow,
lws_dll2_owner_t *tow2);
/*
* Calipers are a helper struct for implementing "hanging latency" detection,
* where setting the start time and finding the end time may happen in more than
* one place.
*
* There are convenience wrappers to eliminate caliper definitions and code
* cleanly if WITH_SYS_METRICS is disabled for the build.
*/
struct lws_metric;
typedef struct lws_metric_caliper {
struct lws_dll2_owner mtags_owner; /**< collect tags here during
* caliper lifetime */
struct lws_metric *mt; /**< NULL == inactive */
lws_usec_t us_start;
} lws_metric_caliper_t;
#if defined(LWS_WITH_SYS_METRICS)
#define lws_metrics_caliper_compose(_name) \
lws_metric_caliper_t _name;
#define lws_metrics_caliper_bind(_name, _mt) \
{ if (_name.mt) { \
lwsl_err("caliper: overwrite %s\n", \
lws_metrics_priv_to_pub(_name.mt)->name); \
assert(0); } \
_name.mt = _mt; _name.us_start = lws_now_usecs(); }
#define lws_metrics_caliper_declare(_name, _mt) \
lws_metric_caliper_t _name = { .mt = _mt, .us_start = lws_now_usecs() }
#define lws_metrics_caliper_report(_name, _go_nogo) \
{ if (_name.us_start) { lws_metric_event(_name.mt, _go_nogo, \
(u_mt_t)(lws_now_usecs() - \
_name.us_start)); \
} lws_metrics_caliper_done(_name); }
#define lws_metrics_caliper_report_hist(_name, pwsi) if (_name.mt) { \
lws_metrics_hist_bump_priv_tagged(lws_metrics_priv_to_pub(_name.mt), \
&_name.mtags_owner, \
pwsi ? &((pwsi)->cal_conn.mtags_owner) : NULL); \
lws_metrics_caliper_done(_name); }
#define lws_metrics_caliper_cancel(_name) { lws_metrics_caliper_done(_name); }
#define lws_metrics_hist_bump(_mt, _name) \
lws_metrics_hist_bump_(_mt, _name)
#define lws_metrics_hist_bump_priv(_mt, _name) \
lws_metrics_hist_bump_(lws_metrics_priv_to_pub(_mt), _name)
#define lws_metrics_caliper_done(_name) { \
_name.us_start = 0; _name.mt = NULL; \
lws_metrics_tags_destroy(&_name.mtags_owner); }
#else
#define lws_metrics_caliper_compose(_name)
#define lws_metrics_caliper_bind(_name, _mt)
#define lws_metrics_caliper_declare(_name, _mp)
#define lws_metrics_caliper_report(_name, _go_nogo)
#define lws_metrics_caliper_report_hist(_name, pwsiconn)
#define lws_metrics_caliper_cancel(_name)
#define lws_metrics_hist_bump(_mt, _name)
#define lws_metrics_hist_bump_priv(_mt, _name)
#define lws_metrics_caliper_done(_name)
#endif
/**
* lws_metrics_format() - helper to format a metrics object for logging
*
* \param pub: public part of metrics object
* \param buf: output buffer to place string in
* \param len: available length of \p buf
*
* Helper for describing the state of a metrics object as a human-readable
* string, accounting for how its flags indicate what it contains. This is not
* how you would report metrics, but during development it can be useful to
* log them inbetween possibily long report intervals.
*
* It uses the metric's flags to adapt the format shown appropriately, eg,
* as a histogram if LWSMTFL_REPORT_HIST etc
*/
LWS_EXTERN LWS_VISIBLE int
lws_metrics_format(lws_metric_pub_t *pub, lws_metric_bucket_t **sub,
char *buf, size_t len);
/**
* lws_metrics_hist_bump() - add or increment histogram bucket
*
* \param pub: public part of metrics object
* \param name: bucket name to increment
*
* Either increment the count of an existing bucket of the right name in the
* metrics object, or add a new bucket of the given name and set its count to 1.
*
* The metrics object must have been created with flag LWSMTFL_REPORT_HIST
*
* Normally, you will actually use the preprocessor wrapper
* lws_metrics_hist_bump() defined above, since this automatically takes care of
* removing itself from the build if WITH_SYS_METRICS is not defined, without
* needing any preprocessor conditionals.
*/
LWS_EXTERN LWS_VISIBLE int
lws_metrics_hist_bump_(lws_metric_pub_t *pub, const char *name);
LWS_VISIBLE LWS_EXTERN int
lws_metrics_foreach(struct lws_context *ctx, void *user,
int (*cb)(lws_metric_pub_t *pub, void *user));
LWS_VISIBLE LWS_EXTERN int
lws_metrics_hist_bump_describe_wsi(struct lws *wsi, lws_metric_pub_t *pub,
const char *name);
enum {
LMT_NORMAL = 0, /* related to successful events */
LMT_OUTLIER, /* related to successful events outside of bounds */
LMT_FAIL, /* related to failed events */
LMT_COUNT,
};
typedef enum lws_metric_rpt {
LMR_PERIODIC = 0, /* we are reporting on a schedule */
LMR_OUTLIER, /* we are reporting the last outlier */
} lws_metric_rpt_kind_t;
#define METRES_GO 0
#define METRES_NOGO 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,344 @@
/*
* libwebsockets - protocol - mqtt
*
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* included from libwebsockets.h
*/
#ifndef _LWS_MQTT_H
#define _LWS_MQTT_H 1
struct _lws_mqtt_related;
typedef struct _lws_mqtt_related lws_mqtt_related_t;
struct lws_mqtt_str_st;
typedef struct lws_mqtt_str_st lws_mqtt_str_t;
#define MQTT_VER_3_1_1 4
#define LWS_MQTT_FINAL_PART 1
#define LWS_MQTT_MAX_AWSIOT_TOPICLEN 256
#define LWS_MQTT_MAX_TOPICLEN 65535
#define LWS_MQTT_MAX_CIDLEN 128
#define LWS_MQTT_RANDOM_CIDLEN 23 /* 3.1.3.1-5: Server MUST... between
1 and 23 chars... */
typedef enum {
QOS0,
QOS1,
QOS2, /* not supported */
RESERVED_QOS_LEVEL,
FAILURE_QOS_LEVEL = 0x80
} lws_mqtt_qos_levels_t;
typedef union {
struct {
uint8_t retain:1;
uint8_t qos:2;
uint8_t dup:1;
uint8_t ctrl_pkt_type:4;
} flags;
uint8_t bits;
} lws_mqtt_fixed_hdr_t;
/*
* MQTT connection parameters, passed into struct
* lws_client_connect_info to establish a connection using
* lws_client_connect_via_info().
*/
typedef struct lws_mqtt_client_connect_param_s {
const char *client_id; /* Client ID */
uint16_t keep_alive; /* MQTT keep alive
interval in
seconds */
uint8_t clean_start:1; /* MQTT clean
session */
uint8_t client_id_nofree:1;
/**< do not free the client id */
struct {
const char *topic;
const char *message;
lws_mqtt_qos_levels_t qos;
uint8_t retain;
} will_param; /* MQTT LWT
parameters */
const char *username;
const char *password;
uint8_t aws_iot;
} lws_mqtt_client_connect_param_t;
/*
* MQTT publish parameters
*/
typedef struct lws_mqtt_publish_param_s {
char *topic; /* Topic Name */
uint16_t topic_len;
const void *payload; /* Publish Payload */
uint32_t payload_len; /* Size of the
complete payload */
uint32_t payload_pos; /* where we are in payload */
lws_mqtt_qos_levels_t qos;
/*--v-Following will be used by LWS-v--*/
uint16_t packet_id; /* Packet ID for QoS >
0 */
uint8_t dup:1; /* Retried PUBLISH,
for QoS > 0 */
} lws_mqtt_publish_param_t;
typedef struct topic_elem {
const char *name; /* Topic Name */
lws_mqtt_qos_levels_t qos; /* Requested QoS */
/*--v-Following will be used by LWS-v--*/
uint8_t acked;
} lws_mqtt_topic_elem_t;
/*
* MQTT publish parameters
*/
typedef struct lws_mqtt_subscribe_param_s {
uint32_t num_topics; /* Number of topics */
lws_mqtt_topic_elem_t *topic; /* Array of topic elements */
/*--v-Following will be used by LWS-v--*/
uint16_t packet_id;
} lws_mqtt_subscribe_param_t;
typedef enum {
LMQCP_RESERVED,
LMQCP_CTOS_CONNECT, /* Connection request */
LMQCP_STOC_CONNACK, /* Connection acknowledgment */
LMQCP_PUBLISH, /* Publish Message */
LMQCP_PUBACK, /* QoS 1: Publish acknowledgment */
LMQCP_PUBREC, /* QoS 2.1: Publish received */
LMQCP_PUBREL, /* QoS 2.2: Publish release */
LMQCP_PUBCOMP, /* QoS 2.3: Publish complete */
LMQCP_CTOS_SUBSCRIBE, /* Subscribe request */
LMQCP_STOC_SUBACK, /* Subscribe acknowledgment */
LMQCP_CTOS_UNSUBSCRIBE, /* Unsubscribe request */
LMQCP_STOC_UNSUBACK, /* Unsubscribe acknowledgment */
LMQCP_CTOS_PINGREQ, /* PING request */
LMQCP_STOC_PINGRESP, /* PONG response */
LMQCP_DISCONNECT, /* Disconnect notification */
LMQCP_AUTH /* Authentication exchange */
} lws_mqtt_control_packet_t;
/* flags from byte 8 of C_TO_S CONNECT */
typedef enum {
LMQCFT_CLIENT_ID_NOFREE = (1 << 8),
/* only the low 8 are standardized and go out in the protocol */
LMQCFT_USERNAME = (1 << 7),
LMQCFT_PASSWORD = (1 << 6),
LMQCFT_WILL_RETAIN = (1 << 5),
LMQCFT_WILL_QOS = (1 << 3),
LMQCFT_WILL_FLAG = (1 << 2),
LMQCFT_CLEAN_START = (1 << 1),
LMQCFT_RESERVED = (1 << 0),
LMQCFT_WILL_QOS_MASK = (3 << 3),
} lws_mqtt_connect_flags_t;
/* flags for S_TO_C CONNACK */
typedef enum {
LMQCFT_SESSION_PRESENT = (1 << 0),
} lws_mqtt_connack_flags_t;
typedef enum {
LMQCP_REASON_SUCCESS = 0x00,
LMQCP_REASON_NORMAL_DISCONNECTION = 0x00,
LMQCP_REASON_GRANTED_QOS0 = 0x00,
LMQCP_REASON_GRANTED_QOS1 = 0x01,
LMQCP_REASON_GRANTED_QOS2 = 0x02,
LMQCP_REASON_DISCONNECT_WILL = 0x04,
LMQCP_REASON_NO_MATCHING_SUBSCRIBER = 0x10,
LMQCP_REASON_NO_SUBSCRIPTION_EXISTED = 0x11,
LMQCP_REASON_CONTINUE_AUTHENTICATION = 0x18,
LMQCP_REASON_RE_AUTHENTICATE = 0x19,
LMQCP_REASON_UNSPECIFIED_ERROR = 0x80,
LMQCP_REASON_MALFORMED_PACKET = 0x81,
LMQCP_REASON_PROTOCOL_ERROR = 0x82,
LMQCP_REASON_IMPLEMENTATION_SPECIFIC_ERROR = 0x83,
/* Begin - Error codes for CONNACK */
LMQCP_REASON_UNSUPPORTED_PROTOCOL = 0x84,
LMQCP_REASON_CLIENT_ID_INVALID = 0x85,
LMQCP_REASON_BAD_CREDENTIALS = 0x86,
LMQCP_REASON_NOT_AUTHORIZED = 0x87,
/* End - Error codes for CONNACK */
LMQCP_REASON_SERVER_UNAVAILABLE = 0x88,
LMQCP_REASON_SERVER_BUSY = 0x89,
LMQCP_REASON_BANNED = 0x8a,
LMQCP_REASON_SERVER_SHUTTING_DOWN = 0x8b,
LMQCP_REASON_BAD_AUTHENTICATION_METHOD = 0x8c,
LMQCP_REASON_KEEPALIVE_TIMEOUT = 0x8d,
LMQCP_REASON_SESSION_TAKEN_OVER = 0x8e,
LMQCP_REASON_TOPIC_FILTER_INVALID = 0x8f,
LMQCP_REASON_TOPIC_NAME_INVALID = 0x90,
LMQCP_REASON_PACKET_ID_IN_USE = 0x91,
LMQCP_REASON_PACKET_ID_NOT_FOUND = 0x92,
LMQCP_REASON_MAX_RX_EXCEEDED = 0x93,
LMQCP_REASON_TOPIC_ALIAS_INVALID = 0x94,
LMQCP_REASON_PACKET_TOO_LARGE = 0x95,
LMQCP_REASON_RATELIMIT = 0x96,
LMQCP_REASON_QUOTA_EXCEEDED = 0x97,
LMQCP_REASON_ADMINISTRATIVE_ACTION = 0x98,
LMQCP_REASON_PAYLOAD_FORMAT_INVALID = 0x99,
LMQCP_REASON_RETAIN_NOT_SUPPORTED = 0x9a,
LMQCP_REASON_QOS_NOT_SUPPORTED = 0x9b,
LMQCP_REASON_USE_ANOTHER_SERVER = 0x9c,
LMQCP_REASON_SERVER_MOVED = 0x9d,
LMQCP_REASON_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 0x9e,
LMQCP_REASON_CONNECTION_RATE_EXCEEDED = 0x9f,
LMQCP_REASON_MAXIMUM_CONNECT_TIME = 0xa0,
LMQCP_REASON_SUBSCRIPTION_IDS_NOT_SUPPORTED = 0xa1,
LMQCP_REASON_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 0xa2,
} lws_mqtt_reason_t;
typedef enum {
LMQPROP_INVALID,
LMQPROP_PAYLOAD_FORMAT_INDICATOR = 0x01,
LMQPROP_MESSAGE_EXPIRY_INTERVAL = 0x02,
LMQPROP_CONTENT_TYPE = 0x03,
LMQPROP_RESPONSE_TOPIC = 0x08,
LMQPROP_CORRELATION_DATA = 0x09,
LMQPROP_SUBSCRIPTION_IDENTIFIER = 0x0b,
LMQPROP_SESSION_EXPIRY_INTERVAL = 0x11,
LMQPROP_ASSIGNED_CLIENT_IDENTIFIER = 0x12,
LMQPROP_SERVER_KEEP_ALIVE = 0x13,
LMQPROP_AUTHENTICATION_METHOD = 0x15,
LMQPROP_AUTHENTICATION_DATA = 0x16,
LMQPROP_REQUEST_PROBLEM_INFORMATION = 0x17,
LMQPROP_WILL_DELAY_INTERVAL = 0x18,
LMQPROP_REQUEST_RESPONSE_INFORMATION = 0x19,
LMQPROP_RESPONSE_INFORMATION = 0x1a,
LMQPROP_SERVER_REFERENCE = 0x1c,
LMQPROP_REASON_STRING = 0x1f,
LMQPROP_RECEIVE_MAXIMUM = 0x21,
LMQPROP_TOPIC_ALIAS_MAXIMUM = 0x22,
LMQPROP_TOPIC_ALIAS = 0x23,
LMQPROP_MAXIMUM_QOS = 0x24,
LMQPROP_RETAIN_AVAILABLE = 0x25,
LMQPROP_USER_PROPERTY = 0x26,
LMQPROP_MAXIMUM_PACKET_SIZE = 0x27,
LMQPROP_WILDCARD_SUBSCRIPTION_AVAIL = 0x28,
LMQPROP_SUBSCRIPTION_IDENTIFIER_AVAIL = 0x29,
LMQPROP_SHARED_SUBSCRIPTION_AVAIL = 0x2a
} lws_mqtt_property;
int
lws_read_mqtt(struct lws *wsi, unsigned char *buf, lws_filepos_t len);
/* returns 0 if bd1 and bd2 are "the same", that includes empty, else nonzero */
LWS_VISIBLE LWS_EXTERN int
lws_mqtt_bindata_cmp(const lws_mqtt_str_t *bd1, const lws_mqtt_str_t *bd2);
LWS_VISIBLE LWS_EXTERN void
lws_mqtt_str_init(lws_mqtt_str_t *s, uint8_t *buf, uint16_t lim, char nf);
LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
lws_mqtt_str_create(uint16_t lim);
LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
lws_mqtt_str_create_init(uint8_t *buf, uint16_t len, uint16_t lim);
LWS_VISIBLE LWS_EXTERN lws_mqtt_str_t *
lws_mqtt_str_create_cstr_dup(const char *buf, uint16_t lim);
LWS_VISIBLE LWS_EXTERN uint8_t *
lws_mqtt_str_next(lws_mqtt_str_t *s, uint16_t *budget);
LWS_VISIBLE LWS_EXTERN int
lws_mqtt_str_advance(lws_mqtt_str_t *s, int n);
LWS_VISIBLE LWS_EXTERN void
lws_mqtt_str_free(lws_mqtt_str_t **s);
/**
* lws_mqtt_client_send_publish() - lws_write a publish packet
*
* \param wsi: the mqtt child wsi
* \param pub: additional information on what we're publishing
* \param buf: payload to send
* \param len: length of data in buf
* \param final: flag indicating this is the last part
*
* Issues part of, or the whole of, a PUBLISH frame. The first part of the
* frame contains the header, and uses the .qos and .payload_len parts of \p pub
* since MQTT requires the frame to specify the PUBLISH message length at the
* start. The \p len paramter may be less than \p pub.payload_len, in which
* case subsequent calls with more payload are needed to complete the frame.
*
* Although the connection is stuck waiting for the remainder, in that it can't
* issue any other frames until the current one is completed, lws returns to the
* event loop normally and can continue the calls with additional payload even
* for huge frames as the data becomes available, consistent with timeout needs
* and latency to start any new frame (even, eg, related to ping / pong).
*
* If you're sending large frames, the OS will typically not allow the data to
* be sent all at once to kernel side. So you should ideally cut the payload
* up into 1 or 2- mtu sized chunks and send that.
*
* Final should be set when you're calling with the last part of the payload.
*/
LWS_VISIBLE LWS_EXTERN int
lws_mqtt_client_send_publish(struct lws *wsi, lws_mqtt_publish_param_t *pub,
const void *buf, uint32_t len, int final);
/**
* lws_mqtt_client_send_subcribe() - lws_write a subscribe packet
*
* \param wsi: the mqtt child wsi
* \param sub: which topic(s) we want to subscribe to
*
* For topics other child streams have not already subscribed to, send a packet
* to the server asking to subscribe to them. If all topics listed are already
* subscribed to be the shared network connection, just trigger the
* LWS_CALLBACK_MQTT_SUBSCRIBED callback as if a SUBACK had come.
*
* \p sub doesn't need to exist after the return from this function.
*/
LWS_VISIBLE LWS_EXTERN int
lws_mqtt_client_send_subcribe(struct lws *wsi, lws_mqtt_subscribe_param_t *sub);
/**
* lws_mqtt_client_send_unsubcribe() - lws_write a unsubscribe packet
*
* \param wsi: the mqtt child wsi
* \param sub: which topic(s) we want to unsubscribe from
*
* For topics other child streams are not subscribed to, send a packet
* to the server asking to unsubscribe from them. If all topics
* listed are already subscribed by other child streams on the shared
* network connection, just trigger the LWS_CALLBACK_MQTT_UNSUBSCRIBED
* callback as if a UNSUBACK had come.
*
* \p unsub doesn't need to exist after the return from this function.
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_mqtt_client_send_unsubcribe(struct lws *wsi,
const lws_mqtt_subscribe_param_t *unsub);
#endif /* _LWS_MQTT_H */

View File

@ -0,0 +1,283 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#define LWS_WIFI_MAX_SCAN_TRACK 16
#define LWS_ETH_ALEN 6
typedef uint8_t lws_wifi_ch_t;
typedef int8_t lws_wifi_rssi_t;
struct lws_netdev_instance;
typedef enum {
LWSNDTYP_UNKNOWN,
LWSNDTYP_WIFI,
LWSNDTYP_ETH,
} lws_netdev_type_t;
/*
* Base class for netdev configuration
*/
typedef struct lws_netdev_config {
void *plat_config;
} lws_netdev_config_t;
/*
* Const Logical generic network interface ops
*/
typedef struct lws_netdev_ops {
struct lws_netdev_instance * (*create)(struct lws_context *ctx,
const struct lws_netdev_ops *ops,
const char *name, void *platinfo);
int (*configure)(struct lws_netdev_instance *nd,
lws_netdev_config_t *config);
int (*up)(struct lws_netdev_instance *nd);
int (*down)(struct lws_netdev_instance *nd);
int (*event)(struct lws_netdev_instance *nd, lws_usec_t timestamp,
void *buf, size_t len);
/**< these are SMD events coming from lws event loop thread context */
void (*destroy)(struct lws_netdev_instance **pnd);
int (*connect)(struct lws_netdev_instance *wnd, const char *ssid,
const char *passphrase, uint8_t *bssid);
void (*scan)(struct lws_netdev_instance *nd);
} lws_netdev_ops_t;
/*
* Network devices on this platform
*
* We also hold a list of all known network credentials (when they are needed
* because there is a network interface without anything to connect to) and
* the lws_settings instance they are stored in
*/
typedef struct lws_netdevs {
lws_dll2_owner_t owner;
/**< list of netdevs / lws_netdev_instance_t -based objects */
lws_dll2_owner_t owner_creds;
/**< list of known credentials */
struct lwsac *ac_creds;
/**< lwsac holding retreived credentials settings, or NULL */
lws_settings_instance_t *si;
lws_sockaddr46 sa46_dns_resolver;
uint8_t refcount_creds;
/**< when there are multiple netdevs, must refcount creds in mem */
} lws_netdevs_t;
/*
* Base class for an allocated instantiated derived object using lws_netdev_ops,
* ie, a specific ethernet device
*/
typedef struct lws_netdev_instance {
const char *name;
const lws_netdev_ops_t *ops;
void *platinfo;
lws_dll2_t list;
uint8_t mac[LWS_ETH_ALEN];
uint8_t type; /* lws_netdev_type_t */
} lws_netdev_instance_t;
enum {
LNDIW_ALG_OPEN,
LNDIW_ALG_WPA2,
LNDIW_MODE_STA = (1 << 0),
LNDIW_MODE_AP = (1 << 1),
LNDIW_UP = (1 << 7),
LNDIW_ACQ_IPv4 = (1 << 0),
LNDIW_ACQ_IPv6 = (1 << 1),
};
/*
* Group AP / Station State
*/
typedef enum {
LWSNDVWIFI_STATE_INITIAL,
/*
* We should gratuitously try whatever last worked for us, then
* if that fails, worry about the rest of the logic
*/
LWSNDVWIFI_STATE_SCAN,
/*
* Unconnected, scanning: AP known in one of the config slots ->
* configure it, start timeout + LWSNDVWIFI_STATE_STAT, if no AP
* already up in same group with lower MAC, after a random
* period start up our AP (LWSNDVWIFI_STATE_AP)
*/
LWSNDVWIFI_STATE_AP,
/* Trying to be the group AP... periodically do a scan
* LWSNDVWIFI_STATE_AP_SCAN, faster and then slower
*/
LWSNDVWIFI_STATE_AP_SCAN,
/*
* doing a scan while trying to be the group AP... if we see a
* lower MAC being the AP for the same group AP, abandon being
* an AP and join that AP as a station
*/
LWSNDVWIFI_STATE_STAT_GRP_AP,
/*
* We have decided to join another group member who is being the
* AP, as its MAC is lower than ours. This is a stable state,
* but we still do periodic scans
* LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN and will always prefer an
* AP configured in a slot.
*/
LWSNDVWIFI_STATE_STAT_GRP_AP_SCAN,
/*
* We have joined a group member who is doing the AP job... we
* want to check every now and then if a configured AP has
* appeared that we should better use instead. Otherwise stay
* in LWSNDVWIFI_STATE_STAT_GRP_AP
*/
LWSNDVWIFI_STATE_STAT,
/*
* trying to connect to another non-group AP. If we don't get an
* IP within a timeout and retries, mark it as unusable it and go back
*/
LWSNDVWIFI_STATE_STAT_HAPPY,
} lws_netdev_wifi_state_t;
/*
* Generic WIFI credentials
*/
typedef struct lws_wifi_creds {
lws_dll2_t list;
uint8_t bssid[LWS_ETH_ALEN];
char passphrase[64];
char ssid[33];
uint8_t alg;
} lws_wifi_creds_t;
/*
* Generic WIFI Network Device Instance
*/
typedef struct lws_netdev_instance_wifi {
lws_netdev_instance_t inst;
lws_dll2_owner_t scan; /* sorted scan results */
lws_sorted_usec_list_t sul_scan;
lws_wifi_creds_t *ap_cred;
const char *ap_ip;
const char *sta_ads;
char current_attempt_ssid[33];
uint8_t current_attempt_bssid[LWS_ETH_ALEN];
uint8_t flags;
uint8_t state; /* lws_netdev_wifi_state_t */
} lws_netdev_instance_wifi_t;
/*
* Logical scan results sorted list item
*/
typedef struct lws_wifi_sta {
lws_dll2_t list;
uint32_t last_seen; /* unix time */
uint32_t last_tried; /* unix time */
uint8_t bssid[LWS_ETH_ALEN];
char *ssid; /* points to overallocation */
uint8_t ssid_len;
lws_wifi_ch_t ch;
lws_wifi_rssi_t rssi[8];
int16_t rssi_avg;
uint8_t authmode;
uint8_t rssi_count;
uint8_t rssi_next;
/* ssid overallocated afterwards */
} lws_wifi_sta_t;
#define rssi_averaged(_x) (_x->rssi_count ? \
((int)_x->rssi_avg / (int)_x->rssi_count) : \
-200)
LWS_VISIBLE LWS_EXTERN lws_netdevs_t *
lws_netdevs_from_ctx(struct lws_context *ctx);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_credentials_settings_set(lws_netdevs_t *nds);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_credentials_settings_get(lws_netdevs_t *nds);
LWS_VISIBLE LWS_EXTERN struct lws_netdev_instance *
lws_netdev_wifi_create_plat(struct lws_context *ctx,
const lws_netdev_ops_t *ops, const char *name,
void *platinfo);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_wifi_configure_plat(struct lws_netdev_instance *nd,
lws_netdev_config_t *config);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_wifi_event_plat(struct lws_netdev_instance *nd, lws_usec_t timestamp,
void *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_wifi_up_plat(struct lws_netdev_instance *nd);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_wifi_down_plat(struct lws_netdev_instance *nd);
LWS_VISIBLE LWS_EXTERN void
lws_netdev_wifi_destroy_plat(struct lws_netdev_instance **pnd);
LWS_VISIBLE LWS_EXTERN void
lws_netdev_wifi_scan_plat(lws_netdev_instance_t *nd);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_wifi_connect_plat(lws_netdev_instance_t *wnd, const char *ssid,
const char *passphrase, uint8_t *bssid);
LWS_VISIBLE LWS_EXTERN lws_netdev_instance_t *
lws_netdev_find(lws_netdevs_t *netdevs, const char *ifname);
#define lws_netdev_wifi_plat_ops \
.create = lws_netdev_wifi_create_plat, \
.configure = lws_netdev_wifi_configure_plat, \
.event = lws_netdev_wifi_event_plat, \
.up = lws_netdev_wifi_up_plat, \
.down = lws_netdev_wifi_down_plat, \
.connect = lws_netdev_wifi_connect_plat, \
.scan = lws_netdev_wifi_scan_plat, \
.destroy = lws_netdev_wifi_destroy_plat
/*
* This is for plat / OS level init that is necessary to be able to use
* networking or wifi at all, without mentioning any specific device
*/
LWS_VISIBLE LWS_EXTERN int
lws_netdev_plat_init(void);
LWS_VISIBLE LWS_EXTERN int
lws_netdev_plat_wifi_init(void);

View File

@ -0,0 +1,246 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/** \defgroup net Network related helper APIs
* ##Network related helper APIs
*
* These wrap miscellaneous useful network-related functions
*/
///@{
#if defined(LWS_ESP_PLATFORM)
#include <lwip/sockets.h>
#endif
typedef uint8_t lws_route_uidx_t;
typedef struct lws_dns_score {
uint8_t precedence;
uint8_t label;
} lws_dns_score_t;
/*
* This represents an entry in the system routing table
*/
typedef struct lws_route {
lws_dll2_t list;
lws_sockaddr46 src;
lws_sockaddr46 dest;
lws_sockaddr46 gateway;
struct lws_route *source; /* when used as lws_dns_sort_t */
lws_dns_score_t score; /* when used as lws_dns_sort_t */
int if_idx;
int priority;
int ifa_flags; /* if source_ads */
lws_route_uidx_t uidx; /* unique index for this route */
uint8_t proto;
uint8_t dest_len;
uint8_t src_len;
uint8_t scope; /* if source_ads */
uint8_t af; /* if source_ads */
uint8_t source_ads:1;
} lws_route_t;
/*
* We reuse the route object as the dns sort granule, so there's only one
* struct needs to know all the gnarly ipv6 details
*/
typedef lws_route_t lws_dns_sort_t;
/**
* lws_canonical_hostname() - returns this host's hostname
*
* This is typically used by client code to fill in the host parameter
* when making a client connection. You can only call it after the context
* has been created.
*
* \param context: Websocket context
*/
LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT
lws_canonical_hostname(struct lws_context *context);
/**
* lws_get_peer_addresses() - Get client address information
* \param wsi: Local struct lws associated with
* \param fd: Connection socket descriptor
* \param name: Buffer to take client address name
* \param name_len: Length of client address name buffer
* \param rip: Buffer to take client address IP dotted quad
* \param rip_len: Length of client address IP buffer
*
* This function fills in name and rip with the name and IP of
* the client connected with socket descriptor fd. Names may be
* truncated if there is not enough room. If either cannot be
* determined, they will be returned as valid zero-length strings.
*/
LWS_VISIBLE LWS_EXTERN void
lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name,
int name_len, char *rip, int rip_len);
/**
* lws_get_peer_simple() - Get client address information without RDNS
*
* \param wsi: Local struct lws associated with
* \param name: Buffer to take client address name
* \param namelen: Length of client address name buffer
*
* This provides a 123.123.123.123 type IP address in name from the
* peer that has connected to wsi
*/
LWS_VISIBLE LWS_EXTERN const char *
lws_get_peer_simple(struct lws *wsi, char *name, size_t namelen);
LWS_VISIBLE LWS_EXTERN const char *
lws_get_peer_simple_fd(lws_sockfd_type fd, char *name, size_t namelen);
#define LWS_ITOSA_USABLE 0
#define LWS_ITOSA_NOT_EXIST -1
#define LWS_ITOSA_NOT_USABLE -2
#define LWS_ITOSA_BUSY -3 /* only returned by lws_socket_bind() on
EADDRINUSE */
#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE)
/**
* lws_interface_to_sa() - Convert interface name or IP to sockaddr struct
*
* \param ipv6: Allow IPV6 addresses
* \param ifname: Interface name or IP
* \param addr: struct sockaddr_in * to be written
* \param addrlen: Length of addr
*
* This converts a textual network interface name to a sockaddr usable by
* other network functions.
*
* If the network interface doesn't exist, it will return LWS_ITOSA_NOT_EXIST.
*
* If the network interface is not usable, eg ethernet cable is removed, it
* may logically exist but not have any IP address. As such it will return
* LWS_ITOSA_NOT_USABLE.
*
* If the network interface exists and is usable, it will return
* LWS_ITOSA_USABLE.
*/
LWS_VISIBLE LWS_EXTERN int
lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
size_t addrlen);
#endif
/**
* lws_sa46_compare_ads() - checks if two sa46 have the same address
*
* \param sa46a: first
* \param sa46b: second
*
* Returns 0 if the address family is INET or INET6 and the address is the same,
* or if the AF is the same but not INET or INET6, otherwise nonzero.
*/
LWS_VISIBLE LWS_EXTERN int
lws_sa46_compare_ads(const lws_sockaddr46 *sa46a, const lws_sockaddr46 *sa46b);
/**
* lws_sa46_on_net() - checks if an sa46 is on the subnet represented by another
*
* \param sa46a: first
* \param sa46_net: network
* \param net_len: length of network non-mask
*
* Returns 0 if sa46a belongs on network sa46_net/net_len
*
* If there is an ipv4 / v6 mismatch between the ip and the net, the ipv4
* address is promoted to ::ffff:x.x.x.x before the comparison.
*/
LWS_VISIBLE LWS_EXTERN int
lws_sa46_on_net(const lws_sockaddr46 *sa46a, const lws_sockaddr46 *sa46_net,
int net_len);
/*
* lws_parse_numeric_address() - converts numeric ipv4 or ipv6 to byte address
*
* \param ads: the numeric ipv4 or ipv6 address string
* \param result: result array
* \param max_len: max length of result array
*
* Converts a 1.2.3.4 or 2001:abcd:123:: or ::ffff:1.2.3.4 formatted numeric
* address into an array of network ordered byte address elements.
*
* Returns < 0 on error, else length of result set, either 4 or 16 for ipv4 /
* ipv6.
*/
LWS_VISIBLE LWS_EXTERN int
lws_parse_numeric_address(const char *ads, uint8_t *result, size_t max_len);
/*
* lws_sa46_parse_numeric_address() - converts numeric ipv4 or ipv6 to sa46
*
* \param ads: the numeric ipv4 or ipv6 address string
* \param sa46: pointer to sa46 to set
*
* Converts a 1.2.3.4 or 2001:abcd:123:: or ::ffff:1.2.3.4 formatted numeric
* address into an sa46, a union of sockaddr_in or sockaddr_in6 depending on
* what kind of address was found. sa46->sa4.sin_fmaily will be AF_INET if
* ipv4, or AF_INET6 if ipv6.
*
* Returns 0 if the sa46 was set, else < 0 on error.
*/
LWS_VISIBLE LWS_EXTERN int
lws_sa46_parse_numeric_address(const char *ads, lws_sockaddr46 *sa46);
/**
* lws_write_numeric_address() - convert network byte order ads to text
*
* \param ads: network byte order address array
* \param size: number of bytes valid in ads
* \param buf: result buffer to take text format
* \param len: max size of text buffer
*
* Converts an array of network-ordered byte address elements to a textual
* representation of the numeric address, like "1.2.3.4" or "::1". Return 0
* if OK else < 0. ipv6 only supported with LWS_IPV6=1 at cmake.
*/
LWS_VISIBLE LWS_EXTERN int
lws_write_numeric_address(const uint8_t *ads, int size, char *buf, size_t len);
/**
* lws_sa46_write_numeric_address() - convert sa46 ads to textual numeric ads
*
* \param sa46: the sa46 whose address to show
* \param buf: result buffer to take text format
* \param len: max size of text buffer
*
* Converts the ipv4 or ipv6 address in an lws_sockaddr46 to a textual
* representation of the numeric address, like "1.2.3.4" or "::1". Return 0
* if OK else < 0. ipv6 only supported with LWS_IPV6=1 at cmake.
*/
LWS_VISIBLE LWS_EXTERN int
lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len);
///@}

View File

@ -0,0 +1,77 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef __LWS_OPTEE_H
#define __LWS_OPTEE_H
/* 128-bit IP6 address */
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
};
};
#define _SS_MAXSIZE 128U
#define _SS_ALIGNSIZE (sizeof(int64_t))
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - \
sizeof(sa_family_t))
#define _SS_PAD2SIZE (_SS_MAXSIZE - \
sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE)
struct sockaddr_storage {
sa_family_t ss_family; /* address family */
char __ss_pad1[_SS_PAD1SIZE];
int64_t __ss_align; /* force desired struct alignment */
char __ss_pad2[_SS_PAD2SIZE];
};
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
struct sockaddr {
sa_family_t sa_family; /* address family */
uint8_t sa_data[__SOCK_SIZE__ /* address value */
- sizeof(sa_family_t)];
};
/* 16 bytes */
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
uint8_t sin_zero[__SOCK_SIZE__ /* padding until 16 bytes */
- sizeof(sa_family_t)
- sizeof(in_port_t)
- sizeof(struct in_addr)];
};
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* Transport layer port # */
uint32_t sin6_flowinfo; /* IP6 flow information */
struct in6_addr sin6_addr; /* IP6 address */
uint32_t sin6_scope_id; /* scope zone index */
};
#endif /* __LWS_OPTEE_H */

View File

@ -0,0 +1,383 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup Protocols-and-Plugins Protocols and Plugins
* \ingroup lwsapi
*
* ##Protocol and protocol plugin -related apis
*
* Protocols bind ws protocol names to a custom callback specific to that
* protocol implementaion.
*
* A list of protocols can be passed in at context creation time, but it is
* also legal to leave that NULL and add the protocols and their callback code
* using plugins.
*
* Plugins are much preferable compared to cut and pasting code into an
* application each time, since they can be used standalone.
*/
///@{
/** struct lws_protocols - List of protocols and handlers client or server
* supports. */
struct lws_protocols {
const char *name;
/**< Protocol name that must match the one given in the client
* Javascript new WebSocket(url, 'protocol') name. */
lws_callback_function *callback;
/**< The service callback used for this protocol. It allows the
* service action for an entire protocol to be encapsulated in
* the protocol-specific callback */
size_t per_session_data_size;
/**< Each new connection using this protocol gets
* this much memory allocated on connection establishment and
* freed on connection takedown. A pointer to this per-connection
* allocation is passed into the callback in the 'user' parameter */
size_t rx_buffer_size;
/**< lws allocates this much space for rx data and informs callback
* when something came. Due to rx flow control, the callback may not
* be able to consume it all without having to return to the event
* loop. That is supported in lws.
*
* If .tx_packet_size is 0, this also controls how much may be sent at
* once for backwards compatibility.
*/
unsigned int id;
/**< ignored by lws, but useful to contain user information bound
* to the selected protocol. For example if this protocol was
* called "myprotocol-v2", you might set id to 2, and the user
* code that acts differently according to the version can do so by
* switch (wsi->a.protocol->id), user code might use some bits as
* capability flags based on selected protocol version, etc. */
void *user; /**< ignored by lws, but user code can pass a pointer
here it can later access from the protocol callback */
size_t tx_packet_size;
/**< 0 indicates restrict send() size to .rx_buffer_size for backwards-
* compatibility.
* If greater than zero, a single send() is restricted to this amount
* and any remainder is buffered by lws and sent afterwards also in
* these size chunks. Since that is expensive, it's preferable
* to restrict one fragment you are trying to send to match this
* size.
*/
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility */
};
#define LWS_PROTOCOL_LIST_TERM { NULL, NULL, 0, 0, 0, NULL, 0 }
/**
* lws_vhost_name_to_protocol() - get vhost's protocol object from its name
*
* \param vh: vhost to search
* \param name: protocol name
*
* Returns NULL or a pointer to the vhost's protocol of the requested name
*/
LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name);
/**
* lws_get_protocol() - Returns a protocol pointer from a websocket
* connection.
* \param wsi: pointer to struct websocket you want to know the protocol of
*
*
* Some apis can act on all live connections of a given protocol,
* this is how you can get a pointer to the active protocol if needed.
*/
LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
lws_get_protocol(struct lws *wsi);
/** lws_protocol_get() - deprecated: use lws_get_protocol */
LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED;
/**
* lws_protocol_vh_priv_zalloc() - Allocate and zero down a protocol's per-vhost
* storage
* \param vhost: vhost the instance is related to
* \param prot: protocol the instance is related to
* \param size: bytes to allocate
*
* Protocols often find it useful to allocate a per-vhost struct, this is a
* helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT
*/
LWS_VISIBLE LWS_EXTERN void *
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
const struct lws_protocols *prot, int size);
/**
* lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage
*
* \param vhost: vhost the instance is related to
* \param prot: protocol the instance is related to
*
* Recover a pointer to the allocated per-vhost storage for the protocol created
* by lws_protocol_vh_priv_zalloc() earlier
*/
LWS_VISIBLE LWS_EXTERN void *
lws_protocol_vh_priv_get(struct lws_vhost *vhost,
const struct lws_protocols *prot);
/**
* lws_vhd_find_by_pvo() - find a partner vhd
*
* \param cx: the lws_context
* \param protname: the name of the lws_protocol the vhd belongs to
* \param pvo_name: the name of a pvo that must exist bound to the vhd
* \param pvo_value: the required value of the named pvo
*
* This allows architectures with multiple protocols bound together to
* cleanly discover partner protocol instances even on completely
* different vhosts. For example, a proxy may consist of two protocols
* listening on different vhosts, and there may be multiple instances
* of the proxy in the same process. It's desirable that each side of
* the proxy is an independent protocol that can be freely bound to any
* vhost, eg, allowing Unix Domain to tls / h2 proxying, or each side
* bound to different network interfaces for localhost-only visibility
* on one side, using existing vhost management.
*
* That leaves the problem that the two sides have to find each other
* and bind at runtime. This api allows each side to specify the
* protocol name, and a common pvo name and pvo value that indicates
* the two sides belong together, and search through all the instantiated
* vhost-protocols looking for a match. If found, the private allocation
* (aka "vhd" of the match is returned). NULL is returned on no match.
*
* Since this can only succeed when called by the last of the two
* protocols to be instantiated, both sides should call it and handle
* NULL gracefully, since it may mean that they were first and their
* partner vhsot-protocol has not been instantiated yet.
*/
LWS_VISIBLE LWS_EXTERN void *
lws_vhd_find_by_pvo(struct lws_context *cx, const char *protname,
const char *pvo_name, const char *pvo_value);
/**
* lws_adjust_protocol_psds - change a vhost protocol's per session data size
*
* \param wsi: a connection with the protocol to change
* \param new_size: the new size of the per session data size for the protocol
*
* Returns user_space for the wsi, after allocating
*
* This should not be used except to initalize a vhost protocol's per session
* data size one time, before any connections are accepted.
*
* Sometimes the protocol wraps another protocol and needs to discover and set
* its per session data size at runtime.
*/
LWS_VISIBLE LWS_EXTERN void *
lws_adjust_protocol_psds(struct lws *wsi, size_t new_size);
/**
* lws_finalize_startup() - drop initial process privileges
*
* \param context: lws context
*
* This is called after the end of the vhost protocol initializations, but
* you may choose to call it earlier
*/
LWS_VISIBLE LWS_EXTERN int
lws_finalize_startup(struct lws_context *context);
/**
* lws_pvo_search() - helper to find a named pvo in a linked-list
*
* \param pvo: the first pvo in the linked-list
* \param name: the name of the pvo to return if found
*
* Returns NULL, or a pointer to the name pvo in the linked-list
*/
LWS_VISIBLE LWS_EXTERN const struct lws_protocol_vhost_options *
lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *name);
/**
* lws_pvo_get_str() - retreive a string pvo value
*
* \param in: the first pvo in the linked-list
* \param name: the name of the pvo to return if found
* \param result: pointer to a const char * to get the result if any
*
* Returns 0 if found and *result set, or nonzero if not found
*/
LWS_VISIBLE LWS_EXTERN int
lws_pvo_get_str(void *in, const char *name, const char **result);
LWS_VISIBLE LWS_EXTERN int
lws_protocol_init(struct lws_context *context);
#define LWS_PLUGIN_API_MAGIC 191
/*
* Abstract plugin header for any kind of plugin class, always at top of
* actual class plugin export type.
*
* The export type object must be exported with the same name as the plugin
* file, eg, libmyplugin.so must export a const one of these as the symbol
* "myplugin".
*
* That is the only expected export from the plugin.
*/
typedef struct lws_plugin_header {
const char *name;
const char *_class;
const char *lws_build_hash; /* set to LWS_BUILD_HASH */
unsigned int api_magic;
/* set to LWS_PLUGIN_API_MAGIC at plugin build time */
/* plugin-class specific superclass data follows */
} lws_plugin_header_t;
/*
* "lws_protocol_plugin" class export, for lws_protocol implementations done
* as plugins
*/
typedef struct lws_plugin_protocol {
lws_plugin_header_t hdr;
const struct lws_protocols *protocols; /**< array of supported protocols provided by plugin */
const struct lws_extension *extensions; /**< array of extensions provided by plugin */
int count_protocols; /**< how many protocols */
int count_extensions; /**< how many extensions */
} lws_plugin_protocol_t;
/*
* This is the dynamic, runtime created part of the plugin instantiation.
* These are kept in a linked-list and destroyed with the context.
*/
struct lws_plugin {
struct lws_plugin *list; /**< linked list */
const lws_plugin_header_t *hdr;
union {
#if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP)
#if (UV_VERSION_MAJOR > 0)
uv_lib_t lib; /**< shared library pointer */
#endif
#endif
void *l; /**< */
} u;
};
/*
* Event lib library plugin type (when LWS_WITH_EVLIB_PLUGINS)
* Public so new event libs can equally be supported outside lws itself
*/
typedef struct lws_plugin_evlib {
lws_plugin_header_t hdr;
const struct lws_event_loop_ops *ops;
} lws_plugin_evlib_t;
typedef int (*each_plugin_cb_t)(struct lws_plugin *p, void *user);
/**
* lws_plugins_init() - dynamically load plugins of matching class from dirs
*
* \param pplugin: pointer to linked-list for this kind of plugin
* \param d: array of directory paths to look in
* \param _class: class string that plugin must declare
* \param filter: NULL, or a string that must appear after the third char of the plugin filename
* \param each: NULL, or each_plugin_cb_t callback for each instantiated plugin
* \param each_user: pointer passed to each callback
*
* Allows you to instantiate a class of plugins to a specified linked-list.
* The each callback allows you to init each inistantiated callback and pass a
* pointer each_user to it.
*
* To take down the plugins, pass a pointer to the linked-list head to
* lws_plugins_destroy.
*
* This is used for lws protocol plugins but you can define your own plugin
* class name like "mypluginclass", declare it in your plugin headers, and load
* your own plugins to your own list using this api the same way.
*/
LWS_VISIBLE LWS_EXTERN int
lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
const char *_class, const char *filter,
each_plugin_cb_t each, void *each_user);
/**
* lws_plugins_destroy() - dynamically unload list of plugins
*
* \param pplugin: pointer to linked-list for this kind of plugin
* \param each: NULL, or each_plugin_cb_t callback for each instantiated plugin
* \param each_user: pointer passed to each callback
*
* Allows you to destroy a class of plugins from a specified linked-list
* created by a call to lws_plugins_init().
*
* The each callback allows you to deinit each inistantiated callback and pass a
* pointer each_user to it, just before its footprint is destroyed.
*/
LWS_VISIBLE LWS_EXTERN int
lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
void *each_user);
#if defined(LWS_WITH_PLUGINS_BUILTIN)
/* provide exports for builtin plugin protocols */
extern const struct lws_protocols post_demo_protocols[1];
extern const struct lws_protocols lws_raw_proxy_protocols[1];
extern const struct lws_protocols lws_status_protocols[1];
extern const struct lws_protocols lws_mirror_protocols[1];
extern const struct lws_protocols lws_ssh_base_protocols[2];
extern const struct lws_protocols post_demo_protocols[1];
extern const struct lws_protocols dumb_increment_protocols[1];
extern const struct lws_protocols deaddrop_protocols[1];
extern const struct lws_protocols lws_raw_test_protocols[1];
extern const struct lws_protocols lws_sshd_demo_protocols[1];
extern const struct lws_protocols lws_acme_client_protocols[1];
extern const struct lws_protocols client_loopback_test_protocols[1];
extern const struct lws_protocols fulltext_demo_protocols[1];
extern const struct lws_protocols lws_openmetrics_export_protocols[
#if defined(LWS_WITH_SERVER) && defined(LWS_WITH_CLIENT) && defined(LWS_ROLE_WS)
4
#else
#if defined(LWS_WITH_SERVER)
3
#else
1
#endif
#endif
];
#define LWSOMPROIDX_DIRECT_HTTP_SERVER 0
#define LWSOMPROIDX_PROX_HTTP_SERVER 1
#define LWSOMPROIDX_PROX_WS_SERVER 2
#define LWSOMPROIDX_PROX_WS_CLIENT 3
#endif
///@}

View File

@ -0,0 +1,105 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/*! \defgroup pur Sanitize / purify SQL and JSON helpers
*
* ##Sanitize / purify SQL and JSON helpers
*
* APIs for escaping untrusted JSON and SQL safely before use
*/
//@{
/**
* lws_sql_purify() - like strncpy but with escaping for sql quotes
*
* \param escaped: output buffer
* \param string: input buffer ('/0' terminated)
* \param len: output buffer max length
*
* Because escaping expands the output string, it's not
* possible to do it in-place, ie, with escaped == string
*/
LWS_VISIBLE LWS_EXTERN const char *
lws_sql_purify(char *escaped, const char *string, size_t len);
/**
* lws_sql_purify_len() - return length of purified version of input string
*
* \param string: input buffer ('/0' terminated)
*
* Calculates any character escaping without writing it anywhere and returns the
* calculated length of the purified string.
*/
int
lws_sql_purify_len(const char *p);
/**
* lws_json_purify() - like strncpy but with escaping for json chars
*
* \param escaped: output buffer
* \param string: input buffer ('/0' terminated)
* \param len: output buffer max length
* \param in_used: number of bytes of string we could escape in len
*
* Because escaping expands the output string, it's not
* possible to do it in-place, ie, with escaped == string
*/
LWS_VISIBLE LWS_EXTERN const char *
lws_json_purify(char *escaped, const char *string, int len, int *in_used);
/**
* lws_json_purify_len() - find out the escaped length of a string
*
* \param string: input buffer ('/0' terminated)
*
* JSON may have to expand escapes by up to 6x the original depending on what
* it is. This doesn't actually do the escaping but goes through the motions
* and computes the length of the escaped string.
*/
LWS_VISIBLE LWS_EXTERN int
lws_json_purify_len(const char *string);
/**
* lws_filename_purify_inplace() - replace scary filename chars with underscore
*
* \param filename: filename to be purified
*
* Replace scary characters in the filename (it should not be a path)
* with underscore, so it's safe to use.
*/
LWS_VISIBLE LWS_EXTERN void
lws_filename_purify_inplace(char *filename);
LWS_VISIBLE LWS_EXTERN int
lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_plat_write_file(const char *filename, void *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_plat_read_file(const char *filename, void *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_plat_recommended_rsa_bits(void);
///@}

Some files were not shown because too many files have changed in this diff Show More