add linux lib
This commit is contained in:
parent
1aac2fcd8d
commit
dd53ccade6
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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_ ]
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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_
|
||||
|
|
@ -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, ×tamp);
|
||||
// ... (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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
@ -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
|
||||
//@}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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 */
|
||||
};
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
///@}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
///@}
|
||||
|
||||
|
|
@ -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
|
||||
///@}
|
||||
|
|
@ -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
|
||||
///@}
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
///@}
|
||||
|
|
@ -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
|
||||
|
|
@ -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; \
|
||||
} \
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
///@}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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
|
||||
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
|
@ -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, \
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
//@}
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
||||
///@}
|
||||
|
|
@ -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
Loading…
Reference in New Issue