diff options
Diffstat (limited to 'external')
134 files changed, 32 insertions, 27788 deletions
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 69dc84e87..1fc4d64c1 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -34,43 +34,22 @@ # We always compile if we are building statically to reduce static dependency issues... # ...except for FreeBSD, because FreeBSD is a special case that doesn't play well with # others. -if(NOT IOS) - find_package(Miniupnpc QUIET) -endif() -# If we have the correct shared version and we're not building static, use it -if(STATIC OR IOS) - set(USE_SHARED_MINIUPNPC false) -elseif(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER) - set(USE_SHARED_MINIUPNPC true) -endif() +find_package(Miniupnpc REQUIRED) -if(USE_SHARED_MINIUPNPC) - message(STATUS "Using shared miniupnpc found at ${MINIUPNP_INCLUDE_DIR}") +message(STATUS "Using in-tree miniupnpc") - set(UPNP_STATIC false PARENT_SCOPE) - set(UPNP_INCLUDE ${MINIUPNP_INCLUDE_DIR} PARENT_SCOPE) - set(UPNP_LIBRARIES ${MINIUPNP_LIBRARY} PARENT_SCOPE) -else() - if(STATIC) - message(STATUS "Using miniupnpc from local source tree for static build") - else() - message(STATUS "Using miniupnpc from local source tree (/external/miniupnpc)") - endif() +add_subdirectory(miniupnp/miniupnpc) - add_subdirectory(miniupnpc) - - set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external") - if(MSVC) - set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267") - elseif(NOT MSVC) - set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value") - endif() - - set(UPNP_STATIC true PARENT_SCOPE) - set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE) +set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external") +if(MSVC) + set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267") +elseif(NOT MSVC) + set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value") endif() +set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE) + find_package(Unbound) if(NOT UNBOUND_INCLUDE_DIR OR STATIC) diff --git a/external/db_drivers/liblmdb/mdb.c b/external/db_drivers/liblmdb/mdb.c index dde428c43..8e2b1eca1 100644 --- a/external/db_drivers/liblmdb/mdb.c +++ b/external/db_drivers/liblmdb/mdb.c @@ -7231,7 +7231,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data, dkey.mv_size = 0; - if (flags == MDB_CURRENT) { + if (flags & MDB_CURRENT) { if (!(mc->mc_flags & C_INITIALIZED)) return EINVAL; rc = MDB_SUCCESS; @@ -7624,7 +7624,7 @@ put_sub: xdata.mv_size = 0; xdata.mv_data = ""; leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); - if (flags & MDB_CURRENT) { + if (flags == MDB_CURRENT) { xflags = MDB_CURRENT|MDB_NOSPILL; } else { mdb_xcursor_init1(mc, leaf); diff --git a/external/db_drivers/liblmdb/mdb_load.c b/external/db_drivers/liblmdb/mdb_load.c index 797c2f979..c74ce81c9 100644 --- a/external/db_drivers/liblmdb/mdb_load.c +++ b/external/db_drivers/liblmdb/mdb_load.c @@ -78,6 +78,7 @@ static void readhdr(void) { char *ptr; + flags = 0; while (fgets(dbuf.mv_data, dbuf.mv_size, stdin) != NULL) { lineno++; if (!strncmp(dbuf.mv_data, "VERSION=", STRLENOF("VERSION="))) { @@ -303,7 +304,7 @@ int main(int argc, char *argv[]) MDB_cursor *mc; MDB_dbi dbi; char *envname; - int envflags = 0, putflags = 0; + int envflags = MDB_NOSYNC, putflags = 0; int dohdr = 0, append = 0; MDB_val prevk; @@ -391,13 +392,11 @@ int main(int argc, char *argv[]) kbuf.mv_data = malloc(kbuf.mv_size * 2); k0buf.mv_size = kbuf.mv_size; k0buf.mv_data = (char *)kbuf.mv_data + kbuf.mv_size; - prevk.mv_size = 0; prevk.mv_data = k0buf.mv_data; while(!Eof) { MDB_val key, data; int batch = 0; - flags = 0; int appflag; if (!dohdr) { @@ -416,6 +415,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } + prevk.mv_size = 0; if (append) { mdb_set_compare(txn, dbi, greater); if (flags & MDB_DUPSORT) @@ -443,7 +443,7 @@ int main(int argc, char *argv[]) appflag = MDB_APPEND; if (flags & MDB_DUPSORT) { if (prevk.mv_size == key.mv_size && !memcmp(prevk.mv_data, key.mv_data, key.mv_size)) - appflag = MDB_APPENDDUP; + appflag = MDB_CURRENT|MDB_APPENDDUP; else { memcpy(prevk.mv_data, key.mv_data, key.mv_size); prevk.mv_size = key.mv_size; @@ -477,6 +477,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; } + if (appflag & MDB_APPENDDUP) { + MDB_val k, d; + mdb_cursor_get(mc, &k, &d, MDB_LAST); + } batch = 0; } } diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index 212a1822d..8a5dc91e9 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -1967,10 +1967,12 @@ void VRegistry::setCategories(const char* categories, bool clear) { base::threading::ScopedLock scopedLock(lock()); auto insert = [&](std::stringstream& ss, Level level) { m_categories.push_back(std::make_pair(ss.str(), level)); + m_cached_allowed_categories.clear(); }; if (clear) { m_categories.clear(); + m_cached_allowed_categories.clear(); m_categoriesString.clear(); } if (!m_categoriesString.empty()) @@ -2033,15 +2035,22 @@ static int priority(Level level) { bool VRegistry::allowed(Level level, const char* category) { base::threading::ScopedLock scopedLock(lock()); + const std::string scategory = category; + const std::map<std::string, int>::const_iterator it = m_cached_allowed_categories.find(scategory); + if (it != m_cached_allowed_categories.end()) + return priority(level) <= it->second; if (m_categories.empty() || category == nullptr) { return false; } else { std::deque<std::pair<std::string, Level>>::const_reverse_iterator it = m_categories.rbegin(); for (; it != m_categories.rend(); ++it) { if (base::utils::Str::wildCardMatch(category, it->first.c_str())) { - return priority(level) <= priority(it->second); + const int p = priority(it->second); + m_cached_allowed_categories.insert(std::make_pair(std::move(scategory), p)); + return priority(level) <= p; } } + m_cached_allowed_categories.insert(std::make_pair(std::move(scategory), -1)); return false; } } diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h index 3270bd607..6b8b4fc35 100644 --- a/external/easylogging++/easylogging++.h +++ b/external/easylogging++/easylogging++.h @@ -2485,6 +2485,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { inline void clearCategories(void) { base::threading::ScopedLock scopedLock(lock()); m_categories.clear(); + m_cached_allowed_categories.clear(); } inline void clearModules(void) { @@ -2526,6 +2527,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { base::type::EnumType* m_pFlags; std::map<std::string, base::type::VerboseLevel> m_modules; std::deque<std::pair<std::string, Level>> m_categories; + std::map<std::string, int> m_cached_allowed_categories; std::string m_categoriesString; std::string m_filenameCommonPrefix; }; diff --git a/external/miniupnp b/external/miniupnp new file mode 160000 +Subproject 6a63f9954959119568fbc4af57d7b491b9428d8 diff --git a/external/miniupnpc/.gitignore b/external/miniupnpc/.gitignore deleted file mode 100644 index 6bc38af20..000000000 --- a/external/miniupnpc/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -deb_dist/ -build/ -*.o -*.a -*.so -*.dll -*.dll.def -*.exe -*.lib -*.dylib -Makefile.bak -miniupnpcstrings.h -pythonmodule -pythonmodule3 -upnpc-shared -upnpc-static -minihttptestserver -minixmlvalid -testminiwget -validateminiwget -validateminixml -java/miniupnpc_*.jar -_jnaerator.* -out.errors.txt -jnaerator-*.jar -miniupnpc.h.bak -testupnpreplyparse -validateupnpreplyparse -testportlistingparse -validateportlistingparse -listdevices -testigddescparse -validateigddescparse -dist/ -miniupnpc.egg-info/ -init diff --git a/external/miniupnpc/CMakeLists.txt b/external/miniupnpc/CMakeLists.txt deleted file mode 100644 index 2df8d474b..000000000 --- a/external/miniupnpc/CMakeLists.txt +++ /dev/null @@ -1,203 +0,0 @@ -cmake_minimum_required (VERSION 2.6) - -project (miniupnpc C) -set (MINIUPNPC_VERSION 2.0) -set (MINIUPNPC_API_VERSION 16) - -# - we comment out this block as we don't support these other build types -if(0) -if (NOT CMAKE_BUILD_TYPE) - if (WIN32) - set (DEFAULT_BUILD_TYPE MinSizeRel) - else (WIN32) - set (DEFAULT_BUILD_TYPE RelWithDebInfo) - endif(WIN32) - set (CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif() -endif() - -option (UPNPC_BUILD_STATIC "Build static library" TRUE) -option (UPNPC_BUILD_SHARED "Build shared library" FALSE) -option (UPNPC_BUILD_TESTS "Build test executables" FALSE) -option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE) - -mark_as_advanced (NO_GETADDRINFO) - -if (NO_GETADDRINFO) - add_definitions (-DNO_GETADDRINFO) -endif (NO_GETADDRINFO) - -if (NOT WIN32) - add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) - add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE) - if (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "DragonFly") - # add_definitions (-D_POSIX_C_SOURCE=200112L) - add_definitions (-D_XOPEN_SOURCE=600) - endif (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_SYSTEM_NAME STREQUAL "DragonFly") - if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)") - add_definitions (-D__EXTENSIONS__ -std=c99) - endif () -else (NOT WIN32) - add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends -endif (NOT WIN32) - -if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") - add_definitions (-D_DARWIN_C_SOURCE) -endif () - -# - we comment out this block as we already set flags -if(0) -# Set compiler specific build flags -if (CMAKE_COMPILER_IS_GNUC) - # Set our own default flags at first run. - if (NOT CONFIGURED) - - if (NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - set (_PIC -fPIC) - endif (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - - set (CMAKE_C_FLAGS "${_PIC} -Wall $ENV{CFLAGS}" # CMAKE_C_FLAGS gets appended to the other C flags - CACHE STRING "Flags used by the C compiler during normal builds." FORCE) - set (CMAKE_C_FLAGS_DEBUG "-g -DDDEBUG" - CACHE STRING "Flags used by the C compiler during debug builds." FORCE) - set (CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - set (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG" - CACHE STRING "Flags used by the C compiler during release builds." FORCE) - - endif (NOT CONFIGURED) -endif () -endif() - -# always add -fPIC -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") -set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fPIC") -set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fPIC") -set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fPIC") -set (CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -fPIC") - -configure_file (${CMAKE_CURRENT_SOURCE_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) -include_directories (${CMAKE_CURRENT_BINARY_DIR}) - -set (MINIUPNPC_SOURCES - igd_desc_parse.c - miniupnpc.c - minixml.c - minisoap.c - minissdpc.c - miniwget.c - upnpcommands.c - upnpdev.c - upnpreplyparse.c - upnperrors.c - connecthostport.c - portlistingparse.c - receivedata.c -) - -if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - set (MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) -endif (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - -if (WIN32) - set_source_files_properties (${MINIUPNPC_SOURCES} PROPERTIES - COMPILE_DEFINITIONS "MINIUPNP_STATICLIB;MINIUPNP_EXPORTS" - ) -endif (WIN32) - -if (WIN32) - # We use set instead of find_library because otherwise static compilation on Windows breaks. Don't ask me why, just roll with it. - # find_library (WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32) - # find_library (IPHLPAPI_LIBRARY NAMES iphlpapi) - set (WINSOCK2_LIBRARY ws2_32) - set (IPHLPAPI_LIBRARY iphlpapi) - set (LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS}) -#elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris") -# find_library (SOCKET_LIBRARY NAMES socket) -# find_library (NSL_LIBRARY NAMES nsl) -# find_library (RESOLV_LIBRARY NAMES resolv) -# set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) -endif (WIN32) - -if (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED) - message (FATAL "Both shared and static libraries are disabled!") -endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED) - -if (UPNPC_BUILD_STATIC) - add_library (libminiupnpc-static STATIC ${MINIUPNPC_SOURCES}) - set_target_properties (libminiupnpc-static PROPERTIES OUTPUT_NAME "miniupnpc") - target_link_libraries (libminiupnpc-static ${LDLIBS}) - set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} libminiupnpc-static) - set (UPNPC_LIBRARY_TARGET libminiupnpc-static) - # add_executable (upnpc-static upnpc.c) - # target_link_libraries (upnpc-static LINK_PRIVATE libminiupnpc-static) -endif (UPNPC_BUILD_STATIC) - -if (UPNPC_BUILD_SHARED) - add_library (libminiupnpc-shared SHARED ${MINIUPNPC_SOURCES}) - set_target_properties (libminiupnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc") - set_target_properties (libminiupnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION}) - set_target_properties (libminiupnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION}) - target_link_libraries (libminiupnpc-shared ${LDLIBS}) - set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} libminiupnpc-shared) - set (UPNPC_LIBRARY_TARGET libminiupnpc-shared) - add_executable (upnpc-shared upnpc.c) - target_link_libraries (upnpc-shared LINK_PRIVATE libminiupnpc-shared) -endif (UPNPC_BUILD_SHARED) - -if (UPNPC_BUILD_TESTS) - add_executable (testminixml testminixml.c minixml.c igd_desc_parse.c) - target_link_libraries (testminixml ${LDLIBS}) - - add_executable (minixmlvalid minixmlvalid.c minixml.c) - target_link_libraries (minixmlvalid ${LDLIBS}) - - add_executable (testupnpreplyparse testupnpreplyparse.c - minixml.c upnpreplyparse.c) - target_link_libraries (testupnpreplyparse ${LDLIBS}) - - add_executable (testigddescparse testigddescparse.c - igd_desc_parse.c minixml.c miniupnpc.c miniwget.c minissdpc.c - upnpcommands.c upnpreplyparse.c minisoap.c connecthostport.c - portlistingparse.c receivedata.c - ) - target_link_libraries (testigddescparse ${LDLIBS}) - - add_executable (testminiwget testminiwget.c - miniwget.c miniupnpc.c minisoap.c upnpcommands.c minissdpc.c - upnpreplyparse.c minixml.c igd_desc_parse.c connecthostport.c - portlistingparse.c receivedata.c - ) - target_link_libraries (testminiwget ${LDLIBS}) - -# set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} testminixml minixmlvalid testupnpreplyparse testigddescparse testminiwget) -endif (UPNPC_BUILD_TESTS) - - -install (TARGETS ${UPNPC_INSTALL_TARGETS} - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib${LIB_SUFFIX} - ARCHIVE DESTINATION lib${LIB_SUFFIX} -) -install (FILES - miniupnpc.h - miniwget.h - upnpcommands.h - igd_desc_parse.h - upnpreplyparse.h - upnperrors.h - upnpdev.h - miniupnpctypes.h - portlistingparse.h - miniupnpc_declspec.h - DESTINATION include/miniupnpc -) - -# commented out by Ben Boeckel, who I presume knows what he's doing;) -# set (CONFIGURED YES CACHE INTERNAL "") - -# vim: ts=2:sw=2 diff --git a/external/miniupnpc/Changelog.txt b/external/miniupnpc/Changelog.txt deleted file mode 100644 index a3ef51809..000000000 --- a/external/miniupnpc/Changelog.txt +++ /dev/null @@ -1,687 +0,0 @@ -$Id: Changelog.txt,v 1.226 2016/12/16 08:57:19 nanard Exp $ -miniUPnP client Changelog. - -2017/05/05: - Fix CVE-2017-8798 Thanks to tin/Team OSTStrom - -2016/11/11: - check strlen before memcmp in XML parsing portlistingparse.c - fix build under SOLARIS and CYGWIN - -2016/10/11: - Add python 3 compatibility to IGD test - -VERSION 2.0 : released 2016/04/19 - -2016/01/24: - change miniwget to return HTTP status code - increments API_VERSION to 16 - -2016/01/22: - Improve UPNPIGD_IsConnected() to check if WAN address is not private. - parse HTTP response status line in miniwget.c - -2015/10/26: - snprintf() overflow check. check overflow in simpleUPnPcommand2() - -2015/10/25: - fix compilation with old macs - fix compilation with mingw32 (for Appveyor) - fix python module for python <= 2.3 - -2015/10/08: - Change sameport to localport - see https://github.com/miniupnp/miniupnp/pull/120 - increments API_VERSION to 15 - -2015/09/15: - Fix buffer overflow in igd_desc_parse.c/IGDstartelt() - Discovered by Aleksandar Nikolic of Cisco Talos - -2015/08/28: - move ssdpDiscoverDevices() to minissdpc.c - -2015/08/27: - avoid unix socket leak in getDevicesFromMiniSSDPD() - -2015/08/16: - Also accept "Up" as ConnectionStatus value - -2015/07/23: - split getDevicesFromMiniSSDPD - add ttl argument to upnpDiscover() functions - increments API_VERSION to 14 - -2015/07/22: - Read USN from SSDP messages. - -2015/07/15: - Check malloc/calloc - -2015/06/16: - update getDevicesFromMiniSSDPD() to process longer minissdpd - responses - -2015/05/22: - add searchalltypes param to upnpDiscoverDevices() - increments API_VERSION to 13 - -2015/04/30: - upnpc: output version on the terminal - -2015/04/27: - _BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE - fix CMakeLists.txt COMPILE_DEFINITIONS - fix getDevicesFromMiniSSDPD() not setting scope_id - improve -r command of upnpc command line tool - -2014/11/17: - search all : - upnpDiscoverDevices() / upnpDiscoverAll() functions - listdevices executable - increment API_VERSION to 12 - validate igd_desc_parse - -2014/11/13: - increment API_VERSION to 11 - -2014/11/05: - simplified function GetUPNPUrls() - -2014/09/11: - use remoteHost arg of DeletePortMapping - -2014/09/06: - Fix python3 build - -2014/07/01: - Fix parsing of IGD2 root descriptions - -2014/06/10: - rename LIBSPEC to MINIUPNP_LIBSPEC - -2014/05/15: - Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange - -2014/02/05: - handle EINPROGRESS after connect() - -2014/02/03: - minixml now handle XML comments - -VERSION 1.9 : released 2014/01/31 - -2014/01/31: - added argument remoteHost to UPNP_GetSpecificPortMappingEntry() - increment API_VERSION to 10 - -2013/12/09: - --help and -h arguments in upnpc.c - -2013/10/07: - fixed potential buffer overrun in miniwget.c - Modified UPNP_GetValidIGD() to check for ExternalIpAddress - -2013/08/01: - define MAXHOSTNAMELEN if not already done - -2013/06/06: - update upnpreplyparse to allow larger values (128 chars instead of 64) - -2013/05/14: - Update upnpreplyparse to take into account "empty" elements - validate upnpreplyparse.c code with "make check" - -2013/05/03: - Fix Solaris build thanks to Maciej MaÅ‚ecki - -2013/04/27: - Fix testminiwget.sh for BSD - -2013/03/23: - Fixed Makefile for *BSD - -2013/03/11: - Update Makefile to use JNAerator version 0.11 - -2013/02/11: - Fix testminiwget.sh for use with dash - Use $(DESTDIR) in Makefile - -VERSION 1.8 : released 2013/02/06 - -2012/10/16: - fix testminiwget with no IPv6 support - -2012/09/27: - Rename all include guards to not clash with C99 - (7.1.3 Reserved identifiers). - -2012/08/30: - Added -e option to upnpc program (set description for port mappings) - -2012/08/29: - Python 3 support (thanks to Christopher Foo) - -2012/08/11: - Fix a memory link in UPNP_GetValidIGD() - Try to handle scope id in link local IPv6 URL under MS Windows - -2012/07/20: - Disable HAS_IP_MREQN on DragonFly BSD - -2012/06/28: - GetUPNPUrls() now inserts scope into link-local IPv6 addresses - -2012/06/23: - More error return checks in upnpc.c - #define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id - parseURL() now parses IPv6 addresses scope - new parameter for miniwget() : IPv6 address scope - increment API_VERSION to 9 - -2012/06/20: - fixed CMakeLists.txt - -2012/05/29 - Improvements in testminiwget.sh - -VERSION 1.7 : released 2012/05/24 - -2012/05/01: - Cleanup settings of CFLAGS in Makefile - Fix signed/unsigned integer comparaisons - -2012/04/20: - Allow to specify protocol with TCP or UDP for -A option - -2012/04/09: - Only try to fetch XML description once in UPNP_GetValidIGD() - Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments. - -2012/04/05: - minor improvements to minihttptestserver.c - -2012/03/15: - upnperrors.c returns valid error string for unrecognized error codes - -2012/03/08: - make minihttptestserver listen on loopback interface instead of 0.0.0.0 - -2012/01/25: - Maven installation thanks to Alexey Kuznetsov - -2012/01/21: - Replace WIN32 macro by _WIN32 - -2012/01/19: - Fixes in java wrappers thanks to Alexey Kuznetsov : - https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc - Make and install .deb packages (python) thanks to Alexey Kuznetsov : - https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc - -2012/01/07: - The multicast interface can now be specified by name with IPv4. - -2012/01/02: - Install man page - -2011/11/25: - added header to Port Mappings list in upnpc.c - -2011/10/09: - Makefile : make clean now removes jnaerator generated files. - MINIUPNPC_VERSION in miniupnpc.h (updated by make) - -2011/09/12: - added rootdescURL to UPNPUrls structure. - -VERSION 1.6 : released 2011/07/25 - -2011/07/25: - Update doc for version 1.6 release - -2011/06/18: - Fix for windows in miniwget.c - -2011/06/04: - display remote host in port mapping listing - -2011/06/03: - Fix in make install : there were missing headers - -2011/05/26: - Fix the socket leak in miniwget thanks to Richard Marsh. - Permit to add leaseduration in -a command. Display lease duration. - -2011/05/15: - Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6 - -2011/05/09: - add a test in testminiwget.sh. - more error checking in miniwget.c - -2011/05/06: - Adding some tool to test and validate miniwget.c - simplified and debugged miniwget.c - -2011/04/11: - moving ReceiveData() to a receivedata.c file. - parsing presentation url - adding IGD v2 WANIPv6FirewallControl commands - -2011/04/10: - update of miniupnpcmodule.c - comments in miniwget.c, update in testminiwget - Adding errors codes from IGD v2 - new functions in upnpc.c for IGD v2 - -2011/04/09: - Support for litteral ip v6 address in miniwget - -2011/04/08: - Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1 - Updating APIVERSION - Supporting IPV6 in upnpDiscover() - Adding a -6 option to upnpc command line tool - -2011/03/18: - miniwget/parseURL() : return an error when url param is null. - fixing GetListOfPortMappings() - -2011/03/14: - upnpDiscover() now reporting an error code. - improvements in comments. - -2011/03/11: - adding miniupnpcstrings.h.cmake and CMakeLists.txt files. - -2011/02/15: - Implementation of GetListOfPortMappings() - -2011/02/07: - updates to minixml to support character data starting with spaces - minixml now support CDATA - upnpreplyparse treats <NewPortListing> specificaly - change in simpleUPnPcommand to return the buffer (simplification) - -2011/02/06: - Added leaseDuration argument to AddPortMapping() - Starting to implement GetListOfPortMappings() - -2011/01/11: - updating wingenminiupnpcstrings.c - -2011/01/04: - improving updateminiupnpcstrings.sh - -VERSION 1.5 : released 2011/01/01 - -2010/12/21: - use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo - -2010/12/11: - Improvements on getHTTPResponse() code. - -2010/12/09: - new code for miniwget that handle Chunked transfer encoding - using getHTTPResponse() in SOAP call code - Adding MANIFEST.in for 'python setup.py bdist_rpm' - -2010/11/25: - changes to minissdpc.c to compile under Win32. - see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729 - -2010/09/17: - Various improvement to Makefile from MichaÅ‚ Górny - -2010/08/05: - Adding the script "external-ip.sh" from Reuben Hawkins - -2010/06/09: - update to python module to match modification made on 2010/04/05 - update to Java test code to match modification made on 2010/04/05 - all UPNP_* function now return an error if the SOAP request failed - at HTTP level. - -2010/04/17: - Using GetBestRoute() under win32 in order to find the - right interface to use. - -2010/04/12: - Retrying with HTTP/1.1 if HTTP/1.0 failed. see - http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703 - -2010/04/07: - avoid returning duplicates in upnpDiscover() - -2010/04/05: - Create a connecthostport.h/.c with connecthostport() function - and use it in miniwget and miniupnpc. - Use getnameinfo() instead of inet_ntop or inet_ntoa - Work to make miniupnpc IPV6 compatible... - Add java test code. - Big changes in order to support device having both WANIPConnection - and WANPPPConnection. - -2010/04/04: - Use getaddrinfo() instead of gethostbyname() in miniwget. - -2010/01/06: - #define _DARWIN_C_SOURCE for Mac OS X - -2009/12/19: - Improve MinGW32 build - -2009/12/11: - adding a MSVC9 project to build the static library and executable - -2009/12/10: - Fixing some compilation stuff for Windows/MinGW - -2009/12/07: - adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS - some fixes for Windows when using virtual ethernet adapters (it is the - case with VMWare installed). - -2009/12/04: - some fixes for AmigaOS compilation - Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked - transfer encoding) - -2009/12/03: - updating printIDG and testigddescparse.c for debug. - modifications to compile under AmigaOS - adding a testminiwget program - Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked - transfer encoding - -2009/11/26: - fixing updateminiupnpcstrings.sh to take into account - which command that does not return an error code. - -VERSION 1.4 : released 2009/10/30 - -2009/10/16: - using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module. - -2009/10/10: - Some fixes for compilation under Solaris - compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464 - -2009/09/21: - fixing the code to ignore EINTR during connect() calls. - -2009/08/07: - Set socket timeout for connect() - Some cleanup in miniwget.c - -2009/08/04: - remove multiple redirections with -d in upnpc.c - Print textual error code in upnpc.c - Ignore EINTR during the connect() and poll() calls. - -2009/07/29: - fix in updateminiupnpcstrings.sh if OS name contains "/" - Sending a correct value for MX: field in SSDP request - -2009/07/20: - Change the Makefile to compile under Mac OS X - Fixed a stackoverflow in getDevicesFromMiniSSDPD() - -2009/07/09: - Compile under Haiku - generate miniupnpcstrings.h.in from miniupnpcstrings.h - -2009/06/04: - patching to compile under CygWin and cross compile for minGW - -VERSION 1.3 : - -2009/04/17: - updating python module - Use strtoull() when using C99 - -2009/02/28: - Fixed miniwget.c for compiling under sun - -2008/12/18: - cleanup in Makefile (thanks to Paul de Weerd) - minissdpc.c : win32 compatibility - miniupnpc.c : changed xmlns prefix from 'm' to 'u' - Removed NDEBUG (using DEBUG) - -2008/10/14: - Added the ExternalHost argument to DeletePortMapping() - -2008/10/11: - Added the ExternalHost argument to AddPortMapping() - Put a correct User-Agent: header in HTTP requests. - -VERSION 1.2 : - -2008/10/07: - Update docs - -2008/09/25: - Integrated sameport patch from Dario Meloni : Added a "sameport" - argument to upnpDiscover(). - -2008/07/18: - small modif to make Clang happy :) - -2008/07/17: - #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV... - -2008/07/14: - include declspec.h in installation (to /usr/include/miniupnpc) - -VERSION 1.1 : - -2008/07/04: - standard options for install/ln instead of gnu-specific stuff. - -2008/07/03: - now builds a .dll and .lib with win32. (mingw32) - -2008/04/28: - make install now install the binary of the upnpc tool - -2008/04/27: - added testupnpigd.py - added error strings for miniupnpc "internal" errors - improved python module error/exception reporting. - -2008/04/23: - Completely rewrite igd_desc_parse.c in order to be compatible with - Linksys WAG200G - Added testigddescparse - updated python module - -VERSION 1.0 : - -2008/02/21: - put some #ifdef DEBUG around DisplayNameValueList() - -2008/02/18: - Improved error reporting in upnpcommands.c - UPNP_GetStatusInfo() returns LastConnectionError - -2008/02/16: - better error handling in minisoap.c - improving display of "valid IGD found" in upnpc.c - -2008/02/03: - Fixing UPNP_GetValidIGD() - improved make install :) - -2007/12/22: - Adding upnperrors.c/h to provide a strupnperror() function - used to translate UPnP error codes to string. - -2007/12/19: - Fixing getDevicesFromMiniSSDPD() - improved error reporting of UPnP functions - -2007/12/18: - It is now possible to specify a different location for MiniSSDPd socket. - working with MiniSSDPd is now more efficient. - python module improved. - -2007/12/16: - improving error reporting - -2007/12/13: - Try to improve compatibility by using HTTP/1.0 instead of 1.1 and - XML a bit different for SOAP. - -2007/11/25: - fixed select() call for linux - -2007/11/15: - Added -fPIC to CFLAG for better shared library code. - -2007/11/02: - Fixed a potential socket leak in miniwget2() - -2007/10/16: - added a parameter to upnpDiscover() in order to allow the use of another - interface than the default multicast interface. - -2007/10/12: - Fixed the creation of symbolic link in Makefile - -2007/10/08: - Added man page - -2007/10/02: - fixed memory bug in GetUPNPUrls() - -2007/10/01: - fixes in the Makefile - Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly. - Added SONAME in the shared library to please debian :) - fixed MS Windows compilation (minissdpd is not available under MS Windows). - -2007/09/25: - small change to Makefile to be able to install in a different location - (default is /usr) - -2007/09/24: - now compiling both shared and static library - -2007/09/19: - Cosmetic changes on upnpc.c - -2007/09/02: - adapting to new miniSSDPd (release version ?) - -2007/08/31: - Usage of miniSSDPd to skip discovery process. - -2007/08/27: - fixed python module to allow compilation with Python older than Python 2.4 - -2007/06/12: - Added a python module. - -2007/05/19: - Fixed compilation under MinGW - -2007/05/15: - fixed a memory leak in AddPortMapping() - Added testupnpreplyparse executable to check the parsing of - upnp soap messages - minixml now ignore namespace prefixes. - -2007/04/26: - upnpc now displays external ip address with -s or -l - -2007/04/11: - changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210" - -2007/03/19: - cleanup in miniwget.c - -2007/03/01: - Small typo fix... - -2007/01/30: - Now parsing the HTTP header from SOAP responses in order to - get content-length value. - -2007/01/29: - Fixed the Soap Query to speedup the HTTP request. - added some Win32 DLL stuff... - -2007/01/27: - Fixed some WIN32 compatibility issues - -2006/12/14: - Added UPNPIGD_IsConnected() function in miniupnp.c/.h - Added UPNP_GetValidIGD() in miniupnp.c/.h - cleaned upnpc.c main(). now using UPNP_GetValidIGD() - -2006/12/07: - Version 1.0-RC1 released - -2006/12/03: - Minor changes to compile under SunOS/Solaris - -2006/11/30: - made a minixml parser validator program - updated minixml to handle attributes correctly - -2006/11/22: - Added a -r option to the upnpc sample thanks to Alexander Hubmann. - -2006/11/19: - Cleanup code to make it more ANSI C compliant - -2006/11/10: - detect and display local lan address. - -2006/11/04: - Packets and Bytes Sent/Received are now unsigned int. - -2006/11/01: - Bug fix thanks to Giuseppe D'Angelo - -2006/10/31: - C++ compatibility for .h files. - Added a way to get ip Address on the LAN used to reach the IGD. - -2006/10/25: - Added M-SEARCH to the services in the discovery process. - -2006/10/22: - updated the Makefile to use makedepend, added a "make install" - update Makefile - -2006/10/20: - fixing the description url parsing thanks to patch sent by - Wayne Dawe. - Fixed/translated some comments. - Implemented a better discover process, first looking - for IGD then for root devices (as some devices only reply to - M-SEARCH for root devices). - -2006/09/02: - added freeUPNPDevlist() function. - -2006/08/04: - More command line arguments checking - -2006/08/01: - Added the .bat file to compile under Win32 with minGW32 - -2006/07/31: - Fixed the rootdesc parser (igd_desc_parse.c) - -2006/07/20: - parseMSEARCHReply() is now returning the ST: line as well - starting changes to detect several UPnP devices on the network - -2006/07/19: - using GetCommonLinkProperties to get down/upload bitrate - diff --git a/external/miniupnpc/LICENSE b/external/miniupnpc/LICENSE deleted file mode 100644 index 081673370..000000000 --- a/external/miniupnpc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -MiniUPnPc -Copyright (c) 2005-2016, Thomas BERNARD -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * 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. - * The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - diff --git a/external/miniupnpc/MANIFEST.in b/external/miniupnpc/MANIFEST.in deleted file mode 100644 index 543ffd6ac..000000000 --- a/external/miniupnpc/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include README -include VERSION -include LICENSE -include miniupnpcmodule.c -include setup.py -include *.h -include libminiupnpc.a diff --git a/external/miniupnpc/Makefile b/external/miniupnpc/Makefile deleted file mode 100644 index 178fbf5d3..000000000 --- a/external/miniupnpc/Makefile +++ /dev/null @@ -1,390 +0,0 @@ -# $Id: Makefile,v 1.134 2016/10/07 09:04:36 nanard Exp $ -# MiniUPnP Project -# http://miniupnp.free.fr/ -# http://miniupnp.tuxfamily.org/ -# https://github.com/miniupnp/miniupnp -# (c) 2005-2017 Thomas Bernard -# to install use : -# $ make DESTDIR=/tmp/dummylocation install -# or -# $ INSTALLPREFIX=/usr/local make install -# or -# $ make install (default INSTALLPREFIX is /usr) -OS = $(shell uname -s) -VERSION = $(shell cat VERSION) - -ifeq ($(OS), Darwin) -JARSUFFIX=mac -LIBTOOL ?= $(shell which libtool) -endif -ifeq ($(OS), Linux) -JARSUFFIX=linux -endif -ifneq (,$(findstring NT-5.1,$(OS))) -JARSUFFIX=win32 -endif - -HAVE_IPV6 ?= yes -export HAVE_IPV6 - -CC ?= gcc -#AR = gar -#CFLAGS = -O -g -DDEBUG -CFLAGS ?= -O -CFLAGS += -Wall -CFLAGS += -W -Wstrict-prototypes -CFLAGS += -fno-common -CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT -CFLAGS += -DMINIUPNPC_GET_SRC_ADDR -CFLAGS += -D_BSD_SOURCE -CFLAGS += -D_DEFAULT_SOURCE -ifeq ($(OS), NetBSD) -CFLAGS += -D_NETBSD_SOURCE -endif -ifneq ($(OS), FreeBSD) -ifneq ($(OS), Darwin) -#CFLAGS += -D_POSIX_C_SOURCE=200112L -CFLAGS += -D_XOPEN_SOURCE=600 -endif -endif -#CFLAGS += -ansi -#CFLAGS += -DNO_GETADDRINFO -INSTALL = install -SH = /bin/sh -JAVA = java -# see http://code.google.com/p/jnaerator/ -#JNAERATOR = jnaerator-0.9.7.jar -#JNAERATOR = jnaerator-0.9.8-shaded.jar -#JNAERATORARGS = -library miniupnpc -#JNAERATOR = jnaerator-0.10-shaded.jar -#JNAERATOR = jnaerator-0.11-shaded.jar -# https://repo1.maven.org/maven2/com/nativelibs4java/jnaerator/0.12/jnaerator-0.12-shaded.jar -JNAERATOR = jnaerator-0.12-shaded.jar -JNAERATORARGS = -mode StandaloneJar -runtime JNAerator -library miniupnpc -#JNAERATORBASEURL = http://jnaerator.googlecode.com/files/ -JNAERATORBASEURL = https://repo1.maven.org/maven2/com/nativelibs4java/jnaerator/0.12 - -ifeq (SunOS, $(OS)) - LDLIBS=-lsocket -lnsl -lresolv - CFLAGS += -D__EXTENSIONS__ - CFLAGS += -std=c99 -endif - -# APIVERSION is used to build SONAME -APIVERSION = 16 - -SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \ - upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \ - minixmlvalid.c testupnpreplyparse.c minissdpc.c \ - upnperrors.c testigddescparse.c testminiwget.c \ - connecthostport.c portlistingparse.c receivedata.c \ - upnpdev.c testportlistingparse.c miniupnpcmodule.c \ - minihttptestserver.c \ - listdevices.c - -LIBOBJS = miniwget.o minixml.o igd_desc_parse.o minisoap.o \ - miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \ - connecthostport.o portlistingparse.o receivedata.o upnpdev.o - -ifneq ($(OS), AmigaOS) -ifeq (,$(findstring CYGWIN,$(OS))) -CFLAGS := -fPIC $(CFLAGS) -endif -LIBOBJS := $(LIBOBJS) minissdpc.o -endif - -OBJS = $(patsubst %.c,%.o,$(SRCS)) - -# HEADERS to install -HEADERS = miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h \ - upnpreplyparse.h upnperrors.h miniupnpctypes.h \ - portlistingparse.h \ - upnpdev.h \ - miniupnpc_declspec.h - -# library names -LIBRARY = libminiupnpc.a -ifeq ($(OS), Darwin) - SHAREDLIBRARY = libminiupnpc.dylib - SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib - CFLAGS := -D_DARWIN_C_SOURCE $(CFLAGS) -else -ifeq ($(JARSUFFIX), win32) - SHAREDLIBRARY = miniupnpc.dll -else - # Linux/BSD/etc. - SHAREDLIBRARY = libminiupnpc.so - SONAME = $(SHAREDLIBRARY).$(APIVERSION) -endif -endif - -EXECUTABLES = upnpc-static listdevices -EXECUTABLES_ADDTESTS = testminixml minixmlvalid testupnpreplyparse \ - testigddescparse testminiwget testportlistingparse - -TESTMINIXMLOBJS = minixml.o igd_desc_parse.o testminixml.o - -TESTMINIWGETOBJS = miniwget.o testminiwget.o connecthostport.o receivedata.o - -TESTUPNPREPLYPARSE = testupnpreplyparse.o minixml.o upnpreplyparse.o - -TESTPORTLISTINGPARSE = testportlistingparse.o minixml.o portlistingparse.o - -TESTIGDDESCPARSE = testigddescparse.o igd_desc_parse.o minixml.o \ - miniupnpc.o miniwget.o upnpcommands.o upnpreplyparse.o \ - minisoap.o connecthostport.o receivedata.o \ - portlistingparse.o - -ifneq ($(OS), AmigaOS) -EXECUTABLES := $(EXECUTABLES) upnpc-shared -TESTMINIWGETOBJS := $(TESTMINIWGETOBJS) minissdpc.o -TESTIGDDESCPARSE := $(TESTIGDDESCPARSE) minissdpc.o -endif - -LIBDIR ?= lib -# install directories -ifeq ($(strip $(PREFIX)),) -INSTALLPREFIX ?= /usr -else -INSTALLPREFIX ?= $(PREFIX) -endif -INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc -INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR) -INSTALLDIRBIN = $(INSTALLPREFIX)/bin -INSTALLDIRMAN = $(INSTALLPREFIX)/share/man - -FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES) -ifneq ($(OS), AmigaOS) -FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY) -endif - - -.PHONY: install clean depend all check test everything \ - installpythonmodule updateversion -# validateminixml validateminiwget - -all: $(LIBRARY) $(EXECUTABLES) - -test: check - -check: validateminixml validateminiwget validateupnpreplyparse \ - validateportlistingparse validateigddescparse - -everything: all $(EXECUTABLES_ADDTESTS) - -pythonmodule: $(LIBRARY) miniupnpcmodule.c setup.py - MAKE=$(MAKE) python setup.py build - touch $@ - -installpythonmodule: pythonmodule - MAKE=$(MAKE) python setup.py install - -pythonmodule3: $(LIBRARY) miniupnpcmodule.c setup.py - MAKE=$(MAKE) python3 setup.py build - touch $@ - -installpythonmodule3: pythonmodule3 - MAKE=$(MAKE) python3 setup.py install - -validateminixml: minixmlvalid - @echo "minixml validation test" - ./minixmlvalid - touch $@ - -validateminiwget: testminiwget minihttptestserver testminiwget.sh - @echo "miniwget validation test" - ./testminiwget.sh - touch $@ - -validateupnpreplyparse: testupnpreplyparse testupnpreplyparse.sh - @echo "upnpreplyparse validation test" - ./testupnpreplyparse.sh - touch $@ - -validateportlistingparse: testportlistingparse - @echo "portlistingparse validation test" - ./testportlistingparse - touch $@ - -validateigddescparse: testigddescparse - @echo "igd desc parse validation test" - ./testigddescparse testdesc/new_LiveBox_desc.xml testdesc/new_LiveBox_desc.values - ./testigddescparse testdesc/linksys_WAG200G_desc.xml testdesc/linksys_WAG200G_desc.values - touch $@ - -clean: - $(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h - $(RM) $(EXECUTABLES_ADDTESTS) - # clean python stuff - $(RM) pythonmodule pythonmodule3 - $(RM) validateminixml validateminiwget validateupnpreplyparse - $(RM) validateigddescparse - $(RM) minihttptestserver - $(RM) -r build/ dist/ - #python setup.py clean - # clean jnaerator stuff - $(RM) _jnaerator.* java/miniupnpc_$(OS).jar - -distclean: clean - $(RM) $(JNAERATOR) java/*.jar java/*.class out.errors.txt - -updateversion: miniupnpc.h - cp miniupnpc.h miniupnpc.h.bak - sed 's/\(.*MINIUPNPC_API_VERSION\s\+\)[0-9]\+/\1$(APIVERSION)/' < miniupnpc.h.bak > miniupnpc.h - -install: updateversion $(FILESTOINSTALL) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC) - $(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB) - $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB) -ifneq ($(OS), AmigaOS) - $(INSTALL) -m 644 $(SHAREDLIBRARY) $(DESTDIR)$(INSTALLDIRLIB)/$(SONAME) - ln -fs $(SONAME) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY) -endif - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN) -ifeq ($(OS), AmigaOS) - $(INSTALL) -m 755 upnpc-static $(DESTDIR)$(INSTALLDIRBIN)/upnpc -else - $(INSTALL) -m 755 upnpc-shared $(DESTDIR)$(INSTALLDIRBIN)/upnpc -endif - $(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip -ifneq ($(OS), AmigaOS) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRMAN)/man3 - $(INSTALL) -m 644 man3/miniupnpc.3 $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3 -ifeq ($(OS), Linux) - gzip -f $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3 -endif -endif - -install-static: updateversion $(FILESTOINSTALL) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC) - $(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB) - $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB) - $(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN) - $(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip - -cleaninstall: - $(RM) -r $(DESTDIR)$(INSTALLDIRINC) - $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(LIBRARY) - $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY) - -depend: - makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null - -$(LIBRARY): $(LIBOBJS) -ifeq ($(OS), Darwin) - $(LIBTOOL) -static -o $@ $? -else - $(AR) crs $@ $? -endif - -$(SHAREDLIBRARY): $(LIBOBJS) -ifeq ($(OS), Darwin) -# $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^ - $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(INSTALLDIRLIB)/$(SONAME) -o $@ $^ -else - $(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^ -endif - -upnpc-static: upnpc.o $(LIBRARY) - $(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS) - -upnpc-shared: upnpc.o $(SHAREDLIBRARY) - $(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS) - -listdevices: listdevices.o $(LIBRARY) - -testminixml: $(TESTMINIXMLOBJS) - -testminiwget: $(TESTMINIWGETOBJS) - -minixmlvalid: minixml.o minixmlvalid.o - -testupnpreplyparse: $(TESTUPNPREPLYPARSE) - -testigddescparse: $(TESTIGDDESCPARSE) - -testportlistingparse: $(TESTPORTLISTINGPARSE) - -miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION - $(SH) updateminiupnpcstrings.sh - -# ftp tool supplied with OpenBSD can download files from http. -jnaerator-%.jar: - wget $(JNAERATORBASEURL)/$@ || \ - curl -o $@ $(JNAERATORBASEURL)/$@ || \ - ftp $(JNAERATORBASEURL)/$@ - -jar: $(SHAREDLIBRARY) $(JNAERATOR) - $(JAVA) -jar $(JNAERATOR) $(JNAERATORARGS) \ - miniupnpc.h miniupnpc_declspec.h upnpcommands.h upnpreplyparse.h \ - igd_desc_parse.h miniwget.h upnperrors.h $(SHAREDLIBRARY) \ - -package fr.free.miniupnp -o . -jar java/miniupnpc_$(JARSUFFIX).jar -v - -mvn_install: - mvn install:install-file -Dfile=java/miniupnpc_$(JARSUFFIX).jar \ - -DgroupId=com.github \ - -DartifactId=miniupnp \ - -Dversion=$(VERSION) \ - -Dpackaging=jar \ - -Dclassifier=$(JARSUFFIX) \ - -DgeneratePom=true \ - -DcreateChecksum=true - -# make .deb packages -deb: /usr/share/pyshared/stdeb all - (python setup.py --command-packages=stdeb.command bdist_deb) - -# install .deb packages -ideb: - (sudo dpkg -i deb_dist/*.deb) - -/usr/share/pyshared/stdeb: /usr/share/doc/python-all-dev - (sudo apt-get install python-stdeb) - -/usr/share/doc/python-all-dev: - (sudo apt-get install python-all-dev) - -minihttptestserver: minihttptestserver.o - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -igd_desc_parse.o: igd_desc_parse.h -miniupnpc.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h upnpdev.h -miniupnpc.o: minissdpc.h miniwget.h minisoap.h minixml.h upnpcommands.h -miniupnpc.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h -miniupnpc.o: connecthostport.h -minixml.o: minixml.h -minisoap.o: minisoap.h miniupnpcstrings.h -miniwget.o: miniupnpcstrings.h miniwget.h miniupnpc_declspec.h -miniwget.o: connecthostport.h receivedata.h -upnpc.o: miniwget.h miniupnpc_declspec.h miniupnpc.h igd_desc_parse.h -upnpc.o: upnpdev.h upnpcommands.h upnpreplyparse.h portlistingparse.h -upnpc.o: miniupnpctypes.h upnperrors.h miniupnpcstrings.h -upnpcommands.o: upnpcommands.h upnpreplyparse.h portlistingparse.h -upnpcommands.o: miniupnpc_declspec.h miniupnpctypes.h miniupnpc.h -upnpcommands.o: igd_desc_parse.h upnpdev.h -upnpreplyparse.o: upnpreplyparse.h minixml.h -testminixml.o: minixml.h igd_desc_parse.h -minixmlvalid.o: minixml.h -testupnpreplyparse.o: upnpreplyparse.h -minissdpc.o: minissdpc.h miniupnpc_declspec.h upnpdev.h miniupnpc.h -minissdpc.o: igd_desc_parse.h receivedata.h codelength.h -upnperrors.o: upnperrors.h miniupnpc_declspec.h upnpcommands.h -upnperrors.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h -upnperrors.o: miniupnpc.h igd_desc_parse.h upnpdev.h -testigddescparse.o: igd_desc_parse.h minixml.h miniupnpc.h -testigddescparse.o: miniupnpc_declspec.h upnpdev.h -testminiwget.o: miniwget.h miniupnpc_declspec.h -connecthostport.o: connecthostport.h -portlistingparse.o: portlistingparse.h miniupnpc_declspec.h miniupnpctypes.h -portlistingparse.o: minixml.h -receivedata.o: receivedata.h -upnpdev.o: upnpdev.h miniupnpc_declspec.h -testportlistingparse.o: portlistingparse.h miniupnpc_declspec.h -testportlistingparse.o: miniupnpctypes.h -miniupnpcmodule.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h -miniupnpcmodule.o: upnpdev.h upnpcommands.h upnpreplyparse.h -miniupnpcmodule.o: portlistingparse.h miniupnpctypes.h upnperrors.h -listdevices.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h upnpdev.h diff --git a/external/miniupnpc/Makefile.mingw b/external/miniupnpc/Makefile.mingw deleted file mode 100644 index 1b0d44aab..000000000 --- a/external/miniupnpc/Makefile.mingw +++ /dev/null @@ -1,102 +0,0 @@ -# $Id: Makefile.mingw,v 1.21 2015/09/18 12:45:16 nanard Exp $ -# Miniupnp project. -# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ -# (c) 2005-2015 Thomas Bernard -# This Makefile is made for MinGW -# -CC ?= gcc -#CFLAGS = -Wall -g -DDEBUG -D_WIN32_WINNT=0X501 -CFLAGS = -Wall -Os -DNDEBUG -D_WIN32_WINNT=0X501 -LDLIBS = -lws2_32 -liphlpapi -# -lwsock32 -# -liphlpapi is needed for GetBestRoute() and GetIpAddrTable() -PYTHON=\utils\python25\python -OBJS=miniwget.o minixml.o igd_desc_parse.o minisoap.o \ - minissdpc.o \ - miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \ - connecthostport.o portlistingparse.o receivedata.o \ - upnpdev.o -OBJSDLL=$(addprefix dll/, $(OBJS)) - -all: init upnpc-static upnpc-shared testminixml libminiupnpc.a \ - miniupnpc.dll listdevices - -init: - mkdir dll - echo init > init - -clean: - del upnpc testminixml *.o - del dll\*.o - del *.exe - del miniupnpc.dll - del libminiupnpc.a - -libminiupnpc.a: $(OBJS) - $(AR) cr $@ $? - -pythonmodule: libminiupnpc.a - $(PYTHON) setupmingw32.py build --compiler=mingw32 - $(PYTHON) setupmingw32.py install --skip-build - -miniupnpc.dll: libminiupnpc.a $(OBJSDLL) - dllwrap -k --driver-name gcc \ - --def miniupnpc.def \ - --output-def miniupnpc.dll.def \ - --implib miniupnpc.lib -o $@ \ - $(OBJSDLL) $(LDLIBS) - -miniupnpc.lib: miniupnpc.dll -# echo $@ generated with $< - -dll/upnpc.o: upnpc.o -# echo $@ generated with $< - -.c.o: - $(CC) $(CFLAGS) -DMINIUPNP_STATICLIB -c -o $@ $< - $(CC) $(CFLAGS) -DMINIUPNP_EXPORTS -c -o dll/$@ $< - -upnpc.o: upnpc.c - $(CC) $(CFLAGS) -DMINIUPNP_STATICLIB -c -o $@ $< - $(CC) $(CFLAGS) -c -o dll/$@ $< - -# --enable-stdcall-fixup -upnpc-static: upnpc.o libminiupnpc.a - $(CC) -o $@ $^ $(LDLIBS) - -upnpc-shared: dll/upnpc.o miniupnpc.lib - $(CC) -o $@ $^ $(LDLIBS) - -listdevices: listdevices.o libminiupnpc.a - $(CC) -o $@ $^ $(LDLIBS) - -wingenminiupnpcstrings: wingenminiupnpcstrings.o - -wingenminiupnpcstrings.o: wingenminiupnpcstrings.c - -miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings - wingenminiupnpcstrings $< $@ - -minixml.o: minixml.c minixml.h - -upnpc.o: miniwget.h minisoap.h miniupnpc.h igd_desc_parse.h -upnpc.o: upnpreplyparse.h upnpcommands.h upnperrors.h miniupnpcstrings.h - -miniwget.o: miniwget.c miniwget.h miniupnpcstrings.h connecthostport.h - -minisoap.o: minisoap.c minisoap.h miniupnpcstrings.h - -miniupnpc.o: miniupnpc.c miniupnpc.h minisoap.h miniwget.h minixml.h - -igd_desc_parse.o: igd_desc_parse.c igd_desc_parse.h - -testminixml: minixml.o igd_desc_parse.o testminixml.c - -upnpreplyparse.o: upnpreplyparse.c upnpreplyparse.h minixml.h - -upnpcommands.o: upnpcommands.c upnpcommands.h upnpreplyparse.h miniupnpc.h portlistingparse.h - -minissdpc.o: minissdpc.c minissdpc.h receivedata.h - -upnpdev.o: upnpdev.c upnpdev.h - diff --git a/external/miniupnpc/README b/external/miniupnpc/README deleted file mode 100644 index 0d3b8054c..000000000 --- a/external/miniupnpc/README +++ /dev/null @@ -1,63 +0,0 @@ -Project: miniupnp -Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ -github: https://github.com/miniupnp/miniupnp -Author: Thomas Bernard -Copyright (c) 2005-2017 Thomas Bernard -This software is subject to the conditions detailed in the -LICENSE file provided within this distribution. - - -* miniUPnP Client - miniUPnPc * - -To compile, simply run 'gmake' (could be 'make' on your system). -Under win32, to compile with MinGW, type "mingw32make.bat". -MS Visual C solution and project files are supplied in the msvc/ subdirectory. - -The compilation is known to work under linux, FreeBSD, -OpenBSD, MacOS X, AmigaOS and cygwin. -The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3. -upx (http://upx.sourceforge.net) is used to compress the win32 .exe files. - -To install the library and headers on the system use : -> su -> make install -> exit - -alternatively, to install into a specific location, use : -> INSTALLPREFIX=/usr/local make install - -upnpc.c is a sample client using the libminiupnpc. -To use the libminiupnpc in your application, link it with -libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h, -upnpcommands.h and miniwget.h : -- upnpDiscover() -- UPNP_GetValidIGD() -- miniwget() -- parserootdesc() -- GetUPNPUrls() -- UPNP_* (calling UPNP methods) - -Note : use #include <miniupnpc/miniupnpc.h> etc... for the includes -and -lminiupnpc for the link - -Discovery process is speeded up when MiniSSDPd is running on the machine. - - -* Python module * - -you can build a python module with 'make pythonmodule' -and install it with 'make installpythonmodule'. -setup.py (and setupmingw32.py) are included in the distribution. - - -Feel free to contact me if you have any problem : -e-mail : miniupnp@free.fr - -If you are using libminiupnpc in your application, please -send me an email ! - -For any question, you can use the web forum : -https://miniupnp.tuxfamily.org/forum/ - -Bugs should be reported on github : -https://github.com/miniupnp/miniupnp/issues diff --git a/external/miniupnpc/VERSION b/external/miniupnpc/VERSION deleted file mode 100644 index cd5ac039d..000000000 --- a/external/miniupnpc/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.0 diff --git a/external/miniupnpc/apiversions.txt b/external/miniupnpc/apiversions.txt deleted file mode 100644 index 9464a8675..000000000 --- a/external/miniupnpc/apiversions.txt +++ /dev/null @@ -1,172 +0,0 @@ -$Id: apiversions.txt,v 1.9 2016/01/24 17:24:36 nanard Exp $ - -Differences in API between miniUPnPc versions - -API version 16 - added "status_code" argument to getHTTPResponse(), miniwget() and miniwget_getaddr() - updated macro : - #define MINIUPNPC_API_VERSION 16 - -API version 15 - changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() - to "localport". When 0 or 1, behaviour is not changed, but it can take - any other value between 2 and 65535 - Existing programs should be compatible - updated macro : - #define MINIUPNPC_API_VERSION 15 - -API version 14 -miniupnpc.h - add ttl argument to upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() - upnpDiscoverDevices() - getDevicesFromMiniSSDPD() : - connectToMiniSSDPD() / disconnectFromMiniSSDPD() - requestDevicesFromMiniSSDPD() / receiveDevicesFromMiniSSDPD() - updated macro : - #define MINIUPNPC_API_VERSION 14 - -API version 13 -miniupnpc.h: - add searchalltype param to upnpDiscoverDevices() function - updated macro : - #define MINIUPNPC_API_VERSION 13 - -API version 12 -miniupnpc.h : - add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices() - functions - updated macros : - #define MINIUPNPC_API_VERSION 12 - -API version 11 - -upnpreplyparse.h / portlistingparse.h : - removed usage of sys/queue.h / bsdqueue.h - -miniupnpc.h: - updated macros : - #define MINIUPNPC_API_VERSION 11 - -====================== miniUPnPc version 1.9 ====================== -API version 10 - -upnpcommands.h: - added argument remoteHost to UPNP_GetSpecificPortMappingEntry() - -miniupnpc.h: - updated macros : - #define MINIUPNPC_VERSION "1.9" - #define MINIUPNPC_API_VERSION 10 - -====================== miniUPnPc version 1.8 ====================== -API version 9 - -miniupnpc.h: - updated macros : - #define MINIUPNPC_VERSION "1.8" - #define MINIUPNPC_API_VERSION 9 - added "unsigned int scope_id;" to struct UPNPDev - added scope_id argument to GetUPNPUrls() - - - -====================== miniUPnPc version 1.7 ====================== -API version 8 - -miniupnpc.h : - add new macros : - #define MINIUPNPC_VERSION "1.7" - #define MINIUPNPC_API_VERSION 8 - add rootdescURL to struct UPNPUrls - - - -====================== miniUPnPc version 1.6 ====================== -API version 8 - -Adding support for IPv6. -igd_desc_parse.h : - struct IGDdatas_service : - add char presentationurl[MINIUPNPC_URL_MAXSIZE]; - struct IGDdatas : - add struct IGDdatas_service IPv6FC; -miniupnpc.h : - new macros : - #define UPNPDISCOVER_SUCCESS (0) - #define UPNPDISCOVER_UNKNOWN_ERROR (-1) - #define UPNPDISCOVER_SOCKET_ERROR (-101) - #define UPNPDISCOVER_MEMORY_ERROR (-102) - simpleUPnPcommand() prototype changed (but is normaly not used by API users) - add arguments ipv6 and error to upnpDiscover() : - struct UPNPDev * - upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int sameport, - int ipv6, - int * error); - add controlURL_6FC member to struct UPNPUrls : - struct UPNPUrls { - char * controlURL; - char * ipcondescURL; - char * controlURL_CIF; - char * controlURL_6FC; - }; - -upnpcommands.h : - add leaseDuration argument to UPNP_AddPortMapping() - add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry() - add UPNP_GetListOfPortMappings() function (IGDv2) - add IGDv2 IPv6 related functions : - UPNP_GetFirewallStatus() - UPNP_GetOutboundPinholeTimeout() - UPNP_AddPinhole() - UPNP_UpdatePinhole() - UPNP_DeletePinhole() - UPNP_CheckPinholeWorking() - UPNP_GetPinholePackets() - - - -====================== miniUPnPc version 1.5 ====================== -API version 5 - -new function : -int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); -new macro in upnpcommands.h : -#define UPNPCOMMAND_HTTP_ERROR - -====================== miniUPnPc version 1.4 ====================== -Same API as version 1.3 - -====================== miniUPnPc version 1.3 ====================== -API version 4 - -Use UNSIGNED_INTEGER type for -UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(), -UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived() -Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping() - -====================== miniUPnPc version 1.2 ====================== -API version 3 - -added sameport argument to upnpDiscover() -struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int sameport); - -====================== miniUPnPc Version 1.1 ====================== -Same API as 1.0 - - -====================== miniUPnPc Version 1.0 ====================== -API version 2 - - -struct UPNPDev { - struct UPNPDev * pNext; - char * descURL; - char * st; - char buffer[2]; -}; -struct UPNPDev * upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock); - diff --git a/external/miniupnpc/codelength.h b/external/miniupnpc/codelength.h deleted file mode 100644 index ea0b005ff..000000000 --- a/external/miniupnpc/codelength.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $Id: codelength.h,v 1.3 2011/07/30 13:10:05 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef CODELENGTH_H_INCLUDED -#define CODELENGTH_H_INCLUDED - -/* Encode length by using 7bit per Byte : - * Most significant bit of each byte specifies that the - * following byte is part of the code */ - -/* n : unsigned - * p : unsigned char * - */ -#define DECODELENGTH(n, p) n = 0; \ - do { n = (n << 7) | (*p & 0x7f); } \ - while((*(p++)&0x80) && (n<(1<<25))); - -/* n : unsigned - * READ : function/macro to read one byte (unsigned char) - */ -#define DECODELENGTH_READ(n, READ) \ - n = 0; \ - do { \ - unsigned char c; \ - READ(c); \ - n = (n << 7) | (c & 0x07f); \ - if(!(c&0x80)) break; \ - } while(n<(1<<25)); - -/* n : unsigned - * p : unsigned char * - * p_limit : unsigned char * - */ -#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \ - n = 0; \ - do { \ - if((p) >= (p_limit)) break; \ - n = (n << 7) | (*(p) & 0x7f); \ - } while((*((p)++)&0x80) && (n<(1<<25))); - - -/* n : unsigned - * p : unsigned char * - */ -#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ - if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ - if(n>=16384) *(p++) = (n >> 14) | 0x80; \ - if(n>=128) *(p++) = (n >> 7) | 0x80; \ - *(p++) = n & 0x7f; - -#endif /* CODELENGTH_H_INCLUDED */ diff --git a/external/miniupnpc/connecthostport.c b/external/miniupnpc/connecthostport.c deleted file mode 100644 index d28aaf5e0..000000000 --- a/external/miniupnpc/connecthostport.c +++ /dev/null @@ -1,262 +0,0 @@ -/* $Id: connecthostport.c,v 1.15 2015/10/09 16:26:19 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2010-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -/* use getaddrinfo() or gethostbyname() - * uncomment the following line in order to use gethostbyname() */ -#ifdef NO_GETADDRINFO -#define USE_GETHOSTBYNAME -#endif - -#include <string.h> -#include <stdio.h> -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#include <io.h> -#define MAXHOSTNAMELEN 64 -#define snprintf _snprintf -#define herror -#define socklen_t int -#else /* #ifdef _WIN32 */ -#include <unistd.h> -#include <sys/types.h> -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT -#include <sys/time.h> -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ -#include <sys/param.h> -#include <sys/select.h> -#include <errno.h> -#define closesocket close -#include <netdb.h> -#include <netinet/in.h> -/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions - * during the connect() call */ -#define MINIUPNPC_IGNORE_EINTR -#include <sys/socket.h> -#include <sys/select.h> -#endif /* #else _WIN32 */ - -/* definition of PRINT_SOCKET_ERROR */ -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#if defined(__amigaos__) || defined(__amigaos4__) -#define herror(A) printf("%s\n", A) -#endif - -#include "connecthostport.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* connecthostport() - * return a socket connected (TCP) to the host and port - * or -1 in case of error */ -int connecthostport(const char * host, unsigned short port, - unsigned int scope_id) -{ - int s, n; -#ifdef USE_GETHOSTBYNAME - struct sockaddr_in dest; - struct hostent *hp; -#else /* #ifdef USE_GETHOSTBYNAME */ - char tmp_host[MAXHOSTNAMELEN+1]; - char port_str[8]; - struct addrinfo *ai, *p; - struct addrinfo hints; -#endif /* #ifdef USE_GETHOSTBYNAME */ -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - struct timeval timeout; -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - -#ifdef USE_GETHOSTBYNAME - hp = gethostbyname(host); - if(hp == NULL) - { - herror(host); - return -1; - } - memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr)); - memset(dest.sin_zero, 0, sizeof(dest.sin_zero)); - s = socket(PF_INET, SOCK_STREAM, 0); - if(s < 0) - { - PRINT_SOCKET_ERROR("socket"); - return -1; - } -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - dest.sin_family = AF_INET; - dest.sin_port = htons(port); - n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in)); -#ifdef MINIUPNPC_IGNORE_EINTR - /* EINTR The system call was interrupted by a signal that was caught - * EINPROGRESS The socket is nonblocking and the connection cannot - * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) - { - socklen_t len; - fd_set wset; - int err; - FD_ZERO(&wset); - FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) - continue; - /*len = 0;*/ - /*n = getpeername(s, NULL, &len);*/ - len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { - PRINT_SOCKET_ERROR("getsockopt"); - closesocket(s); - return -1; - } - if(err != 0) { - errno = err; - n = -1; - } - } -#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n<0) - { - PRINT_SOCKET_ERROR("connect"); - closesocket(s); - return -1; - } -#else /* #ifdef USE_GETHOSTBYNAME */ - /* use getaddrinfo() instead of gethostbyname() */ - memset(&hints, 0, sizeof(hints)); - /* hints.ai_flags = AI_ADDRCONFIG; */ -#ifdef AI_NUMERICSERV - hints.ai_flags = AI_NUMERICSERV; -#endif - hints.ai_socktype = SOCK_STREAM; - hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ - /* hints.ai_protocol = IPPROTO_TCP; */ - snprintf(port_str, sizeof(port_str), "%hu", port); - if(host[0] == '[') - { - /* literal ip v6 address */ - int i, j; - for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) - { - tmp_host[i] = host[j]; - if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */ - j+=2; /* skip "25" */ - } - tmp_host[i] = '\0'; - } - else - { - strncpy(tmp_host, host, MAXHOSTNAMELEN); - } - tmp_host[MAXHOSTNAMELEN] = '\0'; - n = getaddrinfo(tmp_host, port_str, &hints, &ai); - if(n != 0) - { -#ifdef _WIN32 - fprintf(stderr, "getaddrinfo() error : %d\n", n); -#else - fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n)); -#endif - return -1; - } - s = -1; - for(p = ai; p; p = p->ai_next) - { - s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if(s < 0) - continue; - if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { - struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr; - addr6->sin6_scope_id = scope_id; - } -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT - /* setting a 3 seconds timeout for the connect() call */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - n = connect(s, p->ai_addr, p->ai_addrlen); -#ifdef MINIUPNPC_IGNORE_EINTR - /* EINTR The system call was interrupted by a signal that was caught - * EINPROGRESS The socket is nonblocking and the connection cannot - * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) - { - socklen_t len; - fd_set wset; - int err; - FD_ZERO(&wset); - FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) - continue; - /*len = 0;*/ - /*n = getpeername(s, NULL, &len);*/ - len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { - PRINT_SOCKET_ERROR("getsockopt"); - closesocket(s); - freeaddrinfo(ai); - return -1; - } - if(err != 0) { - errno = err; - n = -1; - } - } -#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n < 0) - { - closesocket(s); - continue; - } - else - { - break; - } - } - freeaddrinfo(ai); - if(s < 0) - { - PRINT_SOCKET_ERROR("socket"); - return -1; - } - if(n < 0) - { - PRINT_SOCKET_ERROR("connect"); - return -1; - } -#endif /* #ifdef USE_GETHOSTBYNAME */ - return s; -} - diff --git a/external/miniupnpc/connecthostport.h b/external/miniupnpc/connecthostport.h deleted file mode 100644 index f3b2d2a84..000000000 --- a/external/miniupnpc/connecthostport.h +++ /dev/null @@ -1,18 +0,0 @@ -/* $Id: connecthostport.h,v 1.2 2012/06/23 22:32:33 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ - * Author: Thomas Bernard - * Copyright (c) 2010-2012 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef CONNECTHOSTPORT_H_INCLUDED -#define CONNECTHOSTPORT_H_INCLUDED - -/* connecthostport() - * return a socket connected (TCP) to the host and port - * or -1 in case of error */ -int connecthostport(const char * host, unsigned short port, - unsigned int scope_id); - -#endif - diff --git a/external/miniupnpc/external-ip.sh b/external/miniupnpc/external-ip.sh deleted file mode 100755 index 965d86b2a..000000000 --- a/external/miniupnpc/external-ip.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# $Id: external-ip.sh,v 1.1 2010/08/05 12:57:41 nanard Exp $ -# (c) 2010 Reuben Hawkins -upnpc -s | grep ExternalIPAddress | sed 's/[^0-9\.]//g' diff --git a/external/miniupnpc/igd_desc_parse.c b/external/miniupnpc/igd_desc_parse.c deleted file mode 100644 index d2999ad01..000000000 --- a/external/miniupnpc/igd_desc_parse.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include "igd_desc_parse.h" -#include <stdio.h> -#include <string.h> - -/* Start element handler : - * update nesting level counter and copy element name */ -void IGDstartelt(void * d, const char * name, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - if(l >= MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; - memcpy(datas->cureltname, name, l); - datas->cureltname[l] = '\0'; - datas->level++; - if( (l==7) && !memcmp(name, "service", l) ) { - datas->tmp.controlurl[0] = '\0'; - datas->tmp.eventsuburl[0] = '\0'; - datas->tmp.scpdurl[0] = '\0'; - datas->tmp.servicetype[0] = '\0'; - } -} - -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -/* End element handler : - * update nesting level counter and update parser state if - * service element is parsed */ -void IGDendelt(void * d, const char * name, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - datas->level--; - /*printf("endelt %2d %.*s\n", datas->level, l, name);*/ - if( (l==7) && !memcmp(name, "service", l) ) - { - if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { - memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { - memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPConnection:") - || COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANPPPConnection:") ) { - if(datas->first.servicetype[0] == '\0') { - memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); - } else { - memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); - } - } - } -} - -/* Data handler : - * copy data depending on the current element name and state */ -void IGDdata(void * d, const char * data, int l) -{ - struct IGDdatas * datas = (struct IGDdatas *)d; - char * dstmember = 0; - /*printf("%2d %s : %.*s\n", - datas->level, datas->cureltname, l, data); */ - if( !strcmp(datas->cureltname, "URLBase") ) - dstmember = datas->urlbase; - else if( !strcmp(datas->cureltname, "presentationURL") ) - dstmember = datas->presentationurl; - else if( !strcmp(datas->cureltname, "serviceType") ) - dstmember = datas->tmp.servicetype; - else if( !strcmp(datas->cureltname, "controlURL") ) - dstmember = datas->tmp.controlurl; - else if( !strcmp(datas->cureltname, "eventSubURL") ) - dstmember = datas->tmp.eventsuburl; - else if( !strcmp(datas->cureltname, "SCPDURL") ) - dstmember = datas->tmp.scpdurl; -/* else if( !strcmp(datas->cureltname, "deviceType") ) - dstmember = datas->devicetype_tmp;*/ - if(dstmember) - { - if(l>=MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; - memcpy(dstmember, data, l); - dstmember[l] = '\0'; - } -} - -#ifdef DEBUG -void printIGD(struct IGDdatas * d) -{ - printf("urlbase = '%s'\n", d->urlbase); - printf("WAN Device (Common interface config) :\n"); - /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/ - printf(" serviceType = '%s'\n", d->CIF.servicetype); - printf(" controlURL = '%s'\n", d->CIF.controlurl); - printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl); - printf(" SCPDURL = '%s'\n", d->CIF.scpdurl); - printf("primary WAN Connection Device (IP or PPP Connection):\n"); - /*printf(" deviceType = '%s'\n", d->first.devicetype);*/ - printf(" servicetype = '%s'\n", d->first.servicetype); - printf(" controlURL = '%s'\n", d->first.controlurl); - printf(" eventSubURL = '%s'\n", d->first.eventsuburl); - printf(" SCPDURL = '%s'\n", d->first.scpdurl); - printf("secondary WAN Connection Device (IP or PPP Connection):\n"); - /*printf(" deviceType = '%s'\n", d->second.devicetype);*/ - printf(" servicetype = '%s'\n", d->second.servicetype); - printf(" controlURL = '%s'\n", d->second.controlurl); - printf(" eventSubURL = '%s'\n", d->second.eventsuburl); - printf(" SCPDURL = '%s'\n", d->second.scpdurl); - printf("WAN IPv6 Firewall Control :\n"); - /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/ - printf(" servicetype = '%s'\n", d->IPv6FC.servicetype); - printf(" controlURL = '%s'\n", d->IPv6FC.controlurl); - printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl); - printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl); -} -#endif /* DEBUG */ - diff --git a/external/miniupnpc/igd_desc_parse.h b/external/miniupnpc/igd_desc_parse.h deleted file mode 100644 index 0de546b69..000000000 --- a/external/miniupnpc/igd_desc_parse.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2014 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef IGD_DESC_PARSE_H_INCLUDED -#define IGD_DESC_PARSE_H_INCLUDED - -/* Structure to store the result of the parsing of UPnP - * descriptions of Internet Gateway Devices */ -#define MINIUPNPC_URL_MAXSIZE (128) -struct IGDdatas_service { - char controlurl[MINIUPNPC_URL_MAXSIZE]; - char eventsuburl[MINIUPNPC_URL_MAXSIZE]; - char scpdurl[MINIUPNPC_URL_MAXSIZE]; - char servicetype[MINIUPNPC_URL_MAXSIZE]; - /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/ -}; - -struct IGDdatas { - char cureltname[MINIUPNPC_URL_MAXSIZE]; - char urlbase[MINIUPNPC_URL_MAXSIZE]; - char presentationurl[MINIUPNPC_URL_MAXSIZE]; - int level; - /*int state;*/ - /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ - struct IGDdatas_service CIF; - /* "urn:schemas-upnp-org:service:WANIPConnection:1" - * "urn:schemas-upnp-org:service:WANPPPConnection:1" */ - struct IGDdatas_service first; - /* if both WANIPConnection and WANPPPConnection are present */ - struct IGDdatas_service second; - /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */ - struct IGDdatas_service IPv6FC; - /* tmp */ - struct IGDdatas_service tmp; -}; - -void IGDstartelt(void *, const char *, int); -void IGDendelt(void *, const char *, int); -void IGDdata(void *, const char *, int); -#ifdef DEBUG -void printIGD(struct IGDdatas *); -#endif /* DEBUG */ - -#endif /* IGD_DESC_PARSE_H_INCLUDED */ diff --git a/external/miniupnpc/java/.gitignore b/external/miniupnpc/java/.gitignore deleted file mode 100644 index 8e9e79486..000000000 --- a/external/miniupnpc/java/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.class -*.jar diff --git a/external/miniupnpc/java/JavaBridgeTest.java b/external/miniupnpc/java/JavaBridgeTest.java deleted file mode 100644 index c658c5990..000000000 --- a/external/miniupnpc/java/JavaBridgeTest.java +++ /dev/null @@ -1,97 +0,0 @@ -import java.nio.ByteBuffer; -import java.nio.IntBuffer; - -import fr.free.miniupnp.*; - -/** - * - * @author syuu - */ -public class JavaBridgeTest { - public static void main(String[] args) { - int UPNP_DELAY = 2000; - MiniupnpcLibrary miniupnpc = MiniupnpcLibrary.INSTANCE; - UPNPDev devlist = null; - UPNPUrls urls = new UPNPUrls(); - IGDdatas data = new IGDdatas(); - ByteBuffer lanaddr = ByteBuffer.allocate(16); - ByteBuffer intClient = ByteBuffer.allocate(16); - ByteBuffer intPort = ByteBuffer.allocate(6); - ByteBuffer desc = ByteBuffer.allocate(80); - ByteBuffer enabled = ByteBuffer.allocate(4); - ByteBuffer leaseDuration = ByteBuffer.allocate(16); - int ret; - int i; - - if(args.length < 2) { - System.err.println("Usage : java [...] JavaBridgeTest port protocol"); - System.out.println(" port is numeric, protocol is TCP or UDP"); - return; - } - - devlist = miniupnpc.upnpDiscover(UPNP_DELAY, (String) null, (String) null, 0, 0, (byte)2, IntBuffer.allocate(1)); - if (devlist != null) { - System.out.println("List of UPNP devices found on the network :"); - for (UPNPDev device = devlist; device != null; device = device.pNext) { - System.out.println("desc: " + device.descURL.getString(0) + " st: " + device.st.getString(0)); - } - if ((i = miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16)) != 0) { - switch (i) { - case 1: - System.out.println("Found valid IGD : " + urls.controlURL.getString(0)); - break; - case 2: - System.out.println("Found a (not connected?) IGD : " + urls.controlURL.getString(0)); - System.out.println("Trying to continue anyway"); - break; - case 3: - System.out.println("UPnP device found. Is it an IGD ? : " + urls.controlURL.getString(0)); - System.out.println("Trying to continue anyway"); - break; - default: - System.out.println("Found device (igd ?) : " + urls.controlURL.getString(0)); - System.out.println("Trying to continue anyway"); - - } - System.out.println("Local LAN ip address : " + new String(lanaddr.array())); - ByteBuffer externalAddress = ByteBuffer.allocate(16); - miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0), - new String(data.first.servicetype), externalAddress); - System.out.println("ExternalIPAddress = " + new String(externalAddress.array())); - ret = miniupnpc.UPNP_AddPortMapping( - urls.controlURL.getString(0), // controlURL - new String(data.first.servicetype), // servicetype - args[0], // external Port - args[0], // internal Port - new String(lanaddr.array()), // internal client - "added via miniupnpc/JAVA !", // description - args[1], // protocol UDP or TCP - null, // remote host (useless) - "0"); // leaseDuration - if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) - System.out.println("AddPortMapping() failed with code " + ret); - ret = miniupnpc.UPNP_GetSpecificPortMappingEntry( - urls.controlURL.getString(0), new String(data.first.servicetype), - args[0], args[1], null, intClient, intPort, - desc, enabled, leaseDuration); - if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) - System.out.println("GetSpecificPortMappingEntry() failed with code " + ret); - System.out.println("InternalIP:Port = " + - new String(intClient.array()) + ":" + new String(intPort.array()) + - " (" + new String(desc.array()) + ")"); - ret = miniupnpc.UPNP_DeletePortMapping( - urls.controlURL.getString(0), - new String(data.first.servicetype), - args[0], args[1], null); - if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS) - System.out.println("DelPortMapping() failed with code " + ret); - miniupnpc.FreeUPNPUrls(urls); - } else { - System.out.println("No valid UPNP Internet Gateway Device found."); - } - miniupnpc.freeUPNPDevlist(devlist); - } else { - System.out.println("No IGD UPnP Device found on the network !\n"); - } - } -} diff --git a/external/miniupnpc/java/testjava.bat b/external/miniupnpc/java/testjava.bat deleted file mode 100755 index b836da149..000000000 --- a/external/miniupnpc/java/testjava.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -set JAVA=java -set JAVAC=javac -REM notice the semicolon for Windows. Write once, run ... oh nevermind -set CP=miniupnpc_win32.jar;. - -%JAVAC% -cp "%CP%" JavaBridgeTest.java || exit 1 -%JAVA% -cp "%CP%" JavaBridgeTest 12345 UDP || exit 1 diff --git a/external/miniupnpc/java/testjava.sh b/external/miniupnpc/java/testjava.sh deleted file mode 100755 index 9880523a1..000000000 --- a/external/miniupnpc/java/testjava.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -JAVA=java -JAVAC=javac -CP=$(for i in *.jar; do echo -n $i:; done). - -$JAVAC -cp $CP JavaBridgeTest.java || exit 1 -$JAVA -cp $CP JavaBridgeTest 12345 UDP || exit 1 diff --git a/external/miniupnpc/listdevices.c b/external/miniupnpc/listdevices.c deleted file mode 100644 index a72fb8b9f..000000000 --- a/external/miniupnpc/listdevices.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $Id: listdevices.c,v 1.6 2015/07/23 20:40:08 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2013-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#ifdef _WIN32 -#include <winsock2.h> -#endif /* _WIN32 */ -#include "miniupnpc.h" - -int main(int argc, char * * argv) -{ - const char * searched_device = NULL; - const char * * searched_devices = NULL; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int ipv6 = 0; - unsigned char ttl = 2; - int error = 0; - struct UPNPDev * devlist = 0; - struct UPNPDev * dev; - int i; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - for(i = 1; i < argc; i++) { - if(strcmp(argv[i], "-6") == 0) - ipv6 = 1; - else if(strcmp(argv[i], "-d") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-d"); - return 1; - } - searched_device = argv[i]; - } else if(strcmp(argv[i], "-t") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-t"); - return 1; - } - ttl = (unsigned char)atoi(argv[i]); - } else if(strcmp(argv[i], "-l") == 0) { - if(++i >= argc) { - fprintf(stderr, "-l option needs at least one argument\n"); - return 1; - } - searched_devices = (const char * *)(argv + i); - break; - } else if(strcmp(argv[i], "-m") == 0) { - if(++i >= argc) { - fprintf(stderr, "-m option needs one argument\n"); - return 1; - } - multicastif = argv[i]; - } else { - printf("usage : %s [options] [-l <device1> <device2> ...]\n", argv[0]); - printf("options :\n"); - printf(" -6 : use IPv6\n"); - printf(" -m address/ifname : network interface to use for multicast\n"); - printf(" -d <device string> : search only for this type of device\n"); - printf(" -l <device1> <device2> ... : search only for theses types of device\n"); - printf(" -t ttl : set multicast TTL. Default value is 2.\n"); - printf(" -h : this help\n"); - return 1; - } - } - - if(searched_device) { - printf("searching UPnP device type %s\n", searched_device); - devlist = upnpDiscoverDevice(searched_device, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } else if(searched_devices) { - printf("searching UPnP device types :\n"); - for(i = 0; searched_devices[i]; i++) - printf("\t%s\n", searched_devices[i]); - devlist = upnpDiscoverDevices(searched_devices, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error, 1); - } else { - printf("searching all UPnP devices\n"); - devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } - if(devlist) { - for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) { - printf("%3d: %-48s\n", i, dev->st); - printf(" %s\n", dev->descURL); - printf(" %s\n", dev->usn); - } - freeUPNPDevlist(devlist); - } else { - printf("no device found.\n"); - } - - return 0; -} - diff --git a/external/miniupnpc/man3/miniupnpc.3 b/external/miniupnpc/man3/miniupnpc.3 deleted file mode 100644 index 7b997d475..000000000 --- a/external/miniupnpc/man3/miniupnpc.3 +++ /dev/null @@ -1,55 +0,0 @@ -.TH MINIUPNPC 3 -.SH NAME -miniupnpc \- UPnP client library -.SH SYNOPSIS -.SH DESCRIPTION -The miniupnpc library implement the UPnP protocol defined -to dialog with Internet Gateway Devices. It also has -the ability to use data gathered by minissdpd(1) about -UPnP devices up on the network in order to skip the -long UPnP device discovery process. -.PP -At first, upnpDiscover(3) has to be used to discover UPnP IGD present -on the network. Then UPNP_GetValidIGD(3) to select the right one. -Alternatively, UPNP_GetIGDFromUrl(3) could be used to bypass discovery -process if the root description url of the device to use is known. -Then all the UPNP_* functions can be used, such as -UPNP_GetConnectionTypeInfo(3), UPNP_AddPortMapping(3), etc... -.SH "HEADER FILES" -.IP miniupnpc.h -That's the main header file for the miniupnpc library API. -It contains all the functions and structures related to device discovery. -.IP upnpcommands.h -This header file contain the UPnP IGD methods that are accessible -through the miniupnpc API. The name of the C functions are matching -the UPnP methods names. ie: GetGenericPortMappingEntry is -UPNP_GetGenericPortMappingEntry. -.SH "API FUNCTIONS" -.IP "struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int localport, int ipv6, int * error);" -execute the discovery process. -delay (in millisecond) is the maximum time for waiting any device response. -If available, device list will be obtained from MiniSSDPd. -Default path for minissdpd socket will be used if minissdpdsock argument is NULL. -If multicastif is not NULL, it will be used instead of the default multicast interface for sending SSDP discover packets. -If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent -from the source port 1900 (same as destination port), if set to -UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will -be attempted as the source port. -If ipv6 is not 0, IPv6 is used instead of IPv4 for the discovery process. -.IP "void freeUPNPDevlist(struct UPNPDev * devlist);" -free the list returned by upnpDiscover(). -.IP "int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);" -browse the list of device returned by upnpDiscover(), find -a live UPnP internet gateway device and fill structures passed as arguments -with data used for UPNP methods invokation. -.IP "int UPNP_GetIGDFromUrl(const char * rootdescurl, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);" -permit to bypass the upnpDiscover() call if the xml root description -URL of the UPnP IGD is known. -Fill structures passed as arguments -with data used for UPNP methods invokation. -.IP "void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);" -.IP "void FreeUPNPUrls(struct UPNPUrls *);" - -.SH "SEE ALSO" -minissdpd(1) -.SH BUGS diff --git a/external/miniupnpc/mingw32make.bat b/external/miniupnpc/mingw32make.bat deleted file mode 100644 index c5d3cc4ff..000000000 --- a/external/miniupnpc/mingw32make.bat +++ /dev/null @@ -1,8 +0,0 @@ -@mingw32-make -f Makefile.mingw %1 -@if errorlevel 1 goto end -@if not exist upnpc-static.exe goto end -@strip upnpc-static.exe -@upx --best upnpc-static.exe -@strip upnpc-shared.exe -@upx --best upnpc-shared.exe -:end diff --git a/external/miniupnpc/minihttptestserver.c b/external/miniupnpc/minihttptestserver.c deleted file mode 100644 index e4cdc203c..000000000 --- a/external/miniupnpc/minihttptestserver.c +++ /dev/null @@ -1,659 +0,0 @@ -/* $Id: minihttptestserver.c,v 1.19 2015/11/17 09:07:17 nanard Exp $ */ -/* Project : miniUPnP - * Author : Thomas Bernard - * Copyright (c) 2011-2016 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <signal.h> -#include <time.h> -#include <errno.h> - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -#define CRAP_LENGTH (2048) - -volatile sig_atomic_t quit = 0; -volatile sig_atomic_t child_to_wait_for = 0; - -/** - * signal handler for SIGCHLD (child status has changed) - */ -void handle_signal_chld(int sig) -{ - (void)sig; - /* printf("handle_signal_chld(%d)\n", sig); */ - ++child_to_wait_for; -} - -/** - * signal handler for SIGINT (CRTL C) - */ -void handle_signal_int(int sig) -{ - (void)sig; - /* printf("handle_signal_int(%d)\n", sig); */ - quit = 1; -} - -/** - * build a text/plain content of the specified length - */ -void build_content(char * p, int n) -{ - char line_buffer[80]; - int k; - int i = 0; - - while(n > 0) { - k = snprintf(line_buffer, sizeof(line_buffer), - "%04d_ABCDEFGHIJKL_This_line_is_64_bytes_long_ABCDEFGHIJKL_%04d\r\n", - i, i); - if(k != 64) { - fprintf(stderr, "snprintf() returned %d in build_content()\n", k); - } - ++i; - if(n >= 64) { - memcpy(p, line_buffer, 64); - p += 64; - n -= 64; - } else { - memcpy(p, line_buffer, n); - p += n; - n = 0; - } - } -} - -/** - * build crappy content - */ -void build_crap(char * p, int n) -{ - static const char crap[] = "_CRAP_\r\n"; - int i; - - while(n > 0) { - i = sizeof(crap) - 1; - if(i > n) - i = n; - memcpy(p, crap, i); - p += i; - n -= i; - } -} - -/** - * build chunked response. - * return a malloc'ed buffer - */ -char * build_chunked_response(int content_length, int * response_len) -{ - char * response_buffer; - char * content_buffer; - int buffer_length; - int i, n; - - /* allocate to have some margin */ - buffer_length = 256 + content_length + (content_length >> 4); - response_buffer = malloc(buffer_length); - if(response_buffer == NULL) - return NULL; - *response_len = snprintf(response_buffer, buffer_length, - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n"); - - /* build the content */ - content_buffer = malloc(content_length); - if(content_buffer == NULL) { - free(response_buffer); - return NULL; - } - build_content(content_buffer, content_length); - - /* chunk it */ - i = 0; - while(i < content_length) { - n = (rand() % 199) + 1; - if(i + n > content_length) { - n = content_length - i; - } - /* TODO : check buffer size ! */ - *response_len += snprintf(response_buffer + *response_len, - buffer_length - *response_len, - "%x\r\n", n); - memcpy(response_buffer + *response_len, content_buffer + i, n); - *response_len += n; - i += n; - response_buffer[(*response_len)++] = '\r'; - response_buffer[(*response_len)++] = '\n'; - } - /* the last chunk : "0\r\n" a empty body and then - * the final "\r\n" */ - memcpy(response_buffer + *response_len, "0\r\n\r\n", 5); - *response_len += 5; - free(content_buffer); - - printf("resp_length=%d buffer_length=%d content_length=%d\n", - *response_len, buffer_length, content_length); - return response_buffer; -} - -/* favicon.ico generator */ -#ifdef OLD_HEADER -#define FAVICON_LENGTH (6 + 16 + 12 + 8 + 32 * 4) -#else -#define FAVICON_LENGTH (6 + 16 + 40 + 8 + 32 * 4) -#endif -void build_favicon_content(char * p, int n) -{ - int i; - if(n < FAVICON_LENGTH) - return; - /* header : 6 bytes */ - *p++ = 0; - *p++ = 0; - *p++ = 1; /* type : ICO */ - *p++ = 0; - *p++ = 1; /* number of images in file */ - *p++ = 0; - /* image directory (1 entry) : 16 bytes */ - *p++ = 16; /* width */ - *p++ = 16; /* height */ - *p++ = 2; /* number of colors in the palette. 0 = no palette */ - *p++ = 0; /* reserved */ - *p++ = 1; /* color planes */ - *p++ = 0; /* " */ - *p++ = 1; /* bpp */ - *p++ = 0; /* " */ -#ifdef OLD_HEADER - *p++ = 12 + 8 + 32 * 4; /* bmp size */ -#else - *p++ = 40 + 8 + 32 * 4; /* bmp size */ -#endif - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 6 + 16; /* bmp offset */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - /* BMP */ -#ifdef OLD_HEADER - /* BITMAPCOREHEADER */ - *p++ = 12; /* size of this header */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 16; /* width */ - *p++ = 0; /* " */ - *p++ = 16 * 2; /* height x 2 ! */ - *p++ = 0; /* " */ - *p++ = 1; /* color planes */ - *p++ = 0; /* " */ - *p++ = 1; /* bpp */ - *p++ = 0; /* " */ -#else - /* BITMAPINFOHEADER */ - *p++ = 40; /* size of this header */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 16; /* width */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 16 * 2; /* height x 2 ! */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 0; /* " */ - *p++ = 1; /* color planes */ - *p++ = 0; /* " */ - *p++ = 1; /* bpp */ - *p++ = 0; /* " */ - /* compression method, image size, ppm x, ppm y */ - /* colors in the palette ? */ - /* important colors */ - for(i = 4 * 6; i > 0; --i) - *p++ = 0; -#endif - /* palette */ - *p++ = 0; /* b */ - *p++ = 0; /* g */ - *p++ = 0; /* r */ - *p++ = 0; /* reserved */ - *p++ = 255; /* b */ - *p++ = 255; /* g */ - *p++ = 255; /* r */ - *p++ = 0; /* reserved */ - /* pixel data */ - for(i = 16; i > 0; --i) { - if(i & 1) { - *p++ = 0125; - *p++ = 0125; - } else { - *p++ = 0252; - *p++ = 0252; - } - *p++ = 0; - *p++ = 0; - } - /* Opacity MASK */ - for(i = 16 * 4; i > 0; --i) { - *p++ = 0; - } -} - -enum modes { - MODE_INVALID, MODE_CHUNKED, MODE_ADDCRAP, MODE_NORMAL, MODE_FAVICON -}; - -const struct { - const enum modes mode; - const char * text; -} modes_array[] = { - {MODE_CHUNKED, "chunked"}, - {MODE_ADDCRAP, "addcrap"}, - {MODE_NORMAL, "normal"}, - {MODE_FAVICON, "favicon.ico"}, - {MODE_INVALID, NULL} -}; - -/** - * write the response with random behaviour ! - */ -void send_response(int c, const char * buffer, int len) -{ - int n; - while(len > 0) { - n = (rand() % 99) + 1; - if(n > len) - n = len; - n = write(c, buffer, n); - if(n < 0) { - if(errno != EINTR) { - perror("write"); - return; - } - /* if errno == EINTR, try again */ - } else { - len -= n; - buffer += n; - } - usleep(10000); /* 10ms */ - } -} - -/** - * handle the HTTP connection - */ -void handle_http_connection(int c) -{ - char request_buffer[2048]; - int request_len = 0; - int headers_found = 0; - int n, i; - char request_method[16]; - char request_uri[256]; - char http_version[16]; - char * p; - char * response_buffer; - int response_len; - enum modes mode; - int content_length = 16*1024; - - /* read the request */ - while(request_len < (int)sizeof(request_buffer) && !headers_found) { - n = read(c, - request_buffer + request_len, - sizeof(request_buffer) - request_len); - if(n < 0) { - if(errno == EINTR) - continue; - perror("read"); - return; - } else if(n==0) { - /* remote host closed the connection */ - break; - } else { - request_len += n; - for(i = 0; i < request_len - 3; i++) { - if(0 == memcmp(request_buffer + i, "\r\n\r\n", 4)) { - /* found the end of headers */ - headers_found = 1; - break; - } - } - } - } - if(!headers_found) { - /* error */ - printf("no HTTP header found in the request\n"); - return; - } - printf("headers :\n%.*s", request_len, request_buffer); - /* the request have been received, now parse the request line */ - p = request_buffer; - for(i = 0; i < (int)sizeof(request_method) - 1; i++) { - if(*p == ' ' || *p == '\r') - break; - request_method[i] = *p; - ++p; - } - request_method[i] = '\0'; - while(*p == ' ') - p++; - for(i = 0; i < (int)sizeof(request_uri) - 1; i++) { - if(*p == ' ' || *p == '\r') - break; - request_uri[i] = *p; - ++p; - } - request_uri[i] = '\0'; - while(*p == ' ') - p++; - for(i = 0; i < (int)sizeof(http_version) - 1; i++) { - if(*p == ' ' || *p == '\r') - break; - http_version[i] = *p; - ++p; - } - http_version[i] = '\0'; - printf("Method = %s, URI = %s, %s\n", - request_method, request_uri, http_version); - /* check if the request method is allowed */ - if(0 != strcmp(request_method, "GET")) { - const char response405[] = "HTTP/1.1 405 Method Not Allowed\r\n" - "Allow: GET\r\n\r\n"; - const char * pc; - /* 405 Method Not Allowed */ - /* The response MUST include an Allow header containing a list - * of valid methods for the requested resource. */ - n = sizeof(response405) - 1; - pc = response405; - while(n > 0) { - i = write(c, pc, n); - if(i<0) { - if(errno != EINTR) { - perror("write"); - return; - } - } else { - n -= i; - pc += i; - } - } - return; - } - - mode = MODE_INVALID; - /* use the request URI to know what to do */ - for(i = 0; modes_array[i].mode != MODE_INVALID; i++) { - if(strstr(request_uri, modes_array[i].text)) { - mode = modes_array[i].mode; /* found */ - break; - } - } - - switch(mode) { - case MODE_CHUNKED: - response_buffer = build_chunked_response(content_length, &response_len); - break; - case MODE_ADDCRAP: - response_len = content_length+256; - response_buffer = malloc(response_len); - if(!response_buffer) - break; - n = snprintf(response_buffer, response_len, - "HTTP/1.1 200 OK\r\n" - "Server: minihttptestserver\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: %d\r\n" - "\r\n", content_length); - response_len = content_length+n+CRAP_LENGTH; - p = realloc(response_buffer, response_len); - if(p == NULL) { - /* error 500 */ - free(response_buffer); - response_buffer = NULL; - break; - } - response_buffer = p; - build_content(response_buffer + n, content_length); - build_crap(response_buffer + n + content_length, CRAP_LENGTH); - break; - case MODE_FAVICON: - content_length = FAVICON_LENGTH; - response_len = content_length + 256; - response_buffer = malloc(response_len); - if(!response_buffer) - break; - n = snprintf(response_buffer, response_len, - "HTTP/1.1 200 OK\r\n" - "Server: minihttptestserver\r\n" - "Content-Type: image/vnd.microsoft.icon\r\n" - "Content-Length: %d\r\n" - "\r\n", content_length); - /* image/x-icon */ - build_favicon_content(response_buffer + n, content_length); - response_len = content_length + n; - break; - default: - response_len = content_length+256; - response_buffer = malloc(response_len); - if(!response_buffer) - break; - n = snprintf(response_buffer, response_len, - "HTTP/1.1 200 OK\r\n" - "Server: minihttptestserver\r\n" - "Content-Type: text/plain\r\n" - "\r\n"); - response_len = content_length+n; - p = realloc(response_buffer, response_len); - if(p == NULL) { - /* Error 500 */ - free(response_buffer); - response_buffer = NULL; - break; - } - response_buffer = p; - build_content(response_buffer + n, response_len - n); - } - - if(response_buffer) { - send_response(c, response_buffer, response_len); - free(response_buffer); - } else { - /* Error 500 */ - } -} - -/** - */ -int main(int argc, char * * argv) { - int ipv6 = 0; - int s, c, i; - unsigned short port = 0; - struct sockaddr_storage server_addr; - socklen_t server_addrlen; - struct sockaddr_storage client_addr; - socklen_t client_addrlen; - pid_t pid; - int child = 0; - int status; - const char * expected_file_name = NULL; - struct sigaction sa; - - for(i = 1; i < argc; i++) { - if(argv[i][0] == '-') { - switch(argv[i][1]) { - case '6': - ipv6 = 1; - break; - case 'e': - /* write expected file ! */ - expected_file_name = argv[++i]; - break; - case 'p': - /* port */ - if(++i < argc) { - port = (unsigned short)atoi(argv[i]); - } - break; - default: - fprintf(stderr, "unknown command line switch '%s'\n", argv[i]); - } - } else { - fprintf(stderr, "unknown command line argument '%s'\n", argv[i]); - } - } - - srand(time(NULL)); - - memset(&sa, 0, sizeof(struct sigaction)); - - /*signal(SIGCHLD, handle_signal_chld);*/ - sa.sa_handler = handle_signal_chld; - if(sigaction(SIGCHLD, &sa, NULL) < 0) { - perror("sigaction"); - return 1; - } - /*signal(SIGINT, handle_signal_int);*/ - sa.sa_handler = handle_signal_int; - if(sigaction(SIGINT, &sa, NULL) < 0) { - perror("sigaction"); - return 1; - } - - s = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0); - if(s < 0) { - perror("socket"); - return 1; - } - memset(&server_addr, 0, sizeof(struct sockaddr_storage)); - memset(&client_addr, 0, sizeof(struct sockaddr_storage)); - if(ipv6) { - struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; - addr->sin6_family = AF_INET6; - addr->sin6_port = htons(port); - addr->sin6_addr = in6addr_loopback; - } else { - struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; - addr->sin_family = AF_INET; - addr->sin_port = htons(port); - addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - } - if(bind(s, (struct sockaddr *)&server_addr, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) < 0) { - perror("bind"); - return 1; - } - if(listen(s, 5) < 0) { - perror("listen"); - } - if(port == 0) { - server_addrlen = sizeof(struct sockaddr_storage); - if(getsockname(s, (struct sockaddr *)&server_addr, &server_addrlen) < 0) { - perror("getsockname"); - return 1; - } - if(ipv6) { - struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; - port = ntohs(addr->sin6_port); - } else { - struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; - port = ntohs(addr->sin_port); - } - printf("Listening on port %hu\n", port); - fflush(stdout); - } - - /* write expected file */ - if(expected_file_name) { - FILE * f; - f = fopen(expected_file_name, "wb"); - if(f) { - char * buffer; - buffer = malloc(16*1024); - if(buffer == NULL) { - fprintf(stderr, "memory allocation error\n"); - } else { - build_content(buffer, 16*1024); - i = fwrite(buffer, 1, 16*1024, f); - if(i != 16*1024) { - fprintf(stderr, "error writing to file %s : %dbytes written (out of %d)\n", expected_file_name, i, 16*1024); - } - free(buffer); - } - fclose(f); - } else { - fprintf(stderr, "error opening file %s for writing\n", expected_file_name); - } - } - - /* fork() loop */ - while(!child && !quit) { - while(child_to_wait_for > 0) { - pid = wait(&status); - if(pid < 0) { - perror("wait"); - } else { - printf("child(%d) terminated with status %d\n", (int)pid, status); - } - --child_to_wait_for; - } - client_addrlen = sizeof(struct sockaddr_storage); - c = accept(s, (struct sockaddr *)&client_addr, - &client_addrlen); - if(c < 0) { - if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - continue; - perror("accept"); - return 1; - } - printf("accept...\n"); - pid = fork(); - if(pid < 0) { - perror("fork"); - return 1; - } else if(pid == 0) { - /* child */ - child = 1; - close(s); - s = -1; - handle_http_connection(c); - } - close(c); - } - if(s >= 0) { - close(s); - s = -1; - } - if(!child) { - while(child_to_wait_for > 0) { - pid = wait(&status); - if(pid < 0) { - perror("wait"); - } else { - printf("child(%d) terminated with status %d\n", (int)pid, status); - } - --child_to_wait_for; - } - printf("Bye...\n"); - } - return 0; -} - diff --git a/external/miniupnpc/minisoap.c b/external/miniupnpc/minisoap.c deleted file mode 100644 index 76225f4b6..000000000 --- a/external/miniupnpc/minisoap.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: minisoap.c,v 1.23 2014/11/04 22:31:55 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * - * Minimal SOAP implementation for UPnP protocol. - */ -#include <stdio.h> -#include <string.h> -#ifdef _WIN32 -#include <io.h> -#include <winsock2.h> -#define snprintf _snprintf -#else -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#endif -#include "minisoap.h" -#include "miniupnpcstrings.h" - -/* only for malloc */ -#include <stdlib.h> - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -/* httpWrite sends the headers and the body to the socket - * and returns the number of bytes sent */ -static int -httpWrite(int fd, const char * body, int bodysize, - const char * headers, int headerssize) -{ - int n = 0; - /*n = write(fd, headers, headerssize);*/ - /*if(bodysize>0) - n += write(fd, body, bodysize);*/ - /* Note : my old linksys router only took into account - * soap request that are sent into only one packet */ - char * p; - /* TODO: AVOID MALLOC, we could use writev() for that */ - p = malloc(headerssize+bodysize); - if(!p) - return -1; - memcpy(p, headers, headerssize); - memcpy(p+headerssize, body, bodysize); - /*n = write(fd, p, headerssize+bodysize);*/ - n = send(fd, p, headerssize+bodysize, 0); - if(n<0) { - PRINT_SOCKET_ERROR("send"); - } - /* disable send on the socket */ - /* draytek routers dont seems to like that... */ -#if 0 -#ifdef _WIN32 - if(shutdown(fd, SD_SEND)<0) { -#else - if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ -#endif - PRINT_SOCKET_ERROR("shutdown"); - } -#endif - free(p); - return n; -} - -/* self explanatory */ -int soapPostSubmit(int fd, - const char * url, - const char * host, - unsigned short port, - const char * action, - const char * body, - const char * httpversion) -{ - int bodysize; - char headerbuf[512]; - int headerssize; - char portstr[8]; - bodysize = (int)strlen(body); - /* We are not using keep-alive HTTP connections. - * HTTP/1.1 needs the header Connection: close to do that. - * This is the default with HTTP/1.0 - * Using HTTP/1.1 means we need to support chunked transfer-encoding : - * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked - * transfer encoding. */ - /* Connection: Close is normally there only in HTTP/1.1 but who knows */ - portstr[0] = '\0'; - if(port != 80) - snprintf(portstr, sizeof(portstr), ":%hu", port); - headerssize = snprintf(headerbuf, sizeof(headerbuf), - "POST %s HTTP/%s\r\n" - "Host: %s%s\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - "Content-Length: %d\r\n" - "Content-Type: text/xml\r\n" - "SOAPAction: \"%s\"\r\n" - "Connection: Close\r\n" - "Cache-Control: no-cache\r\n" /* ??? */ - "Pragma: no-cache\r\n" - "\r\n", - url, httpversion, host, portstr, bodysize, action); - if ((unsigned int)headerssize >= sizeof(headerbuf)) - return -1; -#ifdef DEBUG - /*printf("SOAP request : headersize=%d bodysize=%d\n", - headerssize, bodysize); - */ - printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", - url, httpversion, host, portstr); - printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); - printf("Headers :\n%s", headerbuf); - printf("Body :\n%s\n", body); -#endif - return httpWrite(fd, body, bodysize, headerbuf, headerssize); -} - - diff --git a/external/miniupnpc/minisoap.h b/external/miniupnpc/minisoap.h deleted file mode 100644 index 60554f5c3..000000000 --- a/external/miniupnpc/minisoap.h +++ /dev/null @@ -1,15 +0,0 @@ -/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ -#ifndef MINISOAP_H_INCLUDED -#define MINISOAP_H_INCLUDED - -/*int httpWrite(int, const char *, int, const char *);*/ -int soapPostSubmit(int, const char *, const char *, unsigned short, - const char *, const char *, const char *); - -#endif - diff --git a/external/miniupnpc/minissdpc.c b/external/miniupnpc/minissdpc.c deleted file mode 100644 index 8eee2e927..000000000 --- a/external/miniupnpc/minissdpc.c +++ /dev/null @@ -1,888 +0,0 @@ -/* $Id: minissdpc.c,v 1.32 2016/10/07 09:04:36 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2017 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -/*#include <syslog.h>*/ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#if defined (__NetBSD__) -#include <net/if.h> -#endif -#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#include <io.h> -#include <iphlpapi.h> -#include <winsock.h> -#define snprintf _snprintf -#if !defined(_MSC_VER) -#include <stdint.h> -#else /* !defined(_MSC_VER) */ -typedef unsigned short uint16_t; -#endif /* !defined(_MSC_VER) */ -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#endif /* _WIN32 */ -#if defined(__amigaos__) || defined(__amigaos4__) -#include <sys/socket.h> -#endif /* defined(__amigaos__) || defined(__amigaos4__) */ -#if defined(__amigaos__) -#define uint16_t unsigned short -#endif /* defined(__amigaos__) */ -/* Hack */ -#define UNIX_PATH_LEN 108 -struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; -}; -#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */ -#include <strings.h> -#include <unistd.h> -#include <sys/socket.h> -#include <sys/param.h> -#include <sys/time.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <net/if.h> -#define closesocket close -#endif - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) -#define HAS_IP_MREQN -#endif - -#if !defined(HAS_IP_MREQN) && !defined(_WIN32) -#include <sys/ioctl.h> -#if defined(__sun) -#include <sys/sockio.h> -#endif -#endif - -#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) -/* Several versions of glibc don't define this structure, - * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ -struct ip_mreqn -{ - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_address; /* local IP address of interface */ - int imr_ifindex; /* Interface index */ -}; -#endif - -#if defined(__amigaos__) || defined(__amigaos4__) -/* Amiga OS specific stuff */ -#define TIMEVAL struct timeval -#endif - -#include "minissdpc.h" -#include "miniupnpc.h" -#include "receivedata.h" - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -#include "codelength.h" - -struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) -{ - struct UPNPDev * devlist = NULL; - int s; - int res; - - s = connectToMiniSSDPD(socketpath); - if (s < 0) { - if (error) - *error = s; - return NULL; - } - res = requestDevicesFromMiniSSDPD(s, devtype); - if (res < 0) { - if (error) - *error = res; - } else { - devlist = receiveDevicesFromMiniSSDPD(s, error); - } - disconnectFromMiniSSDPD(s); - return devlist; -} - -/* macros used to read from unix socket */ -#define READ_BYTE_BUFFER(c) \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - c = buffer[bufferindex++]; - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -#define READ_COPY_BUFFER(dst, len) \ - for(l = len, p = (unsigned char *)dst; l > 0; ) { \ - unsigned int lcopy; \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - memcpy(p, buffer + bufferindex, lcopy); \ - l -= lcopy; \ - p += lcopy; \ - bufferindex += lcopy; \ - } - -#define READ_DISCARD_BUFFER(len) \ - for(l = len; l > 0; ) { \ - unsigned int lcopy; \ - if(bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - l -= lcopy; \ - bufferindex += lcopy; \ - } - -int -connectToMiniSSDPD(const char * socketpath) -{ - int s; - struct sockaddr_un addr; -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - struct timeval timeout; -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if(s < 0) - { - /*syslog(LOG_ERR, "socket(unix): %m");*/ - perror("socket(unix)"); - return MINISSDPC_SOCKET_ERROR; - } -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - /* setting a 3 seconds timeout */ - /* not supported for AF_UNIX sockets under Solaris */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_RCVTIMEO unix"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_SNDTIMEO unix"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - if(!socketpath) - socketpath = "/var/run/minissdpd.sock"; - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); - /* TODO : check if we need to handle the EINTR */ - if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) - { - /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ - close(s); - return MINISSDPC_SOCKET_ERROR; - } - return s; -} - -int -disconnectFromMiniSSDPD(int s) -{ - if (close(s) < 0) - return MINISSDPC_SOCKET_ERROR; - return MINISSDPC_SUCCESS; -} - -int -requestDevicesFromMiniSSDPD(int s, const char * devtype) -{ - unsigned char buffer[256]; - unsigned char * p; - unsigned int stsize, l; - - stsize = strlen(devtype); - if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) - { - buffer[0] = 3; /* request type 3 : everything */ - } - else - { - buffer[0] = 1; /* request type 1 : request devices/services by type */ - } - p = buffer + 1; - l = stsize; CODELENGTH(l, p); - if(p + stsize > buffer + sizeof(buffer)) - { - /* devtype is too long ! */ -#ifdef DEBUG - fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n", - stsize, (unsigned)sizeof(buffer)); -#endif /* DEBUG */ - return MINISSDPC_INVALID_INPUT; - } - memcpy(p, devtype, stsize); - p += stsize; - if(write(s, buffer, p - buffer) < 0) - { - /*syslog(LOG_ERR, "write(): %m");*/ - perror("minissdpc.c: write()"); - return MINISSDPC_SOCKET_ERROR; - } - return MINISSDPC_SUCCESS; -} - -struct UPNPDev * -receiveDevicesFromMiniSSDPD(int s, int * error) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = NULL; - unsigned char buffer[256]; - ssize_t n; - unsigned char * p; - unsigned char * url; - unsigned char * st; - unsigned int bufferindex; - unsigned int i, ndev; - unsigned int urlsize, stsize, usnsize, l; - - n = read(s, buffer, sizeof(buffer)); - if(n<=0) - { - perror("minissdpc.c: read()"); - if (error) - *error = MINISSDPC_SOCKET_ERROR; - return NULL; - } - ndev = buffer[0]; - bufferindex = 1; - for(i = 0; i < ndev; i++) - { - DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - return devlist; - } -#ifdef DEBUG - printf(" urlsize=%u", urlsize); -#endif /* DEBUG */ - url = malloc(urlsize); - if(url == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - return devlist; - } - READ_COPY_BUFFER(url, urlsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } - DECODELENGTH_READ(stsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } -#ifdef DEBUG - printf(" stsize=%u", stsize); -#endif /* DEBUG */ - st = malloc(stsize); - if (st == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_return; - } - READ_COPY_BUFFER(st, stsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } - DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } -#ifdef DEBUG - printf(" usnsize=%u\n", usnsize); -#endif /* DEBUG */ - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(tmp == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_st_and_return; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - memcpy(tmp->buffer, url, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - free(url); - free(st); - url = NULL; - st = NULL; - tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize; - READ_COPY_BUFFER(tmp->usn, usnsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_tmp_and_return; - } - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */ - devlist = tmp; - } - if (error) - *error = MINISSDPC_SUCCESS; - return devlist; - -free_url_and_st_and_return: - free(st); -free_url_and_return: - free(url); - return devlist; - -free_tmp_and_return: - free(tmp); - return devlist; -} - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -/* parseMSEARCHReply() - * the last 4 arguments are filled during the parsing : - * - location/locationsize : "location:" field of the SSDP reply packet - * - st/stsize : "st:" field of the SSDP reply packet. - * The strings are NOT null terminated */ -static void -parseMSEARCHReply(const char * reply, int size, - const char * * location, int * locationsize, - const char * * st, int * stsize, - const char * * usn, int * usnsize) -{ - int a, b, i; - i = 0; - a = i; /* start of the line */ - b = 0; /* end of the "header" (position of the colon) */ - while(i<size) - { - switch(reply[i]) - { - case ':': - if(b==0) - { - b = i; /* end of the "header" */ - /*for(j=a; j<b; j++) - { - putchar(reply[j]); - } - */ - } - break; - case '\x0a': - case '\x0d': - if(b!=0) - { - /*for(j=b+1; j<i; j++) - { - putchar(reply[j]); - } - putchar('\n');*/ - /* skip the colon and white spaces */ - do { b++; } while(reply[b]==' '); - if(0==strncasecmp(reply+a, "location", 8)) - { - *location = reply+b; - *locationsize = i-b; - } - else if(0==strncasecmp(reply+a, "st", 2)) - { - *st = reply+b; - *stsize = i-b; - } - else if(0==strncasecmp(reply+a, "usn", 3)) - { - *usn = reply+b; - *usnsize = i-b; - } - b = 0; - } - a = i+1; - break; - default: - break; - } - i++; - } -} - -/* port upnp discover : SSDP protocol */ -#define SSDP_PORT 1900 -#define XSTR(s) STR(s) -#define STR(s) #s -#define UPNP_MCAST_ADDR "239.255.255.250" -/* for IPv6 */ -#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */ -#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */ - -/* direct discovery if minissdpd responses are not sufficient */ -/* ssdpDiscoverDevices() : - * return a chained list of all devices found or NULL if - * no devices was found. - * It is up to the caller to free the chained list - * delay is in millisecond (poll). - * UDA v1.1 says : - * The TTL for the IP packet SHOULD default to 2 and - * SHOULD be configurable. */ -struct UPNPDev * -ssdpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = 0; - unsigned int scope_id = 0; - int opt = 1; - static const char MSearchMsgFmt[] = - "M-SEARCH * HTTP/1.1\r\n" - "HOST: %s:" XSTR(SSDP_PORT) "\r\n" - "ST: %s\r\n" - "MAN: \"ssdp:discover\"\r\n" - "MX: %u\r\n" - "\r\n"; - int deviceIndex; - char bufr[1536]; /* reception and emission buffer */ - int sudp; - int n; - struct sockaddr_storage sockudp_r; - unsigned int mx; -#ifdef NO_GETADDRINFO - struct sockaddr_storage sockudp_w; -#else - int rv; - struct addrinfo hints, *servinfo, *p; -#endif -#ifdef _WIN32 - MIB_IPFORWARDROW ip_forward; - unsigned long _ttl = (unsigned long)ttl; -#endif - int linklocal = 1; - int sentok; - - if(error) - *error = MINISSDPC_UNKNOWN_ERROR; - - if(localport==UPNP_LOCAL_PORT_SAME) - localport = SSDP_PORT; - -#ifdef _WIN32 - sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#else - sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0); -#endif - if(sudp < 0) - { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("socket"); - return NULL; - } - /* reception */ - memset(&sockudp_r, 0, sizeof(struct sockaddr_storage)); - if(ipv6) { - struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r; - p->sin6_family = AF_INET6; - if(localport > 0 && localport < 65536) - p->sin6_port = htons((unsigned short)localport); - p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */ - } else { - struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r; - p->sin_family = AF_INET; - if(localport > 0 && localport < 65536) - p->sin_port = htons((unsigned short)localport); - p->sin_addr.s_addr = INADDR_ANY; - } -#ifdef _WIN32 -/* This code could help us to use the right Network interface for - * SSDP multicast traffic */ -/* Get IP associated with the index given in the ip_forward struct - * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ - if(!ipv6 - && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) { - DWORD dwRetVal = 0; - PMIB_IPADDRTABLE pIPAddrTable; - DWORD dwSize = 0; -#ifdef DEBUG - IN_ADDR IPAddr; -#endif - int i; -#ifdef DEBUG - printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop); -#endif - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE)); - if(pIPAddrTable) { - if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { - free(pIPAddrTable); - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); - } - } - if(pIPAddrTable) { - dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); - if (dwRetVal == NO_ERROR) { -#ifdef DEBUG - printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries); -#endif - for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) { -#ifdef DEBUG - printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; - printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask; - printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); - IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr; - printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); - printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize); - printf("\tType and State[%d]:", i); - printf("\n"); -#endif - if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) { - /* Set the address of this interface to be used */ - struct in_addr mc_if; - memset(&mc_if, 0, sizeof(mc_if)); - mc_if.s_addr = pIPAddrTable->table[i].dwAddr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { - PRINT_SOCKET_ERROR("setsockopt"); - } - ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; -#ifndef DEBUG - break; -#endif - } - } - } - free(pIPAddrTable); - pIPAddrTable = NULL; - } - } -#endif /* _WIN32 */ - -#ifdef _WIN32 - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) -#else - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) -#endif - { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)"); - return NULL; - } - - if(ipv6) { - int mcastHops = ttl; - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastHops, sizeof(mcastHops)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt(IPV6_MULTICAST_HOPS,...)"); - } - } else { -#ifdef _WIN32 - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) -#else /* _WIN32 */ - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) -#endif /* _WIN32 */ - { - /* not a fatal error */ - PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); - } - } - - if(multicastif) - { - if(ipv6) { -#if !defined(_WIN32) - /* according to MSDN, if_nametoindex() is supported since - * MS Windows Vista and MS Windows Server 2008. - * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ - unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); - } -#else -#ifdef DEBUG - printf("Setting of multicast interface not supported in IPv6 under Windows.\n"); -#endif -#endif - } else { - struct in_addr mc_if; - mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ - if(mc_if.s_addr != INADDR_NONE) - { - ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } - } else { -#ifdef HAS_IP_MREQN - /* was not an ip address, try with an interface name */ - struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ - memset(&reqn, 0, sizeof(struct ip_mreqn)); - reqn.imr_ifindex = if_nametoindex(multicastif); - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#elif !defined(_WIN32) - struct ifreq ifr; - int ifrlen = sizeof(ifr); - strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) - { - PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); - } - mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#else /* _WIN32 */ -#ifdef DEBUG - printf("Setting of multicast interface not supported with interface name.\n"); -#endif -#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */ - } - } - } - - /* Before sending the packed, we first "bind" in order to be able - * to receive the response */ - if (bind(sudp, (const struct sockaddr *)&sockudp_r, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) - { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("bind"); - closesocket(sudp); - return NULL; - } - - if(error) - *error = MINISSDPC_SUCCESS; - /* Calculating maximum response time in seconds */ - mx = ((unsigned int)delay) / 1000u; - if(mx == 0) { - mx = 1; - delay = 1000; - } - /* receiving SSDP response packet */ - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - sentok = 0; - /* sending the SSDP M-SEARCH packet */ - n = snprintf(bufr, sizeof(bufr), - MSearchMsgFmt, - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex], mx); - if ((unsigned int)n >= sizeof(bufr)) { - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } -#ifdef DEBUG - /*printf("Sending %s", bufr);*/ - printf("Sending M-SEARCH request to %s with ST: %s\n", - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex]); -#endif -#ifdef NO_GETADDRINFO - /* the following code is not using getaddrinfo */ - /* emission */ - memset(&sockudp_w, 0, sizeof(struct sockaddr_storage)); - if(ipv6) { - struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w; - p->sin6_family = AF_INET6; - p->sin6_port = htons(SSDP_PORT); - inet_pton(AF_INET6, - linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR, - &(p->sin6_addr)); - } else { - struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w; - p->sin_family = AF_INET; - p->sin_port = htons(SSDP_PORT); - p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR); - } - n = sendto(sudp, bufr, n, 0, &sockudp_w, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); - if (n < 0) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("sendto"); - } else { - sentok = 1; - } -#else /* #ifdef NO_GETADDRINFO */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */ - hints.ai_socktype = SOCK_DGRAM; - /*hints.ai_flags = */ - if ((rv = getaddrinfo(ipv6 - ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR) - : UPNP_MCAST_ADDR, - XSTR(SSDP_PORT), &hints, &servinfo)) != 0) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; -#ifdef _WIN32 - fprintf(stderr, "getaddrinfo() failed: %d\n", rv); -#else - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); -#endif - break; - } - for(p = servinfo; p; p = p->ai_next) { - n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); - if (n < 0) { -#ifdef DEBUG - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf, - sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { - fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf); - } -#endif - PRINT_SOCKET_ERROR("sendto"); - continue; - } else { - sentok = 1; - } - } - freeaddrinfo(servinfo); - if(!sentok) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - } -#endif /* #ifdef NO_GETADDRINFO */ - /* Waiting for SSDP REPLY packet to M-SEARCH - * if searchalltypes is set, enter the loop only - * when the last deviceType is reached */ - if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { - n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); - if (n < 0) { - /* error */ - if(error) - *error = MINISSDPC_SOCKET_ERROR; - goto error; - } else if (n == 0) { - /* no data or Time Out */ -#ifdef DEBUG - printf("NODATA or TIMEOUT\n"); -#endif /* DEBUG */ - if (devlist && !searchalltypes) { - /* found some devices, stop now*/ - if(error) - *error = MINISSDPC_SUCCESS; - goto error; - } - } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; - parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { -#ifdef DEBUG - printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); -#endif /* DEBUG */ - for(tmp=devlist; tmp; tmp = tmp->pNext) { - if(memcmp(tmp->descURL, descURL, urlsize) == 0 && - tmp->descURL[urlsize] == '\0' && - memcmp(tmp->st, st, stsize) == 0 && - tmp->st[stsize] == '\0' && - (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\0') - break; - } - /* at the exit of the loop above, tmp is null if - * no duplicate device was found */ - if(tmp) - continue; - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(!tmp) { - /* memory allocation error */ - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - tmp->usn = tmp->st + 1 + stsize; - memcpy(tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) - memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = scope_id; - devlist = tmp; - } - } - } while(n > 0); - if(ipv6) { - /* switch linklocal flag */ - if(linklocal) { - linklocal = 0; - --deviceIndex; - } else { - linklocal = 1; - } - } - } -error: - closesocket(sudp); - return devlist; -} - diff --git a/external/miniupnpc/minissdpc.h b/external/miniupnpc/minissdpc.h deleted file mode 100644 index 167d897cb..000000000 --- a/external/miniupnpc/minissdpc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $Id: minissdpc.h,v 1.6 2015/09/18 12:45:16 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef MINISSDPC_H_INCLUDED -#define MINISSDPC_H_INCLUDED - -#include "miniupnpc_declspec.h" -#include "upnpdev.h" - -/* error codes : */ -#define MINISSDPC_SUCCESS (0) -#define MINISSDPC_UNKNOWN_ERROR (-1) -#define MINISSDPC_SOCKET_ERROR (-101) -#define MINISSDPC_MEMORY_ERROR (-102) -#define MINISSDPC_INVALID_INPUT (-103) -#define MINISSDPC_INVALID_SERVER_REPLY (-104) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -MINIUPNP_LIBSPEC struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); - -MINIUPNP_LIBSPEC int -connectToMiniSSDPD(const char * socketpath); - -MINIUPNP_LIBSPEC int -disconnectFromMiniSSDPD(int fd); - -MINIUPNP_LIBSPEC int -requestDevicesFromMiniSSDPD(int fd, const char * devtype); - -MINIUPNP_LIBSPEC struct UPNPDev * -receiveDevicesFromMiniSSDPD(int fd, int * error); - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -MINIUPNP_LIBSPEC struct UPNPDev * -ssdpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/miniupnpc/miniupnpc.c b/external/miniupnpc/miniupnpc.c deleted file mode 100644 index 5eb9500e3..000000000 --- a/external/miniupnpc/miniupnpc.c +++ /dev/null @@ -1,722 +0,0 @@ -/* $Id: miniupnpc.c,v 1.148 2016/01/24 17:24:36 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifdef _WIN32 -/* Win32 Specific includes and defines */ -#include <winsock2.h> -#include <ws2tcpip.h> -#include <io.h> -#include <iphlpapi.h> -#define snprintf _snprintf -#define strdup _strdup -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#define MAXHOSTNAMELEN 64 -#else /* #ifdef _WIN32 */ -/* Standard POSIX includes */ -#include <unistd.h> -#if defined(__amigaos__) && !defined(__amigaos4__) -/* Amiga OS 3 specific stuff */ -#define socklen_t int -#else -#include <sys/select.h> -#endif -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <net/if.h> -#if !defined(__amigaos__) && !defined(__amigaos4__) -#include <poll.h> -#endif -#include <strings.h> -#include <errno.h> -#define closesocket close -#endif /* #else _WIN32 */ -#ifdef __GNU__ -#define MAXHOSTNAMELEN 64 -#endif - - -#include "miniupnpc.h" -#include "minissdpc.h" -#include "miniwget.h" -#include "minisoap.h" -#include "minixml.h" -#include "upnpcommands.h" -#include "connecthostport.h" - -/* compare the begining of a string with a constant string */ -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#define SOAPPREFIX "s" -#define SERVICEPREFIX "u" -#define SERVICEPREFIX2 'u' - -/* check if an ip address is a private (LAN) address - * see https://tools.ietf.org/html/rfc1918 */ -static int is_rfc1918addr(const char * addr) -{ - /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ - if(COMPARE(addr, "192.168.")) - return 1; - /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ - if(COMPARE(addr, "10.")) - return 1; - /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ - if(COMPARE(addr, "172.")) { - int i = atoi(addr + 4); - if((16 <= i) && (i <= 31)) - return 1; - } - return 0; -} - -/* root description parsing */ -MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) -{ - struct xmlparser parser; - /* xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = IGDstartelt; - parser.endeltfunc = IGDendelt; - parser.datafunc = IGDdata; - parser.attfunc = 0; - parsexml(&parser); -#ifdef DEBUG - printIGD(data); -#endif -} - -/* simpleUPnPcommand2 : - * not so simple ! - * return values : - * pointer - OK - * NULL - error */ -char * simpleUPnPcommand2(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize, const char * httpversion) -{ - char hostname[MAXHOSTNAMELEN+1]; - unsigned short port = 0; - char * path; - char soapact[128]; - char soapbody[2048]; - int soapbodylen; - char * buf; - int n; - int status_code; - - *bufsize = 0; - snprintf(soapact, sizeof(soapact), "%s#%s", service, action); - if(args==NULL) - { - soapbodylen = snprintf(soapbody, sizeof(soapbody), - "<?xml version=\"1.0\"?>\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">" - "</" SERVICEPREFIX ":%s>" - "</" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>" - "\r\n", action, service, action); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - } - else - { - char * p; - const char * pe, * pv; - const char * const pend = soapbody + sizeof(soapbody); - soapbodylen = snprintf(soapbody, sizeof(soapbody), - "<?xml version=\"1.0\"?>\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">", - action, service); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - p = soapbody + soapbodylen; - while(args->elt) - { - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '<'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - if((pv = args->val)) - { - while(p < pend && *pv) - *(p++) = *(pv++); - } - - if((p+2) > pend) /* check for space to write next 2 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - args++; - } - if((p+4) > pend) /* check for space to write next 4 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - *(p++) = SERVICEPREFIX2; - *(p++) = ':'; - - pe = action; - while(p < pend && *pe) - *(p++) = *(pe++); - - strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n", - pend - p); - if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */ - return NULL; - } - if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; - if(s < 0) { - s = connecthostport(hostname, port, 0); - if(s < 0) { - /* failed to connect */ - return NULL; - } - } - - n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); - if(n<=0) { -#ifdef DEBUG - printf("Error sending SOAP request\n"); -#endif - closesocket(s); - return NULL; - } - - buf = getHTTPResponse(s, bufsize, &status_code); -#ifdef DEBUG - if(*bufsize > 0 && buf) - { - printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf); - } - else - { - printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize); - } -#endif - closesocket(s); - return buf; -} - -/* simpleUPnPcommand : - * not so simple ! - * return values : - * pointer - OK - * NULL - error */ -char * simpleUPnPcommand(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize) -{ - char * buf; - -#if 1 - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); -#else - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); - if (!buf || *bufsize == 0) - { -#if DEBUG - printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); -#endif - buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); - } -#endif - return buf; -} - -/* upnpDiscoverDevices() : - * return a chained list of all devices found or NULL if - * no devices was found. - * It is up to the caller to free the chained list - * delay is in millisecond (poll). - * UDA v1.1 says : - * The TTL for the IP packet SHOULD default to 2 and - * SHOULD be configurable. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = 0; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - int deviceIndex; -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - if(error) - *error = UPNPDISCOVER_UNKNOWN_ERROR; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* first try to get infos from minissdpd ! */ - if(!minissdpdsock) - minissdpdsock = "/var/run/minissdpd.sock"; - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - struct UPNPDev * minissdpd_devlist; - int only_rootdevice = 1; - minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex], - minissdpdsock, 0); - if(minissdpd_devlist) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - minissdpd_devlist->st, minissdpd_devlist->descURL); -#endif /* DEBUG */ - if(!strstr(minissdpd_devlist->st, "rootdevice")) - only_rootdevice = 0; - for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - tmp->pNext->st, tmp->pNext->descURL); -#endif /* DEBUG */ - if(!strstr(tmp->st, "rootdevice")) - only_rootdevice = 0; - } - tmp->pNext = devlist; - devlist = minissdpd_devlist; - if(!searchalltypes && !only_rootdevice) - break; - } - } - for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) { - /* We return what we have found if it was not only a rootdevice */ - if(!strstr(tmp->st, "rootdevice")) { - if(error) - *error = UPNPDISCOVER_SUCCESS; - return devlist; - } - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - /* direct discovery if minissdpd responses are not sufficient */ - { - struct UPNPDev * discovered_devlist; - discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport, - ipv6, ttl, error, searchalltypes); - if(devlist == NULL) - devlist = discovered_devlist; - else { - for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); - tmp->pNext = discovered_devlist; - } - } - return devlist; -} - -/* upnpDiscover() Discover IGD device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { -#if 0 - "urn:schemas-upnp-org:device:InternetGatewayDevice:2", - "urn:schemas-upnp-org:service:WANIPConnection:2", -#endif - "urn:schemas-upnp-org:device:InternetGatewayDevice:1", - "urn:schemas-upnp-org:service:WANIPConnection:1", - "urn:schemas-upnp-org:service:WANPPPConnection:1", - "upnp:rootdevice", - /*"ssdp:all",*/ - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverAll() Discover all UPnP devices */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { - /*"upnp:rootdevice",*/ - "ssdp:all", - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverDevice() Discover a specific device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - const char * const deviceList[] = { - device, - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -static char * -build_absolute_url(const char * baseurl, const char * descURL, - const char * url, unsigned int scope_id) -{ - int l, n; - char * s; - const char * base; - char * p; -#if defined(IF_NAMESIZE) && !defined(_WIN32) - char ifname[IF_NAMESIZE]; -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - char scope_str[8]; -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - - if( (url[0] == 'h') - &&(url[1] == 't') - &&(url[2] == 't') - &&(url[3] == 'p') - &&(url[4] == ':') - &&(url[5] == '/') - &&(url[6] == '/')) - return strdup(url); - base = (baseurl[0] == '\0') ? descURL : baseurl; - n = strlen(base); - if(n > 7) { - p = strchr(base + 7, '/'); - if(p) - n = p - base; - } - l = n + strlen(url) + 1; - if(url[0] != '/') - l++; - if(scope_id != 0) { -#if defined(IF_NAMESIZE) && !defined(_WIN32) - if(if_indextoname(scope_id, ifname)) { - l += 3 + strlen(ifname); /* 3 == strlen(%25) */ - } -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - /* under windows, scope is numerical */ - l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - s = malloc(l); - if(s == NULL) return NULL; - memcpy(s, base, n); - if(scope_id != 0) { - s[n] = '\0'; - if(0 == memcmp(s, "http://[fe80:", 13)) { - /* this is a linklocal IPv6 address */ - p = strchr(s, ']'); - if(p) { - /* insert %25<scope> into URL */ -#if defined(IF_NAMESIZE) && !defined(_WIN32) - memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, ifname, strlen(ifname)); - n += 3 + strlen(ifname); -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, scope_str, strlen(scope_str)); - n += 3 + strlen(scope_str); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - } - } - if(url[0] != '/') - s[n++] = '/'; - memcpy(s + n, url, l - n); - return s; -} - -/* Prepare the Urls for usage... - */ -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, - const char * descURL, unsigned int scope_id) -{ - /* strdup descURL */ - urls->rootdescURL = strdup(descURL); - - /* get description of WANIPConnection */ - urls->ipcondescURL = build_absolute_url(data->urlbase, descURL, - data->first.scpdurl, scope_id); - urls->controlURL = build_absolute_url(data->urlbase, descURL, - data->first.controlurl, scope_id); - urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL, - data->CIF.controlurl, scope_id); - urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL, - data->IPv6FC.controlurl, scope_id); - -#ifdef DEBUG - printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL); - printf("urls->controlURL='%s'\n", urls->controlURL); - printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF); - printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC); -#endif -} - -MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls * urls) -{ - if(!urls) - return; - free(urls->controlURL); - urls->controlURL = 0; - free(urls->ipcondescURL); - urls->ipcondescURL = 0; - free(urls->controlURL_CIF); - urls->controlURL_CIF = 0; - free(urls->controlURL_6FC); - urls->controlURL_6FC = 0; - free(urls->rootdescURL); - urls->rootdescURL = 0; -} - -int -UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) -{ - char status[64]; - unsigned int uptime; - status[0] = '\0'; - UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, NULL); - if(0 == strcmp("Connected", status)) - return 1; - else if(0 == strcmp("Up", status)) /* Also accept "Up" */ - return 1; - else - return 0; -} - - -/* UPNP_GetValidIGD() : - * return values : - * -1 = Internal error - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any positive non zero return case, the urls and data structures - * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -MINIUPNP_LIBSPEC int -UPNP_GetValidIGD(struct UPNPDev * devlist, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ - struct xml_desc { - char * xml; - int size; - int is_igd; - } * desc = NULL; - struct UPNPDev * dev; - int ndev = 0; - int i; - int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ - int n_igd = 0; - char extIpAddr[16]; - char myLanAddr[40]; - int status_code = -1; - - if(!devlist) - { -#ifdef DEBUG - printf("Empty devlist\n"); -#endif - return 0; - } - /* counting total number of devices in the list */ - for(dev = devlist; dev; dev = dev->pNext) - ndev++; - if(ndev > 0) - { - desc = calloc(ndev, sizeof(struct xml_desc)); - if(!desc) - return -1; /* memory allocation error */ - } - /* Step 1 : downloading descriptions and testing type */ - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { - /* we should choose an internet gateway device. - * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ - desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), - myLanAddr, sizeof(myLanAddr), - dev->scope_id, &status_code); -#ifdef DEBUG - if(!desc[i].xml) - { - printf("error getting XML description %s\n", dev->descURL); - } -#endif - if(desc[i].xml) - { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(desc[i].xml, desc[i].size, data); - if(COMPARE(data->CIF.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) - { - desc[i].is_igd = 1; - n_igd++; - if(lanaddr) - strncpy(lanaddr, myLanAddr, lanaddrlen); - } - } - } - /* iterate the list to find a device depending on state */ - for(state = 1; state <= 3; state++) - { - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { - if(desc[i].xml) - { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(desc[i].xml, desc[i].size, data); - if(desc[i].is_igd || state >= 3 ) - { - int is_connected; - - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - - /* in state 2 and 3 we dont test if device is connected ! */ - if(state >= 2) - goto free_and_return; - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - /* checks that status is connected AND there is a external IP address assigned */ - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) - goto free_and_return; - } - FreeUPNPUrls(urls); - if(data->second.servicetype[0] != '\0') { -#ifdef DEBUG - printf("We tried %s, now we try %s !\n", - data->first.servicetype, data->second.servicetype); -#endif - /* swaping WANPPPConnection and WANIPConnection ! */ - memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); - memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); - memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) - goto free_and_return; - } - FreeUPNPUrls(urls); - } - } - memset(data, 0, sizeof(struct IGDdatas)); - } - } - } - state = 0; -free_and_return: - if(desc) { - for(i = 0; i < ndev; i++) { - if(desc[i].xml) { - free(desc[i].xml); - } - } - free(desc); - } - return state; -} - -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * return value : - * 0 - Not ok - * 1 - OK */ -int -UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ - char * descXML; - int descXMLsize = 0; - - descXML = miniwget_getaddr(rootdescurl, &descXMLsize, - lanaddr, lanaddrlen, 0, NULL); - if(descXML) { - memset(data, 0, sizeof(struct IGDdatas)); - memset(urls, 0, sizeof(struct UPNPUrls)); - parserootdesc(descXML, descXMLsize, data); - free(descXML); - descXML = NULL; - GetUPNPUrls(urls, data, rootdescurl, 0); - return 1; - } else { - return 0; - } -} - diff --git a/external/miniupnpc/miniupnpc.def b/external/miniupnpc/miniupnpc.def deleted file mode 100644 index 60e0bbe42..000000000 --- a/external/miniupnpc/miniupnpc.def +++ /dev/null @@ -1,45 +0,0 @@ -LIBRARY -; miniupnpc library - miniupnpc - -EXPORTS -; miniupnpc - upnpDiscover - freeUPNPDevlist - parserootdesc - UPNP_GetValidIGD - UPNP_GetIGDFromUrl - GetUPNPUrls - FreeUPNPUrls -; miniwget - miniwget - miniwget_getaddr -; upnpcommands - UPNP_GetTotalBytesSent - UPNP_GetTotalBytesReceived - UPNP_GetTotalPacketsSent - UPNP_GetTotalPacketsReceived - UPNP_GetStatusInfo - UPNP_GetConnectionTypeInfo - UPNP_GetExternalIPAddress - UPNP_GetLinkLayerMaxBitRates - UPNP_AddPortMapping - UPNP_AddAnyPortMapping - UPNP_DeletePortMapping - UPNP_DeletePortMappingRange - UPNP_GetPortMappingNumberOfEntries - UPNP_GetSpecificPortMappingEntry - UPNP_GetGenericPortMappingEntry - UPNP_GetListOfPortMappings - UPNP_AddPinhole - UPNP_CheckPinholeWorking - UPNP_UpdatePinhole - UPNP_GetPinholePackets - UPNP_DeletePinhole - UPNP_GetFirewallStatus - UPNP_GetOutboundPinholeTimeout -; upnperrors - strupnperror -; portlistingparse - ParsePortListing - FreePortListing diff --git a/external/miniupnpc/miniupnpc.h b/external/miniupnpc/miniupnpc.h deleted file mode 100644 index 0b5b47329..000000000 --- a/external/miniupnpc/miniupnpc.h +++ /dev/null @@ -1,152 +0,0 @@ -/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ - * Author: Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef MINIUPNPC_H_INCLUDED -#define MINIUPNPC_H_INCLUDED - -#include "miniupnpc_declspec.h" -#include "igd_desc_parse.h" -#include "upnpdev.h" - -/* error codes : */ -#define UPNPDISCOVER_SUCCESS (0) -#define UPNPDISCOVER_UNKNOWN_ERROR (-1) -#define UPNPDISCOVER_SOCKET_ERROR (-101) -#define UPNPDISCOVER_MEMORY_ERROR (-102) - -/* versions : */ -#define MINIUPNPC_VERSION "2.0" -#define MINIUPNPC_API_VERSION 16 - -/* Source port: - Using "1" as an alias for 1900 for backwards compatability - (presuming one would have used that for the "sameport" parameter) */ -#define UPNP_LOCAL_PORT_ANY 0 -#define UPNP_LOCAL_PORT_SAME 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Structures definitions : */ -struct UPNParg { const char * elt; const char * val; }; - -char * -simpleUPnPcommand(int, const char *, const char *, - const char *, struct UPNParg *, - int *); - -/* upnpDiscover() - * discover UPnP devices on the network. - * The discovered devices are returned as a chained list. - * It is up to the caller to free the list with freeUPNPDevlist(). - * delay (in millisecond) is the maximum time for waiting any device - * response. - * If available, device list will be obtained from MiniSSDPd. - * Default path for minissdpd socket will be used if minissdpdsock argument - * is NULL. - * If multicastif is not NULL, it will be used instead of the default - * multicast interface for sending SSDP discover packets. - * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent - * from the source port 1900 (same as destination port), if set to - * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will - * be attempted as the source port. - * "searchalltypes" parameter is useful when searching several types, - * if 0, the discovery will stop with the first type returning results. - * TTL should default to 2. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); - -/* parserootdesc() : - * parse root XML description of a UPnP device and fill the IGDdatas - * structure. */ -MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *); - -/* structure used to get fast access to urls - * controlURL: controlURL of the WANIPConnection - * ipcondescURL: url of the description of the WANIPConnection - * controlURL_CIF: controlURL of the WANCommonInterfaceConfig - * controlURL_6FC: controlURL of the WANIPv6FirewallControl - */ -struct UPNPUrls { - char * controlURL; - char * ipcondescURL; - char * controlURL_CIF; - char * controlURL_6FC; - char * rootdescURL; -}; - -/* UPNP_GetValidIGD() : - * return values : - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any non zero return case, the urls and data structures - * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -MINIUPNP_LIBSPEC int -UPNP_GetValidIGD(struct UPNPDev * devlist, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); - -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * When succeding, urls, data, and lanaddr arguments are set. - * return value : - * 0 - Not ok - * 1 - OK */ -MINIUPNP_LIBSPEC int -UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); - -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, - const char *, unsigned int); - -MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls *); - -/* return 0 or 1 */ -MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/miniupnpc/miniupnpc_declspec.h b/external/miniupnpc/miniupnpc_declspec.h deleted file mode 100644 index 40adb922e..000000000 --- a/external/miniupnpc/miniupnpc_declspec.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED -#define MINIUPNPC_DECLSPEC_H_INCLUDED - -#if defined(_WIN32) && !defined(MINIUPNP_STATICLIB) - /* for windows dll */ - #ifdef MINIUPNP_EXPORTS - #define MINIUPNP_LIBSPEC __declspec(dllexport) - #else - #define MINIUPNP_LIBSPEC __declspec(dllimport) - #endif -#else - #if defined(__GNUC__) && __GNUC__ >= 4 - /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ - #define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) - #else - #define MINIUPNP_LIBSPEC - #endif -#endif - -#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */ - diff --git a/external/miniupnpc/miniupnpcmodule.c b/external/miniupnpc/miniupnpcmodule.c deleted file mode 100644 index 8ffbf51a1..000000000 --- a/external/miniupnpc/miniupnpcmodule.c +++ /dev/null @@ -1,703 +0,0 @@ -/* $Id: miniupnpcmodule.c,v 1.24 2014/06/10 09:48:11 nanard Exp $*/ -/* Project : miniupnp - * Author : Thomas BERNARD - * website : http://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include <Python.h> -#define MINIUPNP_STATICLIB -#include "structmember.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" - -#ifdef _WIN32 -#include <winsock2.h> -#endif - -/* for compatibility with Python < 2.4 */ -#ifndef Py_RETURN_NONE -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - -#ifndef Py_RETURN_TRUE -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#endif - -#ifndef Py_RETURN_FALSE -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False -#endif - -/* for compatibility with Python < 3.0 */ -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, -#endif - -#ifndef Py_TYPE -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#endif - -typedef struct { - PyObject_HEAD - /* Type-specific fields go here. */ - struct UPNPDev * devlist; - struct UPNPUrls urls; - struct IGDdatas data; - unsigned int discoverdelay; /* value passed to upnpDiscover() */ - unsigned int localport; /* value passed to upnpDiscover() */ - char lanaddr[40]; /* our ip address on the LAN */ - char * multicastif; - char * minissdpdsocket; -} UPnPObject; - -static PyMemberDef UPnP_members[] = { - {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr), - READONLY, "ip address on the LAN" - }, - {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay), - 0/*READWRITE*/, "value in ms used to wait for SSDP responses" - }, - {"localport", T_UINT, offsetof(UPnPObject, localport), - 0/*READWRITE*/, - "If localport is set to UPNP_LOCAL_PORT_SAME(1) " - "SSDP packets will be sent from the source port " - "1900 (same as destination port), if set to " - "UPNP_LOCAL_PORT_ANY(0) system assign a source " - "port, any other value will be attempted as the " - "source port" - }, - /* T_STRING is allways readonly :( */ - {"multicastif", T_STRING, offsetof(UPnPObject, multicastif), - 0, "IP of the network interface to be used for multicast operations" - }, - {"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket), - 0, "path of the MiniSSDPd unix socket" - }, - {NULL} -}; - - -static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds) -{ - char* multicastif = NULL; - char* minissdpdsocket = NULL; - static char *kwlist[] = { - "multicastif", "minissdpdsocket", "discoverdelay", - "localport", NULL - }; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist, - &multicastif, - &minissdpdsocket, - &self->discoverdelay, - &self->localport)) - return -1; - - if(self->localport>1 && - (self->localport>65534||self->localport<1024)) { - PyErr_SetString(PyExc_Exception, "Invalid localport value"); - return -1; - } - if(multicastif) - self->multicastif = strdup(multicastif); - if(minissdpdsocket) - self->minissdpdsocket = strdup(minissdpdsocket); - - return 0; -} - -static void -UPnPObject_dealloc(UPnPObject *self) -{ - freeUPNPDevlist(self->devlist); - FreeUPNPUrls(&self->urls); - free(self->multicastif); - free(self->minissdpdsocket); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject * -UPnP_discover(UPnPObject *self) -{ - struct UPNPDev * dev; - int i; - PyObject *res = NULL; - if(self->devlist) - { - freeUPNPDevlist(self->devlist); - self->devlist = 0; - } - Py_BEGIN_ALLOW_THREADS - self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/, - self->multicastif, - self->minissdpdsocket, - (int)self->localport, - 0/*ip v6*/, - 2/* TTL */, - 0/*error */); - Py_END_ALLOW_THREADS - /* Py_RETURN_NONE ??? */ - for(dev = self->devlist, i = 0; dev; dev = dev->pNext) - i++; - res = Py_BuildValue("i", i); - return res; -} - -static PyObject * -UPnP_selectigd(UPnPObject *self) -{ - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, - self->lanaddr, sizeof(self->lanaddr)); -Py_END_ALLOW_THREADS - if(r) - { - return Py_BuildValue("s", self->urls.controlURL); - } - else - { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, "No UPnP device discovered"); - return NULL; - } -} - -static PyObject * -UPnP_totalbytesent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalbytereceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketsent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketreceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_statusinfo(UPnPObject *self) -{ - char status[64]; - char lastconnerror[64]; - unsigned int uptime = 0; - int r; - status[0] = '\0'; - lastconnerror[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype, - status, &uptime, lastconnerror); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); -#else - return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_connectiontype(UPnPObject *self) -{ - char connectionType[64]; - int r; - connectionType[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetConnectionTypeInfo(self->urls.controlURL, - self->data.first.servicetype, - connectionType); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", connectionType); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_externalipaddress(UPnPObject *self) -{ - char externalIPAddress[40]; - int r; - externalIPAddress[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetExternalIPAddress(self->urls.controlURL, - self->data.first.servicetype, - externalIPAddress); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", externalIPAddress); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, - &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - Py_RETURN_TRUE; - } - else - { - // TODO: RAISE an Exception. See upnpcommands.h for errors codes. - // upnperrors.c - //Py_RETURN_FALSE; - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addanyportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - char reservedPort[6]; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration, reservedPort); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("i", atoi(reservedPort)); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - - -/* DeletePortMapping(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - int r; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, proto, remoteHost); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* DeletePortMappingRange(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args) -{ - char extPortStart[6]; - unsigned short ePortStart; - char extPortEnd[6]; - unsigned short ePortEnd; - const char * proto; - unsigned char manage; - char manageStr[1]; - int r; - if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPortStart, "%hu", ePortStart); - sprintf(extPortEnd, "%hu", ePortEnd); - sprintf(manageStr, "%hhu", manage); - r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype, - extPortStart, extPortEnd, proto, manageStr); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_getportmappingnumberofentries(UPnPObject *self) -{ - unsigned int n = 0; - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL, - self->data.first.servicetype, - &n); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", n); -#else - return Py_BuildValue("i", (int)n); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* GetSpecificPortMapping(ePort, proto, remoteHost='') - * proto = 'UDP' or 'TCP' */ -static PyObject * -UPnP_getspecificportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char desc[80]; - char enabled[4]; - char leaseDuration[16]; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; - extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0'; - desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - UPNP_GetSpecificPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - extPort, proto, remoteHost, - intClient, intPort, - desc, enabled, leaseDuration); -Py_END_ALLOW_THREADS - if(intClient[0]) - { - iPort = (unsigned short)atoi(intPort); - return Py_BuildValue("(s,H,s,O,i)", - intClient, iPort, desc, - PyBool_FromLong(atoi(enabled)), - atoi(leaseDuration)); - } - else - { - Py_RETURN_NONE; - } -} - -/* GetGenericPortMapping(index) */ -static PyObject * -UPnP_getgenericportmapping(UPnPObject *self, PyObject *args) -{ - int i, r; - char index[8]; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char extPort[6]; - unsigned short ePort; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; /* lease duration */ - unsigned int dur; - if(!PyArg_ParseTuple(args, "i", &i)) - return NULL; -Py_BEGIN_ALLOW_THREADS - snprintf(index, sizeof(index), "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, rHost, - duration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - ePort = (unsigned short)atoi(extPort); - iPort = (unsigned short)atoi(intPort); - dur = (unsigned int)strtoul(duration, 0, 0); -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(H,s,(s,H),s,s,s,I)", - ePort, protocol, intClient, iPort, - desc, enabled, rHost, dur); -#else - return Py_BuildValue("(i,s,(s,i),s,s,s,i)", - (int)ePort, protocol, intClient, (int)iPort, - desc, enabled, rHost, (int)dur); -#endif - } - else - { - Py_RETURN_NONE; - } -} - -/* miniupnpc.UPnP object Method Table */ -static PyMethodDef UPnP_methods[] = { - {"discover", (PyCFunction)UPnP_discover, METH_NOARGS, - "discover UPnP IGD devices on the network" - }, - {"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS, - "select a valid UPnP IGD among discovered devices" - }, - {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS, - "return the total number of bytes sent by UPnP IGD" - }, - {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS, - "return the total number of bytes received by UPnP IGD" - }, - {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS, - "return the total number of packets sent by UPnP IGD" - }, - {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS, - "return the total number of packets received by UPnP IGD" - }, - {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS, - "return status and uptime" - }, - {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS, - "return IGD WAN connection type" - }, - {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS, - "return external IP address" - }, - {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS, - "add a port mapping" - }, - {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS, - "add a port mapping, IGD to select alternative if necessary" - }, - {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS, - "delete a range of port mappings" - }, - {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS, - "-- non standard --" - }, - {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS, - "get details about a specific port mapping entry" - }, - {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS, - "get all details about the port mapping at index" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject UPnPType = { - PyVarObject_HEAD_INIT(NULL, - 0) /*ob_size*/ - "miniupnpc.UPnP", /*tp_name*/ - sizeof(UPnPObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)UPnPObject_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - "UPnP objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - UPnP_methods, /* tp_methods */ - UPnP_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)UPnP_init, /* tp_init */ - 0, /* tp_alloc */ -#ifndef _WIN32 - PyType_GenericNew,/*UPnP_new,*/ /* tp_new */ -#else - 0, -#endif -}; - -/* module methods */ -static PyMethodDef miniupnpc_methods[] = { - {NULL} /* Sentinel */ -}; - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "miniupnpc", /* m_name */ - "miniupnpc module.", /* m_doc */ - -1, /* m_size */ - miniupnpc_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; -#endif - -#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif - -PyMODINIT_FUNC -#if PY_MAJOR_VERSION >= 3 -PyInit_miniupnpc(void) -#else -initminiupnpc(void) -#endif -{ - PyObject* m; - -#ifdef _WIN32 - /* initialize Winsock. */ - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - - UPnPType.tp_new = PyType_GenericNew; -#endif - if (PyType_Ready(&UPnPType) < 0) -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("miniupnpc", miniupnpc_methods, - "miniupnpc module."); -#endif - - Py_INCREF(&UPnPType); - PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType); - -#if PY_MAJOR_VERSION >= 3 - return m; -#endif -} - diff --git a/external/miniupnpc/miniupnpcstrings.h.cmake b/external/miniupnpc/miniupnpcstrings.h.cmake deleted file mode 100644 index 78c8fe9c5..000000000 --- a/external/miniupnpc/miniupnpcstrings.h.cmake +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef MINIUPNPCSTRINGS_H_INCLUDED -#define MINIUPNPCSTRINGS_H_INCLUDED - -#define OS_STRING "${CMAKE_SYSTEM_NAME}" -#define MINIUPNPC_VERSION_STRING "${MINIUPNPC_VERSION}" - -#if 0 -/* according to "UPnP Device Architecture 1.0" */ -#define UPNP_VERSION_STRING "UPnP/1.0" -#else -/* according to "UPnP Device Architecture 1.1" */ -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#endif diff --git a/external/miniupnpc/miniupnpcstrings.h.in b/external/miniupnpc/miniupnpcstrings.h.in deleted file mode 100644 index 68bf4293d..000000000 --- a/external/miniupnpc/miniupnpcstrings.h.in +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2014 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef MINIUPNPCSTRINGS_H_INCLUDED -#define MINIUPNPCSTRINGS_H_INCLUDED - -#define OS_STRING "OS/version" -#define MINIUPNPC_VERSION_STRING "version" - -#if 0 -/* according to "UPnP Device Architecture 1.0" */ -#define UPNP_VERSION_STRING "UPnP/1.0" -#else -/* according to "UPnP Device Architecture 1.1" */ -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#endif - diff --git a/external/miniupnpc/miniupnpctypes.h b/external/miniupnpc/miniupnpctypes.h deleted file mode 100644 index 307ce3969..000000000 --- a/external/miniupnpc/miniupnpctypes.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */ -/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org - * Author : Thomas Bernard - * Copyright (c) 2011 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided within this distribution */ -#ifndef MINIUPNPCTYPES_H_INCLUDED -#define MINIUPNPCTYPES_H_INCLUDED - -#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) -#define UNSIGNED_INTEGER unsigned long long -#define STRTOUI strtoull -#else -#define UNSIGNED_INTEGER unsigned int -#define STRTOUI strtoul -#endif - -#endif - diff --git a/external/miniupnpc/miniwget.c b/external/miniupnpc/miniwget.c deleted file mode 100644 index 1eda57c5e..000000000 --- a/external/miniupnpc/miniwget.c +++ /dev/null @@ -1,663 +0,0 @@ -/* $Id: miniwget.c,v 1.75 2016/01/24 17:24:36 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#include <io.h> -#define MAXHOSTNAMELEN 64 -#define snprintf _snprintf -#define socklen_t int -#ifndef strncasecmp -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define strncasecmp _memicmp -#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#define strncasecmp memicmp -#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ -#endif /* #ifndef strncasecmp */ -#else /* #ifdef _WIN32 */ -#include <unistd.h> -#include <sys/param.h> -#if defined(__amigaos__) && !defined(__amigaos4__) -#define socklen_t int -#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ -#include <sys/select.h> -#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <netdb.h> -#define closesocket close -#include <strings.h> -#endif /* #else _WIN32 */ -#ifdef __GNU__ -#define MAXHOSTNAMELEN 64 -#endif /* __GNU__ */ - -#ifndef MIN -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif /* MIN */ - - -#include "miniupnpcstrings.h" -#include "miniwget.h" -#include "connecthostport.h" -#include "receivedata.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* - * Read a HTTP response from a socket. - * Process Content-Length and Transfer-encoding headers. - * return a pointer to the content buffer, which length is saved - * to the length parameter. - */ -void * -getHTTPResponse(int s, int * size, int * status_code) -{ - char buf[2048]; - int n; - int endofheaders = 0; - int chunked = 0; - int content_length = -1; - unsigned int chunksize = 0; - unsigned int bytestocopy = 0; - /* buffers : */ - char * header_buf; - unsigned int header_buf_len = 2048; - unsigned int header_buf_used = 0; - char * content_buf; - unsigned int content_buf_len = 2048; - unsigned int content_buf_used = 0; - char chunksize_buf[32]; - unsigned int chunksize_buf_index; -#ifdef DEBUG - char * reason_phrase = NULL; - int reason_phrase_len = 0; -#endif - - if(status_code) *status_code = -1; - header_buf = malloc(header_buf_len); - if(header_buf == NULL) - { -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - content_buf = malloc(content_buf_len); - if(content_buf == NULL) - { - free(header_buf); -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - - while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0) - { - if(endofheaders == 0) - { - int i; - int linestart=0; - int colon=0; - int valuestart=0; - if(header_buf_used + n > header_buf_len) { - char * tmp = realloc(header_buf, header_buf_used + n); - if(tmp == NULL) { - /* memory allocation error */ - free(header_buf); - free(content_buf); - *size = -1; - return NULL; - } - header_buf = tmp; - header_buf_len = header_buf_used + n; - } - memcpy(header_buf + header_buf_used, buf, n); - header_buf_used += n; - /* search for CR LF CR LF (end of headers) - * recognize also LF LF */ - i = 0; - while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { - if(header_buf[i] == '\r') { - i++; - if(header_buf[i] == '\n') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\r') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\n') { - endofheaders = i+1; - } - } - } - } else if(header_buf[i] == '\n') { - i++; - if(header_buf[i] == '\n') { - endofheaders = i+1; - } - } - i++; - } - if(endofheaders == 0) - continue; - /* parse header lines */ - for(i = 0; i < endofheaders - 1; i++) { - if(linestart > 0 && colon <= linestart && header_buf[i]==':') - { - colon = i; - while(i < (endofheaders-1) - && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t')) - i++; - valuestart = i + 1; - } - /* detecting end of line */ - else if(header_buf[i]=='\r' || header_buf[i]=='\n') - { - if(linestart == 0 && status_code) - { - /* Status line - * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ - int sp; - for(sp = 0; sp < i; sp++) - if(header_buf[sp] == ' ') - { - if(*status_code < 0) - *status_code = atoi(header_buf + sp + 1); - else - { -#ifdef DEBUG - reason_phrase = header_buf + sp + 1; - reason_phrase_len = i - sp - 1; -#endif - break; - } - } -#ifdef DEBUG - printf("HTTP status code = %d, Reason phrase = %.*s\n", - *status_code, reason_phrase_len, reason_phrase); -#endif - } - else if(colon > linestart && valuestart > colon) - { -#ifdef DEBUG - printf("header='%.*s', value='%.*s'\n", - colon-linestart, header_buf+linestart, - i-valuestart, header_buf+valuestart); -#endif - if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart)) - { - content_length = atoi(header_buf+valuestart); -#ifdef DEBUG - printf("Content-Length: %d\n", content_length); -#endif - } - else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart) - && 0==strncasecmp(header_buf+valuestart, "chunked", 7)) - { -#ifdef DEBUG - printf("chunked transfer-encoding!\n"); -#endif - chunked = 1; - } - } - while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) - i++; - linestart = i; - colon = linestart; - valuestart = 0; - } - } - /* copy the remaining of the received data back to buf */ - n = header_buf_used - endofheaders; - memcpy(buf, header_buf + endofheaders, n); - /* if(headers) */ - } - if(endofheaders) - { - /* content */ - if(chunked) - { - int i = 0; - while(i < n) - { - if(chunksize == 0) - { - /* reading chunk size */ - if(chunksize_buf_index == 0) { - /* skipping any leading CR LF */ - if(i<n && buf[i] == '\r') i++; - if(i<n && buf[i] == '\n') i++; - } - while(i<n && isxdigit(buf[i]) - && chunksize_buf_index < (sizeof(chunksize_buf)-1)) - { - chunksize_buf[chunksize_buf_index++] = buf[i]; - chunksize_buf[chunksize_buf_index] = '\0'; - i++; - } - while(i<n && buf[i] != '\r' && buf[i] != '\n') - i++; /* discarding chunk-extension */ - if(i<n && buf[i] == '\r') i++; - if(i<n && buf[i] == '\n') { - unsigned int j; - for(j = 0; j < chunksize_buf_index; j++) { - if(chunksize_buf[j] >= '0' - && chunksize_buf[j] <= '9') - chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); - else - chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - i++; - } else { - /* not finished to get chunksize */ - continue; - } -#ifdef DEBUG - printf("chunksize = %u (%x)\n", chunksize, chunksize); -#endif - if(chunksize == 0) - { -#ifdef DEBUG - printf("end of HTTP content - %d %d\n", i, n); - /*printf("'%.*s'\n", n-i, buf+i);*/ -#endif - goto end_of_stream; - } - } - /* it is guaranteed that (n >= i) */ - bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i); - if((content_buf_used + bytestocopy) > content_buf_len) - { - char * tmp; - if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + bytestocopy; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf + i, bytestocopy); - content_buf_used += bytestocopy; - i += bytestocopy; - chunksize -= bytestocopy; - } - } - else - { - /* not chunked */ - if(content_length > 0 - && (content_buf_used + n) > (unsigned int)content_length) { - /* skipping additional bytes */ - n = content_length - content_buf_used; - } - if(content_buf_used + n > content_buf_len) - { - char * tmp; - if(content_length >= 0 - && (unsigned int)content_length >= (content_buf_used + n)) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + n; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf, n); - content_buf_used += n; - } - } - /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= (unsigned int)content_length) - { -#ifdef DEBUG - printf("End of HTTP content\n"); -#endif - break; - } - } -end_of_stream: - free(header_buf); header_buf = NULL; - *size = content_buf_used; - if(content_buf_used == 0) - { - free(content_buf); - content_buf = NULL; - } - return content_buf; -} - -/* miniwget3() : - * do all the work. - * Return NULL if something failed. */ -static void * -miniwget3(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - const char * httpversion, unsigned int scope_id, - int * status_code) -{ - char buf[2048]; - int s; - int n; - int len; - int sent; - void * content; - - *size = 0; - s = connecthostport(host, port, scope_id); - if(s < 0) - return NULL; - - /* get address for caller ! */ - if(addr_str) - { - struct sockaddr_storage saddr; - socklen_t saddrlen; - - saddrlen = sizeof(saddr); - if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) - { - perror("getsockname"); - } - else - { -#if defined(__amigaos__) && !defined(__amigaos4__) - /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); - * But his function make a string with the port : nn.nn.nn.nn:port */ -/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), - NULL, addr_str, (DWORD *)&addr_str_len)) - { - printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); - }*/ - /* the following code is only compatible with ip v4 addresses */ - strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); -#else -#if 0 - if(saddr.sa_family == AF_INET6) { - inet_ntop(AF_INET6, - &(((struct sockaddr_in6 *)&saddr)->sin6_addr), - addr_str, addr_str_len); - } else { - inet_ntop(AF_INET, - &(((struct sockaddr_in *)&saddr)->sin_addr), - addr_str, addr_str_len); - } -#endif - /* getnameinfo return ip v6 address with the scope identifier - * such as : 2a01:e35:8b2b:7330::%4281128194 */ - n = getnameinfo((const struct sockaddr *)&saddr, saddrlen, - addr_str, addr_str_len, - NULL, 0, - NI_NUMERICHOST | NI_NUMERICSERV); - if(n != 0) { -#ifdef _WIN32 - fprintf(stderr, "getnameinfo() failed : %d\n", n); -#else - fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); -#endif - } -#endif - } -#ifdef DEBUG - printf("address miniwget : %s\n", addr_str); -#endif - } - - len = snprintf(buf, sizeof(buf), - "GET %s HTTP/%s\r\n" - "Host: %s:%d\r\n" - "Connection: Close\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - - "\r\n", - path, httpversion, host, port); - if ((unsigned int)len >= sizeof(buf)) - { - closesocket(s); - return NULL; - } - sent = 0; - /* sending the HTTP request */ - while(sent < len) - { - n = send(s, buf+sent, len-sent, 0); - if(n < 0) - { - perror("send"); - closesocket(s); - return NULL; - } - else - { - sent += n; - } - } - content = getHTTPResponse(s, size, status_code); - closesocket(s); - return content; -} - -/* miniwget2() : - * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ -static void * -miniwget2(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - unsigned int scope_id, int * status_code) -{ - char * respbuffer; - -#if 1 - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); -#else - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.0", - scope_id, status_code); - if (*size == 0) - { -#ifdef DEBUG - printf("Retrying with HTTP/1.1\n"); -#endif - free(respbuffer); - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); - } -#endif - return respbuffer; -} - - - - -/* parseURL() - * arguments : - * url : source string not modified - * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) - * port : port (destination) - * path : pointer to the path part of the URL - * - * Return values : - * 0 - Failure - * 1 - Success */ -int -parseURL(const char * url, - char * hostname, unsigned short * port, - char * * path, unsigned int * scope_id) -{ - char * p1, *p2, *p3; - if(!url) - return 0; - p1 = strstr(url, "://"); - if(!p1) - return 0; - p1 += 3; - if( (url[0]!='h') || (url[1]!='t') - ||(url[2]!='t') || (url[3]!='p')) - return 0; - memset(hostname, 0, MAXHOSTNAMELEN + 1); - if(*p1 == '[') - { - /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ - char * scope; - scope = strchr(p1, '%'); - p2 = strchr(p1, ']'); - if(p2 && scope && scope < p2 && scope_id) { - /* parse scope */ -#ifdef IF_NAMESIZE - char tmp[IF_NAMESIZE]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= IF_NAMESIZE) - l = IF_NAMESIZE - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = if_nametoindex(tmp); - if(*scope_id == 0) { - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); - } -#else - /* under windows, scope is numerical */ - char tmp[8]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= sizeof(tmp)) - l = sizeof(tmp) - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); -#endif - } - p3 = strchr(p1, '/'); - if(p2 && p3) - { - p2++; - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - if(*p2 == ':') - { - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - else - { - *port = 80; - } - *path = p3; - return 1; - } - } - p2 = strchr(p1, ':'); - p3 = strchr(p1, '/'); - if(!p3) - return 0; - if(!p2 || (p2>p3)) - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1))); - *port = 80; - } - else - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - *path = p3; - return 1; -} - -void * -miniwget(const char * url, int * size, - unsigned int scope_id, int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code); -} - -void * -miniwget_getaddr(const char * url, int * size, - char * addr, int addrlen, unsigned int scope_id, - int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/path */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(addr) - addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code); -} - diff --git a/external/miniupnpc/miniwget.h b/external/miniupnpc/miniwget.h deleted file mode 100644 index 0701494d0..000000000 --- a/external/miniupnpc/miniwget.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef MINIWGET_H_INCLUDED -#define MINIWGET_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code); - -MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *); - -MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *); - -int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/miniupnpc/minixml.c b/external/miniupnpc/minixml.c deleted file mode 100644 index 1f2227343..000000000 --- a/external/miniupnpc/minixml.c +++ /dev/null @@ -1,229 +0,0 @@ -/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */ -/* minixml.c : the minimum size a xml parser can be ! */ -/* Project : miniupnp - * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard - -Copyright (c) 2005-2014, Thomas BERNARD -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * 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. - * The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ -#include <string.h> -#include "minixml.h" - -/* parseatt : used to parse the argument list - * return 0 (false) in case of success and -1 (true) if the end - * of the xmlbuffer is reached. */ -static int parseatt(struct xmlparser * p) -{ - const char * attname; - int attnamelen; - const char * attvalue; - int attvaluelen; - while(p->xml < p->xmlend) - { - if(*p->xml=='/' || *p->xml=='>') - return 0; - if( !IS_WHITE_SPACE(*p->xml) ) - { - char sep; - attname = p->xml; - attnamelen = 0; - while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) - { - attnamelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - while(*(p->xml++) != '=') - { - if(p->xml >= p->xmlend) - return -1; - } - while(IS_WHITE_SPACE(*p->xml)) - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - sep = *p->xml; - if(sep=='\'' || sep=='\"') - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - attvalue = p->xml; - attvaluelen = 0; - while(*p->xml != sep) - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - else - { - attvalue = p->xml; - attvaluelen = 0; - while( !IS_WHITE_SPACE(*p->xml) - && *p->xml != '>' && *p->xml != '/') - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - /*printf("%.*s='%.*s'\n", - attnamelen, attname, attvaluelen, attvalue);*/ - if(p->attfunc) - p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); - } - p->xml++; - } - return -1; -} - -/* parseelt parse the xml stream and - * call the callback functions when needed... */ -static void parseelt(struct xmlparser * p) -{ - int i; - const char * elementname; - while(p->xml < (p->xmlend - 1)) - { - if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4))) - { - p->xml += 3; - /* ignore comments */ - do - { - p->xml++; - if ((p->xml + 3) >= p->xmlend) - return; - } - while(memcmp(p->xml, "-->", 3) != 0); - p->xml += 3; - } - else if((p->xml)[0]=='<' && (p->xml)[1]!='?') - { - i = 0; elementname = ++p->xml; - while( !IS_WHITE_SPACE(*p->xml) - && (*p->xml!='>') && (*p->xml!='/') - ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - /* to ignore namespace : */ - if(*p->xml==':') - { - i = 0; - elementname = ++p->xml; - } - } - if(i>0) - { - if(p->starteltfunc) - p->starteltfunc(p->data, elementname, i); - if(parseatt(p)) - return; - if(*p->xml!='/') - { - const char * data; - i = 0; data = ++p->xml; - if (p->xml >= p->xmlend) - return; - while( IS_WHITE_SPACE(*p->xml) ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - if(memcmp(p->xml, "<![CDATA[", 9) == 0) - { - /* CDATA handling */ - p->xml += 9; - data = p->xml; - i = 0; - while(memcmp(p->xml, "]]>", 3) != 0) - { - i++; p->xml++; - if ((p->xml + 3) >= p->xmlend) - return; - } - if(i>0 && p->datafunc) - p->datafunc(p->data, data, i); - while(*p->xml!='<') - { - p->xml++; - if (p->xml >= p->xmlend) - return; - } - } - else - { - while(*p->xml!='<') - { - i++; p->xml++; - if ((p->xml + 1) >= p->xmlend) - return; - } - if(i>0 && p->datafunc && *(p->xml + 1) == '/') - p->datafunc(p->data, data, i); - } - } - } - else if(*p->xml == '/') - { - i = 0; elementname = ++p->xml; - if (p->xml >= p->xmlend) - return; - while((*p->xml != '>')) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - if(p->endeltfunc) - p->endeltfunc(p->data, elementname, i); - p->xml++; - } - } - else - { - p->xml++; - } - } -} - -/* the parser must be initialized before calling this function */ -void parsexml(struct xmlparser * parser) -{ - parser->xml = parser->xmlstart; - parser->xmlend = parser->xmlstart + parser->xmlsize; - parseelt(parser); -} - - diff --git a/external/miniupnpc/minixml.h b/external/miniupnpc/minixml.h deleted file mode 100644 index 19e6f513b..000000000 --- a/external/miniupnpc/minixml.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */ -/* minimal xml parser - * - * Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef MINIXML_H_INCLUDED -#define MINIXML_H_INCLUDED -#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) - -/* if a callback function pointer is set to NULL, - * the function is not called */ -struct xmlparser { - const char *xmlstart; - const char *xmlend; - const char *xml; /* pointer to current character */ - int xmlsize; - void * data; - void (*starteltfunc) (void *, const char *, int); - void (*endeltfunc) (void *, const char *, int); - void (*datafunc) (void *, const char *, int); - void (*attfunc) (void *, const char *, int, const char *, int); -}; - -/* parsexml() - * the xmlparser structure must be initialized before the call - * the following structure members have to be initialized : - * xmlstart, xmlsize, data, *func - * xml is for internal usage, xmlend is computed automatically */ -void parsexml(struct xmlparser *); - -#endif - diff --git a/external/miniupnpc/minixmlvalid.c b/external/miniupnpc/minixmlvalid.c deleted file mode 100644 index dad148812..000000000 --- a/external/miniupnpc/minixmlvalid.c +++ /dev/null @@ -1,163 +0,0 @@ -/* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 nanard Exp $ */ -/* MiniUPnP Project - * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ - * minixmlvalid.c : - * validation program for the minixml parser - * - * (c) 2006-2011 Thomas Bernard */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "minixml.h" - -/* xml event structure */ -struct event { - enum { ELTSTART, ELTEND, ATT, CHARDATA } type; - const char * data; - int len; -}; - -struct eventlist { - int n; - struct event * events; -}; - -/* compare 2 xml event lists - * return 0 if the two lists are equals */ -int evtlistcmp(struct eventlist * a, struct eventlist * b) -{ - int i; - struct event * ae, * be; - if(a->n != b->n) - { - printf("event number not matching : %d != %d\n", a->n, b->n); - /*return 1;*/ - } - for(i=0; i<a->n; i++) - { - ae = a->events + i; - be = b->events + i; - if( (ae->type != be->type) - ||(ae->len != be->len) - ||memcmp(ae->data, be->data, ae->len)) - { - printf("Found a difference : %d '%.*s' != %d '%.*s'\n", - ae->type, ae->len, ae->data, - be->type, be->len, be->data); - return 1; - } - } - return 0; -} - -/* Test data */ -static const char xmldata[] = -"<xmlroot>\n" -" <elt1 att1=\"attvalue1\" att2=\"attvalue2\">" -"character data" -"</elt1> \n \t" -"<elt1b/>" -"<elt1>\n<![CDATA[ <html>stuff !\n ]]> \n</elt1>\n" -"<elt2a> \t<elt2b>chardata1</elt2b><elt2b> chardata2 </elt2b></elt2a>" -"</xmlroot>"; - -static const struct event evtref[] = -{ - {ELTSTART, "xmlroot", 7}, - {ELTSTART, "elt1", 4}, - /* attributes */ - {CHARDATA, "character data", 14}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt1b", 5}, - {ELTSTART, "elt1", 4}, - {CHARDATA, " <html>stuff !\n ", 16}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt2a", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, "chardata1", 9}, - {ELTEND, "elt2b", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, " chardata2 ", 11}, - {ELTEND, "elt2b", 5}, - {ELTEND, "elt2a", 5}, - {ELTEND, "xmlroot", 7} -}; - -void startelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("startelt : %.*s\n", l, p);*/ - evt->type = ELTSTART; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void endelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("endelt : %.*s\n", l, p);*/ - evt->type = ELTEND; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void chardata(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("chardata : '%.*s'\n", l, p);*/ - evt->type = CHARDATA; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -int testxmlparser(const char * xml, int size) -{ - int r; - struct eventlist evtlist; - struct eventlist evtlistref; - struct xmlparser parser; - evtlist.n = 0; - evtlist.events = malloc(sizeof(struct event)*100); - if(evtlist.events == NULL) - { - fprintf(stderr, "Memory allocation error.\n"); - return -1; - } - memset(&parser, 0, sizeof(parser)); - parser.xmlstart = xml; - parser.xmlsize = size; - parser.data = &evtlist; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = chardata; - parsexml(&parser); - printf("%d events\n", evtlist.n); - /* compare */ - evtlistref.n = sizeof(evtref)/sizeof(struct event); - evtlistref.events = (struct event *)evtref; - r = evtlistcmp(&evtlistref, &evtlist); - free(evtlist.events); - return r; -} - -int main(int argc, char * * argv) -{ - int r; - (void)argc; (void)argv; - - r = testxmlparser(xmldata, sizeof(xmldata)-1); - if(r) - printf("minixml validation test failed\n"); - return r; -} - diff --git a/external/miniupnpc/msvc/.gitignore b/external/miniupnpc/msvc/.gitignore deleted file mode 100644 index 6d88bf128..000000000 --- a/external/miniupnpc/msvc/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.db -.vs -Debug/ -Release/ diff --git a/external/miniupnpc/msvc/miniupnpc.sln b/external/miniupnpc/msvc/miniupnpc.sln deleted file mode 100644 index b3da1919e..000000000 --- a/external/miniupnpc/msvc/miniupnpc.sln +++ /dev/null @@ -1,29 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "miniupnpc.vcproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upnpc-static", "upnpc-static.vcproj", "{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}" - ProjectSection(ProjectDependencies) = postProject - {D28CE435-CB33-4BAE-8A52-C6EF915956F5} = {D28CE435-CB33-4BAE-8A52-C6EF915956F5} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.ActiveCfg = Debug|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.Build.0 = Debug|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.ActiveCfg = Release|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.Build.0 = Release|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.ActiveCfg = Debug|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.Build.0 = Debug|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.ActiveCfg = Release|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/external/miniupnpc/msvc/miniupnpc.vcproj b/external/miniupnpc/msvc/miniupnpc.vcproj deleted file mode 100644 index fb301e3b8..000000000 --- a/external/miniupnpc/msvc/miniupnpc.vcproj +++ /dev/null @@ -1,283 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9,00" - Name="miniupnpc" - ProjectGUID="{D28CE435-CB33-4BAE-8A52-C6EF915956F5}" - RootNamespace="miniupnpc" - Keyword="Win32Proj" - TargetFrameworkVersion="196613" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="4" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;DEBUG" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="4" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLibrarianTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="4" - CharacterSet="1" - WholeProgramOptimization="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - EnableIntrinsicFunctions="true" - PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB" - RuntimeLibrary="2" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLibrarianTool" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Fichiers sources" - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath="..\connecthostport.c" - > - </File> - <File - RelativePath="..\igd_desc_parse.c" - > - </File> - <File - RelativePath="..\minisoap.c" - > - </File> - <File - RelativePath="..\minissdpc.c" - > - </File> - <File - RelativePath="..\miniupnpc.c" - > - </File> - <File - RelativePath="..\miniwget.c" - > - </File> - <File - RelativePath="..\minixml.c" - > - </File> - <File - RelativePath="..\portlistingparse.c" - > - </File> - <File - RelativePath="..\receivedata.c" - > - </File> - <File - RelativePath="..\upnpcommands.c" - > - </File> - <File - RelativePath="..\upnpdev.c" - > - </File> - <File - RelativePath="..\upnperrors.c" - > - </File> - <File - RelativePath="..\upnpreplyparse.c" - > - </File> - </Filter> - <Filter - Name="Fichiers d'en-tête" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath="..\connecthostport.h" - > - </File> - <File - RelativePath="..\declspec.h" - > - </File> - <File - RelativePath="..\igd_desc_parse.h" - > - </File> - <File - RelativePath="..\minisoap.h" - > - </File> - <File - RelativePath="..\minissdpc.h" - > - </File> - <File - RelativePath="..\miniupnpc.h" - > - </File> - <File - RelativePath="..\miniupnpcstrings.h" - > - </File> - <File - RelativePath="..\miniupnpctypes.h" - > - </File> - <File - RelativePath="..\miniwget.h" - > - </File> - <File - RelativePath="..\minixml.h" - > - </File> - <File - RelativePath="..\portlistingparse.h" - > - </File> - <File - RelativePath="..\receivedata.h" - > - </File> - <File - RelativePath="..\upnpcommands.h" - > - </File> - <File - RelativePath="..\upnpdev.h" - > - </File> - <File - RelativePath="..\upnperrors.h" - > - </File> - <File - RelativePath="..\upnpreplyparse.h" - > - </File> - </Filter> - <Filter - Name="Fichiers de ressources" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" - > - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/external/miniupnpc/msvc/miniupnpc.vcxproj b/external/miniupnpc/msvc/miniupnpc.vcxproj deleted file mode 100644 index 2725136e3..000000000 --- a/external/miniupnpc/msvc/miniupnpc.vcxproj +++ /dev/null @@ -1,111 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{D28CE435-CB33-4BAE-8A52-C6EF915956F5}</ProjectGuid> - <RootNamespace>miniupnpc</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <OutDir>$(SolutionDir)$(Configuration)\</OutDir> - <IntDir>$(Configuration)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)$(Configuration)\</OutDir> - <IntDir>$(Configuration)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader /> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader /> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\connecthostport.c" /> - <ClCompile Include="..\igd_desc_parse.c" /> - <ClCompile Include="..\minisoap.c" /> - <ClCompile Include="..\minissdpc.c" /> - <ClCompile Include="..\miniupnpc.c" /> - <ClCompile Include="..\miniwget.c" /> - <ClCompile Include="..\minixml.c" /> - <ClCompile Include="..\portlistingparse.c" /> - <ClCompile Include="..\receivedata.c" /> - <ClCompile Include="..\upnpcommands.c" /> - <ClCompile Include="..\upnpdev.c" /> - <ClCompile Include="..\upnperrors.c" /> - <ClCompile Include="..\upnpreplyparse.c" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\connecthostport.h" /> - <ClInclude Include="..\declspec.h" /> - <ClInclude Include="..\igd_desc_parse.h" /> - <ClInclude Include="..\minisoap.h" /> - <ClInclude Include="..\minissdpc.h" /> - <ClInclude Include="..\miniupnpc.h" /> - <ClInclude Include="..\miniupnpcstrings.h" /> - <ClInclude Include="..\miniupnpctypes.h" /> - <ClInclude Include="..\miniwget.h" /> - <ClInclude Include="..\minixml.h" /> - <ClInclude Include="..\portlistingparse.h" /> - <ClInclude Include="..\receivedata.h" /> - <ClInclude Include="..\upnpcommands.h" /> - <ClInclude Include="..\upnpdev.h" /> - <ClInclude Include="..\upnperrors.h" /> - <ClInclude Include="..\upnpreplyparse.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/miniupnpc.vcxproj.filters b/external/miniupnpc/msvc/miniupnpc.vcxproj.filters deleted file mode 100644 index 01a4dbeb2..000000000 --- a/external/miniupnpc/msvc/miniupnpc.vcxproj.filters +++ /dev/null @@ -1,108 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Fichiers sources"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Fichiers d%27en-tête"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Fichiers de ressources"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\connecthostport.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\igd_desc_parse.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\minisoap.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\minissdpc.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\miniupnpc.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\miniwget.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\minixml.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\portlistingparse.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\receivedata.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\upnpcommands.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\upnpdev.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\upnperrors.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - <ClCompile Include="..\upnpreplyparse.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\connecthostport.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\declspec.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\igd_desc_parse.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\minisoap.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\minissdpc.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\miniupnpc.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\miniupnpcstrings.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\miniupnpctypes.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\miniwget.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\minixml.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\portlistingparse.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\receivedata.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\upnpcommands.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\upnpdev.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\upnperrors.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - <ClInclude Include="..\upnpreplyparse.h"> - <Filter>Fichiers d%27en-tête</Filter> - </ClInclude> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/miniupnpc_vs2015.sln b/external/miniupnpc/msvc/miniupnpc_vs2015.sln deleted file mode 100644 index 27a43f6c3..000000000 --- a/external/miniupnpc/msvc/miniupnpc_vs2015.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "miniupnpc.vcxproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upnpc-static", "upnpc-static.vcxproj", "{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.ActiveCfg = Debug|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.Build.0 = Debug|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.ActiveCfg = Release|Win32 - {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.Build.0 = Release|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.ActiveCfg = Debug|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.Build.0 = Debug|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.ActiveCfg = Release|Win32 - {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/external/miniupnpc/msvc/upnpc-static.vcproj b/external/miniupnpc/msvc/upnpc-static.vcproj deleted file mode 100644 index c88c9a6e9..000000000 --- a/external/miniupnpc/msvc/upnpc-static.vcproj +++ /dev/null @@ -1,195 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9,00" - Name="upnpc-static" - ProjectGUID="{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}" - RootNamespace="upnpcstatic" - Keyword="Win32Proj" - TargetFrameworkVersion="196613" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="1" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="_DEBUG;_CONSOLE;MINIUPNP_STATICLIB;DEBUG;_CRT_SECURE_NO_WARNINGS" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="4" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Debug\miniupnpc.lib" - LinkIncremental="2" - GenerateDebugInformation="true" - SubSystem="1" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" - ConfigurationType="1" - CharacterSet="1" - WholeProgramOptimization="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - EnableIntrinsicFunctions="true" - PreprocessorDefinitions="NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB" - RuntimeLibrary="2" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="ws2_32.lib IPHlpApi.Lib Release\miniupnpc.lib" - LinkIncremental="1" - GenerateDebugInformation="true" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Fichiers sources" - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath="..\upnpc.c" - > - </File> - </Filter> - <Filter - Name="Fichiers d'en-tête" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - </Filter> - <Filter - Name="Fichiers de ressources" - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" - > - </Filter> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/external/miniupnpc/msvc/upnpc-static.vcxproj b/external/miniupnpc/msvc/upnpc-static.vcxproj deleted file mode 100644 index 44dea81e8..000000000 --- a/external/miniupnpc/msvc/upnpc-static.vcxproj +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}</ProjectGuid> - <RootNamespace>upnpcstatic</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <PlatformToolset>v140</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <OutDir>$(SolutionDir)$(Configuration)\</OutDir> - <IntDir>$(Configuration)\</IntDir> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(SolutionDir)$(Configuration)\</OutDir> - <IntDir>$(Configuration)\</IntDir> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>_DEBUG;_CONSOLE;MINIUPNP_STATICLIB;DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader /> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - </ClCompile> - <Link> - <AdditionalDependencies>ws2_32.lib;IPHlpApi.Lib;Debug\miniupnpc.lib;%(AdditionalDependencies)</AdditionalDependencies> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader /> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <AdditionalDependencies>ws2_32.lib;IPHlpApi.Lib;Release\miniupnpc.lib;%(AdditionalDependencies)</AdditionalDependencies> - <GenerateDebugInformation>true</GenerateDebugInformation> - <SubSystem>Console</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <TargetMachine>MachineX86</TargetMachine> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\upnpc.c" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="miniupnpc.vcxproj"> - <Project>{d28ce435-cb33-4bae-8a52-c6ef915956f5}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/upnpc-static.vcxproj.filters b/external/miniupnpc/msvc/upnpc-static.vcxproj.filters deleted file mode 100644 index 2e75de02f..000000000 --- a/external/miniupnpc/msvc/upnpc-static.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Fichiers sources"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Fichiers d%27en-tête"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Fichiers de ressources"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\upnpc.c"> - <Filter>Fichiers sources</Filter> - </ClCompile> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/external/miniupnpc/portlistingparse.c b/external/miniupnpc/portlistingparse.c deleted file mode 100644 index 55859f271..000000000 --- a/external/miniupnpc/portlistingparse.c +++ /dev/null @@ -1,172 +0,0 @@ -/* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2016 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#include <string.h> -#include <stdlib.h> -#ifdef DEBUG -#include <stdio.h> -#endif /* DEBUG */ -#include "portlistingparse.h" -#include "minixml.h" - -/* list of the elements */ -static const struct { - const portMappingElt code; - const char * const str; -} elements[] = { - { PortMappingEntry, "PortMappingEntry"}, - { NewRemoteHost, "NewRemoteHost"}, - { NewExternalPort, "NewExternalPort"}, - { NewProtocol, "NewProtocol"}, - { NewInternalPort, "NewInternalPort"}, - { NewInternalClient, "NewInternalClient"}, - { NewEnabled, "NewEnabled"}, - { NewDescription, "NewDescription"}, - { NewLeaseTime, "NewLeaseTime"}, - { PortMappingEltNone, NULL} -}; - -/* Helper function */ -static UNSIGNED_INTEGER -atoui(const char * p, int l) -{ - UNSIGNED_INTEGER r = 0; - while(l > 0 && *p) - { - if(*p >= '0' && *p <= '9') - r = r*10 + (*p - '0'); - else - break; - p++; - l--; - } - return r; -} - -/* Start element handler */ -static void -startelt(void * d, const char * name, int l) -{ - int i; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { - if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) - { - pdata->curelt = elements[i].code; - break; - } - } - if(pdata->curelt == PortMappingEntry) - { - struct PortMapping * pm; - pm = calloc(1, sizeof(struct PortMapping)); - if(pm == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "startelt"); -#endif /* DEBUG */ - return; - } - pm->l_next = pdata->l_head; /* insert in list */ - pdata->l_head = pm; - } -} - -/* End element handler */ -static void -endelt(void * d, const char * name, int l) -{ - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - (void)name; - (void)l; - pdata->curelt = PortMappingEltNone; -} - -/* Data handler */ -static void -data(void * d, const char * data, int l) -{ - struct PortMapping * pm; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pm = pdata->l_head; - if(!pm) - return; - if(l > 63) - l = 63; - switch(pdata->curelt) - { - case NewRemoteHost: - memcpy(pm->remoteHost, data, l); - pm->remoteHost[l] = '\0'; - break; - case NewExternalPort: - pm->externalPort = (unsigned short)atoui(data, l); - break; - case NewProtocol: - if(l > 3) - l = 3; - memcpy(pm->protocol, data, l); - pm->protocol[l] = '\0'; - break; - case NewInternalPort: - pm->internalPort = (unsigned short)atoui(data, l); - break; - case NewInternalClient: - memcpy(pm->internalClient, data, l); - pm->internalClient[l] = '\0'; - break; - case NewEnabled: - pm->enabled = (unsigned char)atoui(data, l); - break; - case NewDescription: - memcpy(pm->description, data, l); - pm->description[l] = '\0'; - break; - case NewLeaseTime: - pm->leaseTime = atoui(data, l); - break; - default: - break; - } -} - - -/* Parse the PortMappingList XML document for IGD version 2 - */ -void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata) -{ - struct xmlparser parser; - - memset(pdata, 0, sizeof(struct PortMappingParserData)); - /* init xmlparser */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = pdata; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = data; - parser.attfunc = 0; - parsexml(&parser); -} - -void -FreePortListing(struct PortMappingParserData * pdata) -{ - struct PortMapping * pm; - while((pm = pdata->l_head) != NULL) - { - /* remove from list */ - pdata->l_head = pm->l_next; - free(pm); - } -} - diff --git a/external/miniupnpc/portlistingparse.h b/external/miniupnpc/portlistingparse.h deleted file mode 100644 index e3957a3f4..000000000 --- a/external/miniupnpc/portlistingparse.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $Id: portlistingparse.h,v 1.10 2014/11/01 10:37:32 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2015 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#ifndef PORTLISTINGPARSE_H_INCLUDED -#define PORTLISTINGPARSE_H_INCLUDED - -#include "miniupnpc_declspec.h" -/* for the definition of UNSIGNED_INTEGER */ -#include "miniupnpctypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* sample of PortMappingEntry : - <p:PortMappingEntry> - <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost> - <p:NewExternalPort>2345</p:NewExternalPort> - <p:NewProtocol>TCP</p:NewProtocol> - <p:NewInternalPort>2345</p:NewInternalPort> - <p:NewInternalClient>192.168.1.137</p:NewInternalClient> - <p:NewEnabled>1</p:NewEnabled> - <p:NewDescription>dooom</p:NewDescription> - <p:NewLeaseTime>345</p:NewLeaseTime> - </p:PortMappingEntry> - */ -typedef enum { PortMappingEltNone, - PortMappingEntry, NewRemoteHost, - NewExternalPort, NewProtocol, - NewInternalPort, NewInternalClient, - NewEnabled, NewDescription, - NewLeaseTime } portMappingElt; - -struct PortMapping { - struct PortMapping * l_next; /* list next element */ - UNSIGNED_INTEGER leaseTime; - unsigned short externalPort; - unsigned short internalPort; - char remoteHost[64]; - char internalClient[64]; - char description[64]; - char protocol[4]; - unsigned char enabled; -}; - -struct PortMappingParserData { - struct PortMapping * l_head; /* list head */ - portMappingElt curelt; -}; - -MINIUPNP_LIBSPEC void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata); - -MINIUPNP_LIBSPEC void -FreePortListing(struct PortMappingParserData * pdata); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/external/miniupnpc/pymoduletest.py b/external/miniupnpc/pymoduletest.py deleted file mode 100755 index 9fddd9c29..000000000 --- a/external/miniupnpc/pymoduletest.py +++ /dev/null @@ -1,88 +0,0 @@ -#! /usr/bin/python -# vim: tabstop=2 shiftwidth=2 expandtab -# MiniUPnP project -# Author : Thomas Bernard -# This Sample code is public domain. -# website : http://miniupnp.tuxfamily.org/ - -# import the python miniupnpc module -import miniupnpc -import sys - -try: - import argparse - parser = argparse.ArgumentParser() - parser.add_argument('-m', '--multicastif') - parser.add_argument('-p', '--minissdpdsocket') - parser.add_argument('-d', '--discoverdelay', type=int, default=200) - parser.add_argument('-z', '--localport', type=int, default=0) - # create the object - u = miniupnpc.UPnP(**vars(parser.parse_args())) -except: - print 'argparse not available' - i = 1 - multicastif = None - minissdpdsocket = None - discoverdelay = 200 - localport = 0 - while i < len(sys.argv): - print sys.argv[i] - if sys.argv[i] == '-m' or sys.argv[i] == '--multicastif': - multicastif = sys.argv[i+1] - elif sys.argv[i] == '-p' or sys.argv[i] == '--minissdpdsocket': - minissdpdsocket = sys.argv[i+1] - elif sys.argv[i] == '-d' or sys.argv[i] == '--discoverdelay': - discoverdelay = int(sys.argv[i+1]) - elif sys.argv[i] == '-z' or sys.argv[i] == '--localport': - localport = int(sys.argv[i+1]) - else: - raise Exception('invalid argument %s' % sys.argv[i]) - i += 2 - # create the object - u = miniupnpc.UPnP(multicastif, minissdpdsocket, discoverdelay, localport) - -print 'inital(default) values :' -print ' discoverdelay', u.discoverdelay -print ' lanaddr', u.lanaddr -print ' multicastif', u.multicastif -print ' minissdpdsocket', u.minissdpdsocket -#u.minissdpdsocket = '../minissdpd/minissdpd.sock' -# discovery process, it usualy takes several seconds (2 seconds or more) -print 'Discovering... delay=%ums' % u.discoverdelay -print u.discover(), 'device(s) detected' -# select an igd -try: - u.selectigd() -except Exception, e: - print 'Exception :', e - sys.exit(1) -# display information about the IGD and the internet connection -print 'local ip address :', u.lanaddr -print 'external ip address :', u.externalipaddress() -print u.statusinfo(), u.connectiontype() -print 'total bytes : sent', u.totalbytesent(), 'received', u.totalbytereceived() -print 'total packets : sent', u.totalpacketsent(), 'received', u.totalpacketreceived() - -#print u.addportmapping(64000, 'TCP', -# '192.168.1.166', 63000, 'port mapping test', '') -#print u.deleteportmapping(64000, 'TCP') - -port = 0 -proto = 'UDP' -# list the redirections : -i = 0 -while True: - p = u.getgenericportmapping(i) - if p==None: - break - print i, p - (port, proto, (ihost,iport), desc, c, d, e) = p - #print port, desc - i = i + 1 - -print u.getspecificportmapping(port, proto) -try: - print u.getportmappingnumberofentries() -except Exception, e: - print 'GetPortMappingNumberOfEntries() is not supported :', e - diff --git a/external/miniupnpc/pymoduletest3.py b/external/miniupnpc/pymoduletest3.py deleted file mode 100755 index d4cf1e22f..000000000 --- a/external/miniupnpc/pymoduletest3.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/python3 -# MiniUPnP project -# Author : Thomas Bernard -# This Sample code is public domain. -# website : http://miniupnp.tuxfamily.org/ - -# import the python miniupnpc module -import miniupnpc -import sys - -# create the object -u = miniupnpc.UPnP() -print('inital(default) values :') -print(' discoverdelay', u.discoverdelay) -print(' lanaddr', u.lanaddr) -print(' multicastif', u.multicastif) -print(' minissdpdsocket', u.minissdpdsocket) -u.discoverdelay = 200; -#u.minissdpdsocket = '../minissdpd/minissdpd.sock' -# discovery process, it usualy takes several seconds (2 seconds or more) -print('Discovering... delay=%ums' % u.discoverdelay) -print(u.discover(), 'device(s) detected') -# select an igd -try: - u.selectigd() -except Exception as e: - print('Exception :', e) - sys.exit(1) -# display information about the IGD and the internet connection -print('local ip address :', u.lanaddr) -print('external ip address :', u.externalipaddress()) -print(u.statusinfo(), u.connectiontype()) - -#print u.addportmapping(64000, 'TCP', -# '192.168.1.166', 63000, 'port mapping test', '') -#print u.deleteportmapping(64000, 'TCP') - -port = 0 -proto = 'UDP' -# list the redirections : -i = 0 -while True: - p = u.getgenericportmapping(i) - if p==None: - break - print(i, p) - (port, proto, (ihost,iport), desc, c, d, e) = p - #print port, desc - i = i + 1 - -print(u.getspecificportmapping(port, proto)) - diff --git a/external/miniupnpc/receivedata.c b/external/miniupnpc/receivedata.c deleted file mode 100644 index d003eb69d..000000000 --- a/external/miniupnpc/receivedata.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $Id: receivedata.c,v 1.7 2015/11/09 21:51:41 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2011-2014 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <string.h> -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#else /* _WIN32 */ -#include <unistd.h> -#if defined(__amigaos__) && !defined(__amigaos4__) -#define socklen_t int -#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ -#include <sys/select.h> -#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ -#include <sys/socket.h> -#include <netinet/in.h> -#if !defined(__amigaos__) && !defined(__amigaos4__) -#include <poll.h> -#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */ -#include <errno.h> -#define MINIUPNPC_IGNORE_EINTR -#endif /* _WIN32 */ - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#include "receivedata.h" - -int -receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id) -{ -#ifdef MINIUPNPC_GET_SRC_ADDR - struct sockaddr_storage src_addr; - socklen_t src_addr_len = sizeof(src_addr); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - int n; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* using poll */ - struct pollfd fds[1]; /* for the poll */ -#ifdef MINIUPNPC_IGNORE_EINTR - do { -#endif /* MINIUPNPC_IGNORE_EINTR */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll(fds, 1, timeout); -#ifdef MINIUPNPC_IGNORE_EINTR - } while(n < 0 && errno == EINTR); -#endif /* MINIUPNPC_IGNORE_EINTR */ - if(n < 0) { - PRINT_SOCKET_ERROR("poll"); - return -1; - } else if(n == 0) { - /* timeout */ - return 0; - } -#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - /* using select under _WIN32 and amigaos */ - fd_set socketSet; - TIMEVAL timeval; - FD_ZERO(&socketSet); - FD_SET(socket, &socketSet); - timeval.tv_sec = timeout / 1000; - timeval.tv_usec = (timeout % 1000) * 1000; - n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); - if(n < 0) { - PRINT_SOCKET_ERROR("select"); - return -1; - } else if(n == 0) { - return 0; - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ -#ifdef MINIUPNPC_GET_SRC_ADDR - memset(&src_addr, 0, sizeof(src_addr)); - n = recvfrom(socket, data, length, 0, - (struct sockaddr *)&src_addr, &src_addr_len); -#else /* MINIUPNPC_GET_SRC_ADDR */ - n = recv(socket, data, length, 0); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - if(n<0) { - PRINT_SOCKET_ERROR("recv"); - } -#ifdef MINIUPNPC_GET_SRC_ADDR - if (src_addr.ss_family == AF_INET6) { - const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr; -#ifdef DEBUG - printf("scope_id=%u\n", src_addr6->sin6_scope_id); -#endif /* DEBUG */ - if(scope_id) - *scope_id = src_addr6->sin6_scope_id; - } -#endif /* MINIUPNPC_GET_SRC_ADDR */ - return n; -} - diff --git a/external/miniupnpc/receivedata.h b/external/miniupnpc/receivedata.h deleted file mode 100644 index cb85c3317..000000000 --- a/external/miniupnpc/receivedata.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id: receivedata.h,v 1.3 2012/06/23 22:34:47 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2011-2012 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef RECEIVEDATA_H_INCLUDED -#define RECEIVEDATA_H_INCLUDED - -/* Reads data from the specified socket. - * Returns the number of bytes read if successful, zero if no bytes were - * read or if we timed out. Returns negative if there was an error. */ -int receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id); - -#endif - diff --git a/external/miniupnpc/setup.py b/external/miniupnpc/setup.py deleted file mode 100755 index 24a676d85..000000000 --- a/external/miniupnpc/setup.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/python -# vim: tabstop=8 shiftwidth=8 expandtab -# $Id: setup.py,v 1.9 2012/05/23 08:50:10 nanard Exp $ -# the MiniUPnP Project (c) 2007-2017 Thomas Bernard -# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ -# -# python script to build the miniupnpc module under unix -# -# Uses MAKE environment variable (defaulting to 'make') - -from setuptools import setup, Extension -from setuptools.command import build_ext -import subprocess -import os - -EXT = ['libminiupnpc.a'] - -class make_then_build_ext(build_ext.build_ext): - def run(self): - subprocess.check_call([os.environ.get('MAKE', 'make')] + EXT) - build_ext.build_ext.run(self) - -setup(name="miniupnpc", - version=open('VERSION').read().strip(), - author='Thomas BERNARD', - author_email='miniupnp@free.fr', - license=open('LICENSE').read(), - url='http://miniupnp.free.fr/', - description='miniUPnP client', - cmdclass={'build_ext': make_then_build_ext}, - ext_modules=[ - Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], - extra_objects=EXT) - ]) - diff --git a/external/miniupnpc/setupmingw32.py b/external/miniupnpc/setupmingw32.py deleted file mode 100755 index 7e3c382bd..000000000 --- a/external/miniupnpc/setupmingw32.py +++ /dev/null @@ -1,28 +0,0 @@ -#! /usr/bin/python -# vim: tabstop=8 shiftwidth=8 expandtab -# $Id: setupmingw32.py,v 1.8 2012/05/23 08:50:10 nanard Exp $ -# the MiniUPnP Project (c) 2007-2014 Thomas Bernard -# http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ -# -# python script to build the miniupnpc module under windows (using mingw32) -# -try: - from setuptools import setup, Extension -except ImportError: - from distutils.core import setup, Extension -from distutils import sysconfig -sysconfig.get_config_vars()["OPT"] = '' -sysconfig.get_config_vars()["CFLAGS"] = '' -setup(name="miniupnpc", - version=open('VERSION').read().strip(), - author='Thomas BERNARD', - author_email='miniupnp@free.fr', - license=open('LICENSE').read(), - url='http://miniupnp.free.fr/', - description='miniUPnP client', - ext_modules=[ - Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], - libraries=["ws2_32", "iphlpapi"], - extra_objects=["libminiupnpc.a"]) - ]) - diff --git a/external/miniupnpc/testdesc/linksys_WAG200G_desc.values b/external/miniupnpc/testdesc/linksys_WAG200G_desc.values deleted file mode 100644 index cf4222187..000000000 --- a/external/miniupnpc/testdesc/linksys_WAG200G_desc.values +++ /dev/null @@ -1,14 +0,0 @@ -# values for linksys_WAG200G_desc.xml - -CIF: - servicetype = urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 - controlurl = /upnp/control/WANCommonIFC1 - eventsuburl = /upnp/event/WANCommonIFC1 - scpdurl = /cmnicfg.xml - -first: - servicetype = urn:schemas-upnp-org:service:WANPPPConnection:1 - controlurl = /upnp/control/WANPPPConn1 - eventsuburl = /upnp/event/WANPPPConn1 - scpdurl = /pppcfg.xml - diff --git a/external/miniupnpc/testdesc/linksys_WAG200G_desc.xml b/external/miniupnpc/testdesc/linksys_WAG200G_desc.xml deleted file mode 100644 index d428d73b0..000000000 --- a/external/miniupnpc/testdesc/linksys_WAG200G_desc.xml +++ /dev/null @@ -1,110 +0,0 @@ -<?xml version="1.0"?> -<root xmlns="urn:schemas-upnp-org:device-1-0"> -<specVersion> -<major>1</major> -<minor>0</minor> -</specVersion> -<URLBase>http://192.168.1.1:49152</URLBase> -<device> -<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType> -<friendlyName>LINKSYS WAG200G Gateway</friendlyName> -<manufacturer>LINKSYS</manufacturer> -<manufacturerURL>http://www.linksys.com</manufacturerURL> -<modelDescription>LINKSYS WAG200G Gateway</modelDescription> -<modelName>Wireless-G ADSL Home Gateway</modelName> -<modelNumber>WAG200G</modelNumber> -<modelURL>http://www.linksys.com</modelURL> -<serialNumber>123456789</serialNumber> -<UDN>uuid:8ca2eb37-1dd2-11b2-86f1-001a709b5aa8</UDN> -<UPC>WAG200G</UPC> -<serviceList> -<service> -<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType> -<serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId> -<controlURL>/upnp/control/L3Forwarding1</controlURL> -<eventSubURL>/upnp/event/L3Forwarding1</eventSubURL> -<SCPDURL>/l3frwd.xml</SCPDURL> -</service> -</serviceList> -<deviceList> -<device> -<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType> -<friendlyName>WANDevice</friendlyName> -<manufacturer>LINKSYS</manufacturer> -<manufacturerURL>http://www.linksys.com/</manufacturerURL> -<modelDescription>Residential Gateway</modelDescription> -<modelName>Internet Connection Sharing</modelName> -<modelNumber>1</modelNumber> -<modelURL>http://www.linksys.com/</modelURL> -<serialNumber>0000001</serialNumber> -<UDN>uuid:8ca2eb36-1dd2-11b2-86f1-001a709b5aa8</UDN> -<UPC>WAG200G</UPC> -<serviceList> -<service> -<serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType> -<serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId> -<controlURL>/upnp/control/WANCommonIFC1</controlURL> -<eventSubURL>/upnp/event/WANCommonIFC1</eventSubURL> -<SCPDURL>/cmnicfg.xml</SCPDURL> -</service> -</serviceList> -<deviceList> -<device> -<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType> -<friendlyName>WANConnectionDevice</friendlyName> -<manufacturer>LINKSYS</manufacturer> -<manufacturerURL>http://www.linksys.com/</manufacturerURL> -<modelDescription>Residential Gateway</modelDescription> -<modelName>Internet Connection Sharing</modelName> -<modelNumber>1</modelNumber> -<modelURL>http://www.linksys.com/</modelURL> -<serialNumber>0000001</serialNumber> -<UDN>uuid:8ca2eb37-1dd2-11b2-86f0-001a709b5aa8</UDN> -<UPC>WAG200G</UPC> -<serviceList> -<service> -<serviceType>urn:schemas-upnp-org:service:WANEthernetLinkConfig:1</serviceType> -<serviceId>urn:upnp-org:serviceId:WANEthLinkC1</serviceId> -<controlURL>/upnp/control/WANEthLinkC1</controlURL> -<eventSubURL>/upnp/event/WANEthLinkC1</eventSubURL> -<SCPDURL>/wanelcfg.xml</SCPDURL> -</service> -<service> -<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType> -<serviceId>urn:upnp-org:serviceId:WANPPPConn1</serviceId> -<controlURL>/upnp/control/WANPPPConn1</controlURL> -<eventSubURL>/upnp/event/WANPPPConn1</eventSubURL> -<SCPDURL>/pppcfg.xml</SCPDURL> -</service> -</serviceList> -</device> -</deviceList> -</device> -<device> -<deviceType>urn:schemas-upnp-org:device:LANDevice:1</deviceType> -<friendlyName>LANDevice</friendlyName> -<manufacturer>LINKSYS</manufacturer> -<manufacturerURL>http://www.linksys.com/</manufacturerURL> -<modelDescription>Residential Gateway</modelDescription> -<modelName>Residential Gateway</modelName> -<modelNumber>1</modelNumber> -<modelURL>http://www.linksys.com/</modelURL> -<serialNumber>0000001</serialNumber> -<UDN>uuid:8ca2eb36-1dd2-11b2-86f0-001a709b5aa -8</UDN> -<UPC>WAG200G</UPC> -<serviceList> -<service> -<serviceType>urn:schemas-upnp-org:service:LANHostConfigManagement:1</serviceType> -<serviceId>urn:upnp-org:serviceId:LANHostCfg1</serviceId> -<controlURL>/upnp/control/LANHostCfg1</controlURL> -<eventSubURL>/upnp/event/LANHostCfg1</eventSubURL> -<SCPDURL>/lanhostc.xml</SCPDURL> -</service> -</serviceList> -</device> -</deviceList> -<presentationURL>http://192.168.1.1/index.htm</presentationURL> -</device> -</root> - diff --git a/external/miniupnpc/testdesc/new_LiveBox_desc.values b/external/miniupnpc/testdesc/new_LiveBox_desc.values deleted file mode 100644 index c55552e58..000000000 --- a/external/miniupnpc/testdesc/new_LiveBox_desc.values +++ /dev/null @@ -1,20 +0,0 @@ -# values for new_LiveBox_desc.xml - -CIF: - servicetype = urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 - controlurl = /87895a19/upnp/control/WANCommonIFC1 - eventsuburl = /87895a19/upnp/control/WANCommonIFC1 - scpdurl = /87895a19/gateicfgSCPD.xml - -first: - servicetype = urn:schemas-upnp-org:service:WANPPPConnection:2 - controlurl = /87895a19/upnp/control/WANIPConn1 - eventsuburl = /87895a19/upnp/control/WANIPConn1 - scpdurl = /87895a19/gateconnSCPD_PPP.xml - -IPv6FC: - servicetype = urn:schemas-upnp-org:service:WANIPv6FirewallControl:1 - controlurl = /87895a19/upnp/control/WANIPv6FwCtrl1 - eventsuburl = /87895a19/upnp/control/WANIPv6FwCtrl1 - scpdurl = /87895a19/wanipv6fwctrlSCPD.xml - diff --git a/external/miniupnpc/testdesc/new_LiveBox_desc.xml b/external/miniupnpc/testdesc/new_LiveBox_desc.xml deleted file mode 100644 index 620eb55af..000000000 --- a/external/miniupnpc/testdesc/new_LiveBox_desc.xml +++ /dev/null @@ -1,90 +0,0 @@ -<?xml version="1.0"?>
-<root xmlns="urn:schemas-upnp-org:device-1-0">
- <specVersion>
- <major>1</major>
- <minor>0</minor>
- </specVersion>
- <device>
- <pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">VEN_0129&DEV_0000&SUBSYS_03&REV_250417</pnpx:X_hardwareId>
- <pnpx:X_compatibleId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">GenericUmPass</pnpx:X_compatibleId>
- <pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">NetworkInfrastructure.Gateway</pnpx:X_deviceCategory>
- <df:X_deviceCategory xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">Network.Gateway</df:X_deviceCategory>
- <deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:2</deviceType>
- <friendlyName>Orange Livebox</friendlyName>
- <manufacturer>Sagemcom</manufacturer>
- <manufacturerURL>http://www.sagemcom.com/</manufacturerURL>
- <modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName>
- <UDN>uuid:87895a19-50f9-3736-a87f-115c230155f8</UDN>
- <modelDescription>Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription>
- <modelNumber>3</modelNumber>
- <serialNumber>LK14129DP441489</serialNumber>
- <presentationURL>http://192.168.1.1</presentationURL>
- <UPC></UPC>
- <iconList>
- <icon>
- <mimetype>image/png</mimetype>
- <width>16</width>
- <height>16</height>
- <depth>8</depth>
- <url>/87895a19/ligd.png</url>
- </icon>
- </iconList>
- <deviceList>
- <device>
- <deviceType>urn:schemas-upnp-org:device:WANDevice:2</deviceType>
- <friendlyName>WANDevice</friendlyName>
- <manufacturer>Sagemcom</manufacturer>
- <manufacturerURL>http://www.sagemcom.com/</manufacturerURL>
- <modelDescription>WAN Device on Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription>
- <modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName>
- <modelNumber>3</modelNumber>
- <modelURL>http://www.sagemcom.com/</modelURL>
- <serialNumber>LK14129DP441489</serialNumber>
- <presentationURL>http://192.168.1.1</presentationURL>
- <UDN>uuid:e2397374-53d8-3fc6-8306-593ba1a34625</UDN>
- <UPC></UPC>
- <serviceList>
- <service>
- <serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType>
- <serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId>
- <controlURL>/87895a19/upnp/control/WANCommonIFC1</controlURL>
- <eventSubURL>/87895a19/upnp/control/WANCommonIFC1</eventSubURL>
- <SCPDURL>/87895a19/gateicfgSCPD.xml</SCPDURL>
- </service>
- </serviceList>
- <deviceList>
- <device>
- <deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:2</deviceType>
- <friendlyName>WANConnectionDevice</friendlyName>
- <manufacturer>Sagemcom</manufacturer>
- <manufacturerURL>http://www.sagemcom.com/</manufacturerURL>
- <modelDescription>WanConnectionDevice on Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription>
- <modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName>
- <modelNumber>3</modelNumber>
- <modelURL>http://www.sagemcom.com/</modelURL>
- <serialNumber>LK14129DP441489</serialNumber>
- <presentationURL>http://192.168.1.1</presentationURL>
- <UDN>uuid:44598a08-288e-32c9-8a4d-d3c008ede331</UDN>
- <UPC></UPC>
- <serviceList>
- <service>
- <serviceType>urn:schemas-upnp-org:service:WANPPPConnection:2</serviceType>
- <serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId>
- <controlURL>/87895a19/upnp/control/WANIPConn1</controlURL>
- <eventSubURL>/87895a19/upnp/control/WANIPConn1</eventSubURL>
- <SCPDURL>/87895a19/gateconnSCPD_PPP.xml</SCPDURL>
- </service>
- <service>
- <serviceType>urn:schemas-upnp-org:service:WANIPv6FirewallControl:1</serviceType>
- <serviceId>urn:upnp-org:serviceId:WANIPv6FwCtrl1</serviceId>
- <controlURL>/87895a19/upnp/control/WANIPv6FwCtrl1</controlURL>
- <eventSubURL>/87895a19/upnp/control/WANIPv6FwCtrl1</eventSubURL>
- <SCPDURL>/87895a19/wanipv6fwctrlSCPD.xml</SCPDURL>
- </service>
- </serviceList>
- </device>
- </deviceList>
- </device>
- </deviceList>
- </device>
-</root>
\ No newline at end of file diff --git a/external/miniupnpc/testigddescparse.c b/external/miniupnpc/testigddescparse.c deleted file mode 100644 index cb7e94ad6..000000000 --- a/external/miniupnpc/testigddescparse.c +++ /dev/null @@ -1,187 +0,0 @@ -/* $Id: testigddescparse.c,v 1.8 2015/02/08 08:46:06 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2008-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "igd_desc_parse.h" -#include "minixml.h" -#include "miniupnpc.h" - -/* count number of differences */ -int compare_service(struct IGDdatas_service * s, FILE * f) -{ - int n = 0; - char line[1024]; - - while(fgets(line, sizeof(line), f)) { - char * value; - char * equal; - char * name; - char * parsedvalue; - int l; - l = strlen(line); - while((l > 0) && ((line[l-1] == '\r') || (line[l-1] == '\n') || (line[l-1] == ' '))) - line[--l] = '\0'; - if(l == 0) - break; /* end on blank line */ - if(line[0] == '#') - continue; /* skip comments */ - equal = strchr(line, '='); - if(equal == NULL) { - fprintf(stderr, "Warning, line does not contain '=' : %s\n", line); - continue; - } - *equal = '\0'; - name = line; - while(*name == ' ' || *name == '\t') - name++; - l = strlen(name); - while((l > 0) && (name[l-1] == ' ' || name[l-1] == '\t')) - name[--l] = '\0'; - value = equal + 1; - while(*value == ' ' || *value == '\t') - value++; - if(strcmp(name, "controlurl") == 0) - parsedvalue = s->controlurl; - else if(strcmp(name, "eventsuburl") == 0) - parsedvalue = s->eventsuburl; - else if(strcmp(name, "scpdurl") == 0) - parsedvalue = s->scpdurl; - else if(strcmp(name, "servicetype") == 0) - parsedvalue = s->servicetype; - else { - fprintf(stderr, "unknown field '%s'\n", name); - continue; - } - if(0 != strcmp(parsedvalue, value)) { - fprintf(stderr, "difference : '%s' != '%s'\n", parsedvalue, value); - n++; - } - } - return n; -} - -int compare_igd(struct IGDdatas * p, FILE * f) -{ - int n = 0; - char line[1024]; - struct IGDdatas_service * s; - - while(fgets(line, sizeof(line), f)) { - char * colon; - int l = (int)strlen(line); - while((l > 0) && (line[l-1] == '\r' || (line[l-1] == '\n'))) - line[--l] = '\0'; - if(l == 0 || line[0] == '#') - continue; /* skip blank lines and comments */ - colon = strchr(line, ':'); - if(colon == NULL) { - fprintf(stderr, "Warning, no ':' : %s\n", line); - continue; - } - s = NULL; - *colon = '\0'; - if(strcmp(line, "CIF") == 0) - s = &p->CIF; - else if(strcmp(line, "first") == 0) - s = &p->first; - else if(strcmp(line, "second") == 0) - s = &p->second; - else if(strcmp(line, "IPv6FC") == 0) - s = &p->IPv6FC; - else { - s = NULL; - fprintf(stderr, "*** unknown service '%s' ***\n", line); - n++; - continue; - } - n += compare_service(s, f); - } - if(n > 0) - fprintf(stderr, "*** %d difference%s ***\n", n, (n > 1) ? "s" : ""); - return n; -} - -int test_igd_desc_parse(char * buffer, int len, FILE * f) -{ - int n; - struct IGDdatas igd; - struct xmlparser parser; - struct UPNPUrls urls; - - memset(&igd, 0, sizeof(struct IGDdatas)); - memset(&parser, 0, sizeof(struct xmlparser)); - parser.xmlstart = buffer; - parser.xmlsize = len; - parser.data = &igd; - parser.starteltfunc = IGDstartelt; - parser.endeltfunc = IGDendelt; - parser.datafunc = IGDdata; - parsexml(&parser); -#ifdef DEBUG - printIGD(&igd); -#endif /* DEBUG */ - GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0); - printf("ipcondescURL='%s'\n", urls.ipcondescURL); - printf("controlURL='%s'\n", urls.controlURL); - printf("controlURL_CIF='%s'\n", urls.controlURL_CIF); - n = f ? compare_igd(&igd, f) : 0; - FreeUPNPUrls(&urls); - return n; -} - -int main(int argc, char * * argv) -{ - FILE * f; - char * buffer; - int len; - int r; - if(argc<2) { - fprintf(stderr, "Usage: %s file.xml [file.values]\n", argv[0]); - return 1; - } - f = fopen(argv[1], "r"); - if(!f) { - fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); - return 1; - } - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - buffer = malloc(len); - if(!buffer) { - fprintf(stderr, "Memory allocation error.\n"); - fclose(f); - return 1; - } - r = (int)fread(buffer, 1, len, f); - if(r != len) { - fprintf(stderr, "Failed to read file %s. %d out of %d bytes.\n", - argv[1], r, len); - fclose(f); - free(buffer); - return 1; - } - fclose(f); - f = NULL; - if(argc > 2) { - f = fopen(argv[2], "r"); - if(!f) { - fprintf(stderr, "Cannot open %s for reading.\n", argv[2]); - free(buffer); - return 1; - } - } - r = test_igd_desc_parse(buffer, len, f); - free(buffer); - if(f) - fclose(f); - return r; -} - diff --git a/external/miniupnpc/testminiwget.c b/external/miniupnpc/testminiwget.c deleted file mode 100644 index 5eb49ec1c..000000000 --- a/external/miniupnpc/testminiwget.c +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id: testminiwget.c,v 1.5 2016/01/24 17:24:36 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include <stdio.h> -#include <stdlib.h> -#include "miniwget.h" - -/** - * This program uses the miniwget / miniwget_getaddr function - * from miniwget.c in order to retreive a web ressource using - * a GET HTTP method, and store it in a file. - */ -int main(int argc, char * * argv) -{ - void * data; - int size, writtensize; - FILE *f; - char addr[64]; - int status_code = -1; - - if(argc < 3) { - fprintf(stderr, "Usage:\t%s url file\n", argv[0]); - fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]); - return 1; - } - data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0, &status_code); - if(!data || (status_code != 200)) { - if(data) free(data); - fprintf(stderr, "Error %d fetching %s\n", status_code, argv[1]); - return 1; - } - printf("local address : %s\n", addr); - printf("got %d bytes\n", size); - f = fopen(argv[2], "wb"); - if(!f) { - fprintf(stderr, "Cannot open file %s for writing\n", argv[2]); - free(data); - return 1; - } - writtensize = fwrite(data, 1, size, f); - if(writtensize != size) { - fprintf(stderr, "Could only write %d bytes out of %d to %s\n", - writtensize, size, argv[2]); - } else { - printf("%d bytes written to %s\n", writtensize, argv[2]); - } - fclose(f); - free(data); - return 0; -} - diff --git a/external/miniupnpc/testminiwget.sh b/external/miniupnpc/testminiwget.sh deleted file mode 100755 index 690b4056f..000000000 --- a/external/miniupnpc/testminiwget.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/sh -# $Id: testminiwget.sh,v 1.13 2015/09/03 17:57:44 nanard Exp $ -# project miniupnp : http://miniupnp.free.fr/ -# (c) 2011-2015 Thomas Bernard -# -# test program for miniwget.c -# is usually invoked by "make check" -# -# This test program : -# 1 - launches a local HTTP server (minihttptestserver) -# 2 - uses testminiwget to retreive data from this server -# 3 - compares served and received data -# 4 - kills the local HTTP server and exits -# -# The script was tested and works with ksh, bash -# it should now also run with dash - -TMPD=`mktemp -d -t miniwgetXXXXXXXXXX` -HTTPSERVEROUT="${TMPD}/httpserverout" -EXPECTEDFILE="${TMPD}/expectedfile" -DOWNLOADEDFILE="${TMPD}/downloadedfile" -PORT= -RET=0 - -case "$HAVE_IPV6" in - n|no|0) - ADDR=localhost - SERVERARGS="" - ;; - *) - ADDR="[::1]" - SERVERARGS="-6" - ;; - -esac - -#make minihttptestserver -#make testminiwget - -# launching the test HTTP server -./minihttptestserver $SERVERARGS -e $EXPECTEDFILE > $HTTPSERVEROUT & -SERVERPID=$! -while [ -z "$PORT" ]; do - sleep 1 - PORT=`cat $HTTPSERVEROUT | sed 's/Listening on port \([0-9]*\)/\1/' ` -done -echo "Test HTTP server is listening on $PORT" - -URL1="http://$ADDR:$PORT/index.html" -URL2="http://$ADDR:$PORT/chunked" -URL3="http://$ADDR:$PORT/addcrap" - -echo "standard test ..." -./testminiwget $URL1 "${DOWNLOADEDFILE}.1" -if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.1" ; then - echo "ok" -else - echo "standard test FAILED" - RET=1 -fi - -echo "chunked transfert encoding test ..." -./testminiwget $URL2 "${DOWNLOADEDFILE}.2" -if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.2" ; then - echo "ok" -else - echo "chunked transfert encoding test FAILED" - RET=1 -fi - -echo "response too long test ..." -./testminiwget $URL3 "${DOWNLOADEDFILE}.3" -if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.3" ; then - echo "ok" -else - echo "response too long test FAILED" - RET=1 -fi - -# kill the test HTTP server -kill $SERVERPID -wait $SERVERPID - -# remove temporary files (for success cases) -if [ $RET -eq 0 ]; then - rm -f "${DOWNLOADEDFILE}.1" - rm -f "${DOWNLOADEDFILE}.2" - rm -f "${DOWNLOADEDFILE}.3" - rm -f $EXPECTEDFILE $HTTPSERVEROUT - rmdir ${TMPD} -else - echo "at least one of the test FAILED" - echo "directory ${TMPD} is left intact" -fi -exit $RET - diff --git a/external/miniupnpc/testminixml.c b/external/miniupnpc/testminixml.c deleted file mode 100644 index 57c4a85eb..000000000 --- a/external/miniupnpc/testminixml.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $Id: testminixml.c,v 1.10 2014/11/17 17:19:13 nanard Exp $ - * MiniUPnP project - * Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard. - * Copyright (c) 2005-2014 Thomas Bernard - * - * testminixml.c - * test program for the "minixml" functions. - */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "minixml.h" -#include "igd_desc_parse.h" - -/* ---------------------------------------------------------------------- */ -void printeltname1(void * d, const char * name, int l) -{ - int i; - (void)d; - printf("element "); - for(i=0;i<l;i++) - putchar(name[i]); -} -void printeltname2(void * d, const char * name, int l) -{ - int i; - (void)d; - putchar('/'); - for(i=0;i<l;i++) - putchar(name[i]); - putchar('\n'); -} -void printdata(void *d, const char * data, int l) -{ - int i; - (void)d; - printf("data : "); - for(i=0;i<l;i++) - putchar(data[i]); - putchar('\n'); -} - -void burptest(const char * buffer, int bufsize) -{ - struct IGDdatas data; - struct xmlparser parser; - /*objet IGDdatas */ - memset(&data, 0, sizeof(struct IGDdatas)); - /* objet xmlparser */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = &data; - /*parser.starteltfunc = printeltname1; - parser.endeltfunc = printeltname2; - parser.datafunc = printdata; */ - parser.starteltfunc = IGDstartelt; - parser.endeltfunc = IGDendelt; - parser.datafunc = IGDdata; - parsexml(&parser); -#ifdef DEBUG - printIGD(&data); -#endif /* DEBUG */ -} - -/* ----- main ---- */ -#define XML_MAX_SIZE (8192) -int main(int argc, char * * argv) -{ - FILE * f; - char buffer[XML_MAX_SIZE]; - int bufsize; - if(argc<2) - { - printf("usage:\t%s file.xml\n", argv[0]); - return 1; - } - f = fopen(argv[1], "r"); - if(!f) - { - printf("cannot open file %s\n", argv[1]); - return 1; - } - bufsize = (int)fread(buffer, 1, XML_MAX_SIZE, f); - fclose(f); - burptest(buffer, bufsize); - return 0; -} - diff --git a/external/miniupnpc/testportlistingparse.c b/external/miniupnpc/testportlistingparse.c deleted file mode 100644 index bd9247dca..000000000 --- a/external/miniupnpc/testportlistingparse.c +++ /dev/null @@ -1,151 +0,0 @@ -/* $Id: testportlistingparse.c,v 1.2 2014/11/01 10:37:32 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard - * Copyright (c) 2014 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ - -#include <string.h> -#include <stdio.h> -#include "portlistingparse.h" - -struct port_mapping { - unsigned int leasetime; - unsigned short externalport; - unsigned short internalport; - const char * remotehost; - const char * client; - const char * proto; - const char * desc; - unsigned char enabled; -}; - -/* return the number of differences */ -int test(const char * portListingXml, int portListingXmlLen, - const struct port_mapping * ref, int count) -{ - int i; - int r = 0; - struct PortMappingParserData data; - struct PortMapping * pm; - - memset(&data, 0, sizeof(data)); - ParsePortListing(portListingXml, portListingXmlLen, &data); - for(i = 0, pm = data.l_head; - (pm != NULL) && (i < count); - i++, pm = pm->l_next) { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - if(0 != strcmp(pm->protocol, ref[i].proto)) { - printf("protocol : '%s' != '%s'\n", pm->protocol, ref[i].proto); - r++; - } - if(pm->externalPort != ref[i].externalport) { - printf("externalPort : %hu != %hu\n", - pm->externalPort, ref[i].externalport); - r++; - } - if(0 != strcmp(pm->internalClient, ref[i].client)) { - printf("client : '%s' != '%s'\n", - pm->internalClient, ref[i].client); - r++; - } - if(pm->internalPort != ref[i].internalport) { - printf("internalPort : %hu != %hu\n", - pm->internalPort, ref[i].internalport); - r++; - } - if(0 != strcmp(pm->description, ref[i].desc)) { - printf("description : '%s' != '%s'\n", - pm->description, ref[i].desc); - r++; - } - if(0 != strcmp(pm->remoteHost, ref[i].remotehost)) { - printf("remoteHost : '%s' != '%s'\n", - pm->remoteHost, ref[i].remotehost); - r++; - } - if((unsigned)pm->leaseTime != ref[i].leasetime) { - printf("leaseTime : %u != %u\n", - (unsigned)pm->leaseTime, ref[i].leasetime); - r++; - } - if(pm->enabled != ref[i].enabled) { - printf("enabled : %d != %d\n", - (int)pm->enabled, (int)ref[i].enabled); - r++; - } - } - if((i != count) || (pm != NULL)) { - printf("count mismatch : i=%d count=%d pm=%p\n", i, count, pm); - r++; - } - FreePortListing(&data); - return r; -} - -const char test_document[] = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<p:PortMappingList xmlns:p=\"urn:schemas-upnp-org:gw:WANIPConnection\"\n" -"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" -"xsi:schemaLocation=\"urn:schemas-upnp-org:gw:WANIPConnection " -"http://www.upnp.org/schemas/gw/WANIPConnection-v2.xsd\">\n" -" <p:PortMappingEntry>\n" -" <p:NewRemoteHost></p:NewRemoteHost>\n" -" <p:NewExternalPort>5002</p:NewExternalPort>\n" -" <p:NewProtocol>UDP</p:NewProtocol>\n" -" <p:NewInternalPort>4001</p:NewInternalPort>\n" -" <p:NewInternalClient>192.168.1.123</p:NewInternalClient>\n" -" <p:NewEnabled>1</p:NewEnabled>\n" -" <p:NewDescription>xxx</p:NewDescription>\n" -" <p:NewLeaseTime>0</p:NewLeaseTime>\n" -" </p:PortMappingEntry>\n" -" <p:PortMappingEntry>\n" -" <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>\n" -" <p:NewExternalPort>2345</p:NewExternalPort>\n" -" <p:NewProtocol>TCP</p:NewProtocol>\n" -" <p:NewInternalPort>2349</p:NewInternalPort>\n" -" <p:NewInternalClient>192.168.1.137</p:NewInternalClient>\n" -" <p:NewEnabled>1</p:NewEnabled>\n" -" <p:NewDescription>dooom</p:NewDescription>\n" -" <p:NewLeaseTime>346</p:NewLeaseTime>\n" -" </p:PortMappingEntry>\n" -" <p:PortMappingEntry>\n" -" <p:NewRemoteHost>134.231.2.11</p:NewRemoteHost>\n" -" <p:NewExternalPort>12345</p:NewExternalPort>\n" -" <p:NewProtocol>TCP</p:NewProtocol>\n" -" <p:NewInternalPort>12345</p:NewInternalPort>\n" -" <p:NewInternalClient>192.168.1.137</p:NewInternalClient>\n" -" <p:NewEnabled>1</p:NewEnabled>\n" -" <p:NewDescription>dooom A</p:NewDescription>\n" -" <p:NewLeaseTime>347</p:NewLeaseTime>\n" -" </p:PortMappingEntry>\n" -"</p:PortMappingList>"; - -#define PORT_MAPPINGS_COUNT 3 -const struct port_mapping port_mappings[PORT_MAPPINGS_COUNT] = { -{347, 12345, 12345, "134.231.2.11", "192.168.1.137", "TCP", "dooom A", 1}, -{346, 2345, 2349, "202.233.2.1", "192.168.1.137", "TCP", "dooom", 1}, -{0, 5002, 4001, "", "192.168.1.123", "UDP", "xxx", 1} -}; - -/* --- main --- */ -int main(void) -{ - int r; - r = test(test_document, sizeof(test_document) - 1, - port_mappings, PORT_MAPPINGS_COUNT); - if(r == 0) { - printf("test of portlistingparse OK\n"); - return 0; - } else { - printf("test FAILED (%d differences counted)\n", r); - return 1; - } -} - diff --git a/external/miniupnpc/testreplyparse/DeletePortMapping.namevalue b/external/miniupnpc/testreplyparse/DeletePortMapping.namevalue deleted file mode 100644 index 48ca0cccb..000000000 --- a/external/miniupnpc/testreplyparse/DeletePortMapping.namevalue +++ /dev/null @@ -1,3 +0,0 @@ -NewRemoteHost= -NewExternalPort=123 -NewProtocol=TCP diff --git a/external/miniupnpc/testreplyparse/DeletePortMapping.xml b/external/miniupnpc/testreplyparse/DeletePortMapping.xml deleted file mode 100644 index a955c53fc..000000000 --- a/external/miniupnpc/testreplyparse/DeletePortMapping.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:DeletePortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>123</NewExternalPort> -<NewProtocol>TCP</NewProtocol></u:DeletePortMapping></s:Body> - -</s:Envelope> - diff --git a/external/miniupnpc/testreplyparse/GetExternalIPAddress.namevalue b/external/miniupnpc/testreplyparse/GetExternalIPAddress.namevalue deleted file mode 100644 index 5aa75f882..000000000 --- a/external/miniupnpc/testreplyparse/GetExternalIPAddress.namevalue +++ /dev/null @@ -1,2 +0,0 @@ -NewExternalIPAddress=1.2.3.4 - diff --git a/external/miniupnpc/testreplyparse/GetExternalIPAddress.xml b/external/miniupnpc/testreplyparse/GetExternalIPAddress.xml deleted file mode 100644 index db7ec1f9c..000000000 --- a/external/miniupnpc/testreplyparse/GetExternalIPAddress.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewExternalIPAddress>1.2.3.4</NewExternalIPAddress></u:GetExternalIPAddressResponse></s:Body></s:Envelope> - diff --git a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.namevalue b/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.namevalue deleted file mode 100644 index 26b169c35..000000000 --- a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.namevalue +++ /dev/null @@ -1,3 +0,0 @@ -NewProtocol=UDP -NewExternalPort=12345 -NewRemoteHost= diff --git a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.xml b/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.xml deleted file mode 100644 index bbb540eac..000000000 --- a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryReq.xml +++ /dev/null @@ -1,3 +0,0 @@ -<?xml version="1.0"?> -<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetSpecificPortMappingEntry xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>12345</NewExternalPort><NewProtocol>UDP</NewProtocol></u:GetSpecificPortMappingEntry></s:Body></s:Envelope> - diff --git a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.namevalue b/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.namevalue deleted file mode 100644 index 2189789b4..000000000 --- a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.namevalue +++ /dev/null @@ -1,5 +0,0 @@ -NewInternalPort=12345 -NewInternalClient=192.168.10.110 -NewEnabled=1 -NewPortMappingDescription=libminiupnpc -NewLeaseDuration=0 diff --git a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.xml b/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.xml deleted file mode 100644 index 77e8d9c7c..000000000 --- a/external/miniupnpc/testreplyparse/GetSpecificPortMappingEntryResp.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetSpecificPortMappingEntryResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewInternalPort>12345</NewInternalPort><NewInternalClient>192.168.10.110</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>libminiupnpc</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:GetSpecificPortMappingEntryResponse></s:Body></s:Envelope> - diff --git a/external/miniupnpc/testreplyparse/SetDefaultConnectionService.namevalue b/external/miniupnpc/testreplyparse/SetDefaultConnectionService.namevalue deleted file mode 100644 index f78c7e2ae..000000000 --- a/external/miniupnpc/testreplyparse/SetDefaultConnectionService.namevalue +++ /dev/null @@ -1 +0,0 @@ -NewDefaultConnectionService=uuid:c6c05a33-f704-48df-9910-e099b3471d81:WANConnectionDevice:1,INVALID_SERVICE_ID diff --git a/external/miniupnpc/testreplyparse/SetDefaultConnectionService.xml b/external/miniupnpc/testreplyparse/SetDefaultConnectionService.xml deleted file mode 100644 index ac04c07a9..000000000 --- a/external/miniupnpc/testreplyparse/SetDefaultConnectionService.xml +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:SetDefaultConnectionService xmlns:u="urn:schemas-upnp-org:service:Layer3Forwarding:1"><NewDefaultConnectionService>uuid:c6c05a33-f704-48df-9910-e099b3471d81:WANConnectionDevice:1,INVALID_SERVICE_ID</NewDefaultConnectionService></u:SetDefaultConnectionService></s:Body></s:Envelope> diff --git a/external/miniupnpc/testreplyparse/readme.txt b/external/miniupnpc/testreplyparse/readme.txt deleted file mode 100644 index 3eb1f015f..000000000 --- a/external/miniupnpc/testreplyparse/readme.txt +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains files used for validation of upnpreplyparse.c code. - -Each .xml file to parse should give the results which are in the .namevalue -file. - -A .namevalue file contain name=value lines. - diff --git a/external/miniupnpc/testupnpigd.py b/external/miniupnpc/testupnpigd.py deleted file mode 100755 index 33019bd99..000000000 --- a/external/miniupnpc/testupnpigd.py +++ /dev/null @@ -1,88 +0,0 @@ -#! /usr/bin/python -# $Id: testupnpigd.py,v 1.4 2008/10/11 10:27:20 nanard Exp $ -# MiniUPnP project -# Author : Thomas Bernard -# This Sample code is public domain. -# website : http://miniupnp.tuxfamily.org/ - -# import the python miniupnpc module -import miniupnpc -import socket - -try: - from http.server import BaseHTTPRequestHandler, HTTPServer -except ImportError: - from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer - -# function definition -def list_redirections(): - i = 0 - while True: - p = u.getgenericportmapping(i) - if p==None: - break - print(i, p) - i = i + 1 - -#define the handler class for HTTP connections -class handler_class(BaseHTTPRequestHandler): - def do_GET(self): - self.send_response(200) - self.end_headers() - self.wfile.write("OK MON GARS") - -# create the object -u = miniupnpc.UPnP() -#print 'inital(default) values :' -#print ' discoverdelay', u.discoverdelay -#print ' lanaddr', u.lanaddr -#print ' multicastif', u.multicastif -#print ' minissdpdsocket', u.minissdpdsocket -u.discoverdelay = 200; - -try: - print('Discovering... delay=%ums' % u.discoverdelay) - ndevices = u.discover() - print(ndevices, 'device(s) detected') - - # select an igd - u.selectigd() - # display information about the IGD and the internet connection - print('local ip address :', u.lanaddr) - externalipaddress = u.externalipaddress() - print('external ip address :', externalipaddress) - print(u.statusinfo(), u.connectiontype()) - - #instanciate a HTTPd object. The port is assigned by the system. - httpd = HTTPServer((u.lanaddr, 0), handler_class) - eport = httpd.server_port - - # find a free port for the redirection - r = u.getspecificportmapping(eport, 'TCP') - while r != None and eport < 65536: - eport = eport + 1 - r = u.getspecificportmapping(eport, 'TCP') - - print('trying to redirect %s port %u TCP => %s port %u TCP' % (externalipaddress, eport, u.lanaddr, httpd.server_port)) - - b = u.addportmapping(eport, 'TCP', u.lanaddr, httpd.server_port, - 'UPnP IGD Tester port %u' % eport, '') - if b: - print('Success. Now waiting for some HTTP request on http://%s:%u' % (externalipaddress ,eport)) - try: - httpd.handle_request() - httpd.server_close() - except KeyboardInterrupt as details: - print("CTRL-C exception!", details) - b = u.deleteportmapping(eport, 'TCP') - if b: - print('Successfully deleted port mapping') - else: - print('Failed to remove port mapping') - else: - print('Failed') - - httpd.server_close() - -except Exception as e: - print('Exception :', e) diff --git a/external/miniupnpc/testupnpreplyparse.c b/external/miniupnpc/testupnpreplyparse.c deleted file mode 100644 index 7ba7131ea..000000000 --- a/external/miniupnpc/testupnpreplyparse.c +++ /dev/null @@ -1,96 +0,0 @@ -/* $Id: testupnpreplyparse.c,v 1.4 2014/01/27 11:45:19 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2014 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "upnpreplyparse.h" - -int -test_parsing(const char * buf, int len, FILE * f) -{ - char line[1024]; - struct NameValueParserData pdata; - int ok = 1; - ParseNameValue(buf, len, &pdata); - /* check result */ - if(f != NULL) - { - while(fgets(line, sizeof(line), f)) - { - char * value; - char * equal; - char * parsedvalue; - int l; - l = strlen(line); - while((l > 0) && ((line[l-1] == '\r') || (line[l-1] == '\n'))) - line[--l] = '\0'; - /* skip empty lines */ - if(l == 0) - continue; - equal = strchr(line, '='); - if(equal == NULL) - { - fprintf(stderr, "Warning, line does not contain '=' : %s\n", line); - continue; - } - *equal = '\0'; - value = equal + 1; - parsedvalue = GetValueFromNameValueList(&pdata, line); - if((parsedvalue == NULL) || (strcmp(parsedvalue, value) != 0)) - { - fprintf(stderr, "Element <%s> : expecting value '%s', got '%s'\n", - line, value, parsedvalue ? parsedvalue : "<null string>"); - ok = 0; - } - } - } - ClearNameValueList(&pdata); - return ok; -} - -int main(int argc, char * * argv) -{ - FILE * f; - char buffer[4096]; - int l; - int ok; - - if(argc<2) - { - fprintf(stderr, "Usage: %s file.xml [file.namevalues]\n", argv[0]); - return 1; - } - f = fopen(argv[1], "r"); - if(!f) - { - fprintf(stderr, "Error : can not open file %s\n", argv[1]); - return 2; - } - l = fread(buffer, 1, sizeof(buffer)-1, f); - fclose(f); - f = NULL; - buffer[l] = '\0'; - if(argc > 2) - { - f = fopen(argv[2], "r"); - if(!f) - { - fprintf(stderr, "Error : can not open file %s\n", argv[2]); - return 2; - } - } -#ifdef DEBUG - DisplayNameValueList(buffer, l); -#endif - ok = test_parsing(buffer, l, f); - if(f) - { - fclose(f); - } - return ok ? 0 : 3; -} - diff --git a/external/miniupnpc/testupnpreplyparse.sh b/external/miniupnpc/testupnpreplyparse.sh deleted file mode 100755 index 992930b7b..000000000 --- a/external/miniupnpc/testupnpreplyparse.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -for f in testreplyparse/*.xml ; do - bf="`dirname $f`/`basename $f .xml`" - if ./testupnpreplyparse $f $bf.namevalue ; then - echo "$f : passed" - else - echo "$f : FAILED" - exit 1 - fi -done - -exit 0 - diff --git a/external/miniupnpc/updateminiupnpcstrings.sh b/external/miniupnpc/updateminiupnpcstrings.sh deleted file mode 100755 index dde4354a8..000000000 --- a/external/miniupnpc/updateminiupnpcstrings.sh +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/sh -# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $ -# project miniupnp : http://miniupnp.free.fr/ -#Â (c) 2009 Thomas Bernard - -FILE=miniupnpcstrings.h -TMPFILE=miniupnpcstrings.h.tmp -TEMPLATE_FILE=${FILE}.in - -# detecting the OS name and version -OS_NAME=`uname -s` -OS_VERSION=`uname -r` -if [ -f /etc/debian_version ]; then - OS_NAME=Debian - OS_VERSION=`cat /etc/debian_version` -fi -# use lsb_release (Linux Standard Base) when available -LSB_RELEASE=`which lsb_release` -if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then - OS_NAME=`${LSB_RELEASE} -i -s` - OS_VERSION=`${LSB_RELEASE} -r -s` - case $OS_NAME in - Debian) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - Ubuntu) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - esac -fi - -# on AmigaOS 3, uname -r returns "unknown", so we use uname -v -if [ "$OS_NAME" = "AmigaOS" ]; then - if [ "$OS_VERSION" = "unknown" ]; then - OS_VERSION=`uname -v` - fi -fi - -echo "Detected OS [$OS_NAME] version [$OS_VERSION]" -MINIUPNPC_VERSION=`cat VERSION` -echo "MiniUPnPc version [${MINIUPNPC_VERSION}]" - -EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|" -#echo $EXPR -test -f ${FILE}.in -echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE." -sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE - -EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|" -echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE." -sed -e "$EXPR" < $TMPFILE > $FILE -rm $TMPFILE - diff --git a/external/miniupnpc/upnpc.c b/external/miniupnpc/upnpc.c deleted file mode 100644 index e719ecec5..000000000 --- a/external/miniupnpc/upnpc.c +++ /dev/null @@ -1,857 +0,0 @@ -/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#ifdef _WIN32 -#include <winsock2.h> -#define snprintf _snprintf -#else -/* for IPPROTO_TCP / IPPROTO_UDP */ -#include <netinet/in.h> -#endif -#include <ctype.h> -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" -#include "miniupnpcstrings.h" - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; - int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) - return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) - return proto_udp; - return 0; -} - -/* is_int() checks if parameter is an integer or not - * 1 for integer - * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) - return 0; - while(*s) { - /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) - return 0; - s++; - } - return 1; -} - -static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime = 0; - unsigned int brUp, brDown; - time_t timenow, timestarted; - int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) - printf("GetConnectionTypeInfo failed.\n"); - else - printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) - printf("GetStatusInfo failed.\n"); - else - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); - if(uptime > 0) { - timenow = time(NULL); - timestarted = timenow - uptime; - printf(" Time started : %s", ctime(×tarted)); - } - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { - printf("GetLinkLayerMaxBitRates failed.\n"); - } else { - printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { - printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { - printf(" (%u Kbps)", brDown / 1000); - } - printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { - printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { - printf(" (%u Kbps)", brUp / 1000); - } - printf("\n"); - } - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { - printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); - } else { - printf("ExternalIPAddress = %s\n", externalIPAddress); - } -} - -static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; - /*unsigned int num=0; - UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); - printf("PortMappingNumberOfEntries : %u\n", num);*/ - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - do { - snprintf(index, 6, "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - struct PortMappingParserData pdata; - struct PortMapping * pm; - - memset(&pdata, 0, sizeof(struct PortMappingParserData)); - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 4 - get this port mapping from the IGD */ -static int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char reservedPort[6]; - char duration[16]; - int r; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return -1; - } - - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress failed.\n"); - else - printf("ExternalIPAddress = %s\n", externalIPAddress); - - if (addAny) { - r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) - eport = reservedPort; - else - printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - } else { - r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - return -2; - } - } - - r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, NULL/*remoteHost*/, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); - return -2; - } else { - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); - } - return 0; -} - -static int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ - int r; - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMapping() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMapping() returned : %d\n", r); - } - return 0; -} - -static int -RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ - int r; - - if (!manage) - manage = "0"; - - if(!proto || !ePortStart || !ePortEnd) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); - } - return 0; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - int firewallEnabled = 0, inboundPinholeAllowed = 0; - - UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); - printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); - - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -/* Test function - * 1 - Add pinhole - * 2 - Check if pinhole is working from the IGD side */ -static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ - char uniqueID[8]; - /*int isWorking = 0;*/ - int r; - char proto_tmp[8]; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - if(atoi(proto) == 0) - { - const char * protocol; - protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); - proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); - proto = proto_tmp; - } - else - { - fprintf(stderr, "invalid protocol\n"); - return; - } - } - r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); - /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/ - } -} - -/* Test function - * 1 - Check if pinhole is working from the IGD side - * 2 - Update pinhole */ -static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ - int isWorking = 0; - int r; - - if(!uniqueID || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { - r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); - printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) - printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); - } -} - -/* Test function - * Get pinhole timeout - */ -static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ - int timeout = 0; - int r; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - - r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); - else - printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); -} - -static void -GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, pinholePackets = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); -} - -static void -CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, isWorking = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); -} - -static void -RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID); - printf("UPNP_DeletePinhole() returned : %d\n", r); -} - - -/* sample upnp client program */ -int main(int argc, char ** argv) -{ - char command = 0; - char ** commandargv = 0; - int commandargc = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64] = "unset"; /* my ip address on the LAN */ - int i; - const char * rootdescurl = 0; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int localport = UPNP_LOCAL_PORT_ANY; - int retcode = 0; - int error = 0; - int ipv6 = 0; - unsigned char ttl = 2; /* defaulting to 2 */ - const char * description = 0; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2017 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" - "for more information.\n"); - /* command line processing */ - for(i=1; i<argc; i++) - { - if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h")) - { - command = 0; - break; - } - if(argv[i][0] == '-') - { - if(argv[i][1] == 'u') - rootdescurl = argv[++i]; - else if(argv[i][1] == 'm') - multicastif = argv[++i]; - else if(argv[i][1] == 'z') - { - char junk; - if(sscanf(argv[++i], "%d%c", &localport, &junk)!=1 || - localport<0 || localport>65535 || - (localport >1 && localport < 1024)) - { - fprintf(stderr, "Invalid localport '%s'\n", argv[i]); - localport = UPNP_LOCAL_PORT_ANY; - break; - } - } - else if(argv[i][1] == 'p') - minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') - ipv6 = 1; - else if(argv[i][1] == 'e') - description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { - command = argv[i][1]; - i++; - commandargv = argv + i; - commandargc = argc - i; - break; - } - } - else - { - fprintf(stderr, "option '%s' invalid\n", argv[i]); - } - } - - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { - fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol <remote host>\n\t\tDelete port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); - fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); - fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); - fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); - fprintf(stderr, "\nprotocol is UDP or TCP\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -e description : set description for port mapping.\n"); - fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); - fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); - fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); - fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n"); - fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); - fprintf(stderr, " -t ttl : set multicast TTL. Default value is 2.\n"); - return 1; - } - - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { - struct UPNPDev * device; - struct UPNPUrls urls; - struct IGDdatas data; - if(devlist) - { - printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { - printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); - } - } - else if(!rootdescurl) - { - printf("upnpDiscover() error code=%d\n", error); - } - i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - } - printf("Local LAN ip address : %s\n", lanaddr); - #if 0 - printf("getting \"%s\"\n", urls.ipcondescURL); - descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { - /*fwrite(descXML, 1, descXMLsize, stdout);*/ - free(descXML); descXML = NULL; - } - #endif - - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 0) < 0) - retcode = 2; - break; - case 'd': - if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL) < 0) - retcode = 2; - break; - case 'n': /* aNy */ - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 1) < 0) - retcode = 2; - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); - - if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL) < 0) - retcode = 2; - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i<commandargc) - { - if(!is_int(commandargv[i])) { - /* 1st parameter not an integer : error */ - fprintf(stderr, "command -r : %s is not an port number\n", commandargv[i]); - retcode = 1; - break; - } else if(is_int(commandargv[i+1])){ - /* 2nd parameter is an integer : <port> <external_port> <protocol> */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", - description, 0) < 0) - retcode = 2; - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : <port> <protocol> */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", - description, 0) < 0) - retcode = 2; - i+=2; /* 2 parameters parsed */ - } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; i<commandargc; i++) - { - CheckPinhole(&urls, &data, commandargv[i]); - } - break; - case 'K': - for(i=0; i<commandargc; i++) - { - GetPinholePackets(&urls, &data, commandargv[i]); - } - break; - case 'D': - for(i=0; i<commandargc; i++) - { - RemovePinhole(&urls, &data, commandargv[i]); - } - break; - case 'S': - GetFirewallStatus(&urls, &data); - break; - case 'G': - GetPinholeOutboundTimeout(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4]); - break; - case 'P': - printf("Presentation URL found:\n"); - printf(" %s\n", data.presentationurl); - break; - default: - fprintf(stderr, "Unknown switch -%c\n", command); - retcode = 1; - } - - FreeUPNPUrls(&urls); - } - else - { - fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n"); - retcode = 1; - } - freeUPNPDevlist(devlist); devlist = 0; - } - else - { - fprintf(stderr, "No IGD UPnP Device found on the network !\n"); - retcode = 1; - } -#ifdef _WIN32 - nResult = WSACleanup(); - if(nResult != NO_ERROR) { - fprintf(stderr, "WSACleanup() failed.\n"); - } -#endif /* _WIN32 */ - return retcode; -} - diff --git a/external/miniupnpc/upnpcommands.c b/external/miniupnpc/upnpcommands.c deleted file mode 100644 index 9f704496f..000000000 --- a/external/miniupnpc/upnpcommands.c +++ /dev/null @@ -1,1240 +0,0 @@ -/* $Id: upnpcommands.c,v 1.46 2015/07/15 12:19:00 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2017 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "upnpcommands.h" -#include "miniupnpc.h" -#include "portlistingparse.h" - -static UNSIGNED_INTEGER -my_atoui(const char * s) -{ - return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* UPNP_GetStatusInfo() call the corresponding UPNP method - * returns the current status and uptime */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - char * up; - char * err; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!status && !uptime) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetStatusInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - up = GetValueFromNameValueList(&pdata, "NewUptime"); - p = GetValueFromNameValueList(&pdata, "NewConnectionStatus"); - err = GetValueFromNameValueList(&pdata, "NewLastConnectionError"); - if(p && up) - ret = UPNPCOMMAND_SUCCESS; - - if(status) { - if(p){ - strncpy(status, p, 64 ); - status[63] = '\0'; - }else - status[0]= '\0'; - } - - if(uptime) { - if(up) - sscanf(up,"%u",uptime); - else - *uptime = 0; - } - - if(lastconnerror) { - if(err) { - strncpy(lastconnerror, err, 64 ); - lastconnerror[63] = '\0'; - } else - lastconnerror[0] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method - * returns the connection type */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!connectionType) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetConnectionTypeInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewConnectionType"); - /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/ - /* PossibleConnectionTypes will have several values.... */ - if(p) { - strncpy(connectionType, p, 64 ); - connectionType[63] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - connectionType[0] = '\0'; - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. - * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. - * One of the values can be null - * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only - * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char * controlURL, - const char * servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - char * down; - char * up; - char * p; - - if(!bitrateDown && !bitrateUp) - return UPNPCOMMAND_INVALID_ARGS; - - /* shouldn't we use GetCommonLinkProperties ? */ - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetCommonLinkProperties", 0, &bufsize))) { - /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/ - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/ - /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/ - down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate"); - up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate"); - /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/ - /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/ - if(down && up) - ret = UPNPCOMMAND_SUCCESS; - - if(bitrateDown) { - if(down) - sscanf(down,"%u",bitrateDown); - else - *bitrateDown = 0; - } - - if(bitrateUp) { - if(up) - sscanf(up,"%u",bitrateUp); - else - *bitrateUp = 0; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!extIpAdd || !controlURL || !servicetype) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetExternalIPAddress", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/ - p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress"); - if(p) { - strncpy(extIpAdd, p, 16 ); - extIpAdd[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - extIpAdd[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - /*buffer[bufsize] = '\0';*/ - /*puts(buffer);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddAnyPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - char *p; - - p = GetValueFromNameValueList(&pdata, "NewReservedPort"); - if(p) { - strncpy(reservedPort, p, 6); - reservedPort[5] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else { - ret = UPNPCOMMAND_INVALID_RESPONSE; - } - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewRemoteHost"; - DeletePortMappingArgs[0].val = remoteHost; - DeletePortMappingArgs[1].elt = "NewExternalPort"; - DeletePortMappingArgs[1].val = extPort; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMapping", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage) -{ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPortStart || !extPortEnd || !proto || !manage) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewStartPort"; - DeletePortMappingArgs[0].val = extPortStart; - DeletePortMappingArgs[1].elt = "NewEndPort"; - DeletePortMappingArgs[1].val = extPortEnd; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - DeletePortMappingArgs[3].elt = "NewManage"; - DeletePortMappingArgs[3].val = manage; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMappingRange", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int r = UPNPCOMMAND_UNKNOWN_ERROR; - if(!index) - return UPNPCOMMAND_INVALID_ARGS; - intClient[0] = '\0'; - intPort[0] = '\0'; - GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewPortMappingIndex"; - GetPortMappingArgs[0].val = index; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetGenericPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); - if(p && rHost) - { - strncpy(rHost, p, 64); - rHost[63] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewExternalPort"); - if(p && extPort) - { - strncpy(extPort, p, 6); - extPort[5] = '\0'; - r = UPNPCOMMAND_SUCCESS; - } - p = GetValueFromNameValueList(&pdata, "NewProtocol"); - if(p && protocol) - { - strncpy(protocol, p, 4); - protocol[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) - { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - r = 0; - } - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) - { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) - { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) - { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && duration) - { - strncpy(duration, p, 16); - duration[15] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - r = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &r); - } - ClearNameValueList(&pdata); - return r; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char * controlURL, - const char * servicetype, - unsigned int * numEntries) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char* p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPortMappingNumberOfEntries", 0, - &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } -#ifdef DEBUG - DisplayNameValueList(buffer, bufsize); -#endif - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); - if(numEntries && p) { - *numEntries = 0; - sscanf(p, "%u", numEntries); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping - * the result is returned in the intClient and intPort strings - * please provide 16 and 6 bytes of data */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!intPort || !intClient || !extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewRemoteHost"; - GetPortMappingArgs[0].val = remoteHost; - GetPortMappingArgs[1].elt = "NewExternalPort"; - GetPortMappingArgs[1].val = extPort; - GetPortMappingArgs[2].elt = "NewProtocol"; - GetPortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetSpecificPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - intClient[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } else - intPort[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && leaseDuration) - { - strncpy(leaseDuration, p, 16); - leaseDuration[15] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetListOfPortMappings() - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data) -{ - struct NameValueParserData pdata; - struct UPNParg * GetListOfPortMappingsArgs; - const char * p; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!startPort || !endPort || !protocol) - return UPNPCOMMAND_INVALID_ARGS; - - GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg)); - if(GetListOfPortMappingsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetListOfPortMappingsArgs[0].elt = "NewStartPort"; - GetListOfPortMappingsArgs[0].val = startPort; - GetListOfPortMappingsArgs[1].elt = "NewEndPort"; - GetListOfPortMappingsArgs[1].val = endPort; - GetListOfPortMappingsArgs[2].elt = "NewProtocol"; - GetListOfPortMappingsArgs[2].val = protocol; - GetListOfPortMappingsArgs[3].elt = "NewManage"; - GetListOfPortMappingsArgs[3].val = "1"; - GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; - GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetListOfPortMappings", - GetListOfPortMappingsArgs, &bufsize); - free(GetListOfPortMappingsArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/ - /*if(p) { - printf("NewPortListing : %s\n", p); - }*/ - /*printf("NewPortListing(%d chars) : %s\n", - pdata.portListingLength, pdata.portListing);*/ - if(pdata.portListing) - { - /*struct PortMapping * pm; - int i = 0;*/ - ParsePortListing(pdata.portListing, pdata.portListingLength, - data); - ret = UPNPCOMMAND_SUCCESS; - /* - for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost); - i++; - } - */ - /*FreePortListing(&data);*/ - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - - /*printf("%.*s", bufsize, buffer);*/ - - return ret; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * fe, *ipa, *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!firewallEnabled || !inboundPinholeAllowed) - return UPNPCOMMAND_INVALID_ARGS; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetFirewallStatus", 0, &bufsize); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - fe = GetValueFromNameValueList(&pdata, "FirewallEnabled"); - ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed"); - if(ipa && fe) - ret = UPNPCOMMAND_SUCCESS; - if(fe) - *firewallEnabled = my_atoui(fe); - /*else - *firewallEnabled = 0;*/ - if(ipa) - *inboundPinholeAllowed = my_atoui(ipa); - /*else - *inboundPinholeAllowed = 0;*/ - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout) -{ - struct UPNParg * GetOutboundPinholeTimeoutArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remotePort || !remoteHost) - return UPNPCOMMAND_INVALID_ARGS; - - GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg)); - if(GetOutboundPinholeTimeoutArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost"; - GetOutboundPinholeTimeoutArgs[0].val = remoteHost; - GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort"; - GetOutboundPinholeTimeoutArgs[1].val = remotePort; - GetOutboundPinholeTimeoutArgs[2].elt = "Protocol"; - GetOutboundPinholeTimeoutArgs[2].val = proto; - GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort"; - GetOutboundPinholeTimeoutArgs[3].val = intPort; - GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient"; - GetOutboundPinholeTimeoutArgs[4].val = intClient; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); - free(GetOutboundPinholeTimeoutArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); - if(p) - *opTimeout = my_atoui(p); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID) -{ - struct UPNParg * AddPinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); - if(AddPinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - /* RemoteHost can be wilcarded */ - if(strncmp(remoteHost, "empty", 5)==0) - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = ""; - } - else - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = remoteHost; - } - AddPinholeArgs[1].elt = "RemotePort"; - AddPinholeArgs[1].val = remotePort; - AddPinholeArgs[2].elt = "Protocol"; - AddPinholeArgs[2].val = proto; - AddPinholeArgs[3].elt = "InternalPort"; - AddPinholeArgs[3].val = intPort; - if(strncmp(intClient, "empty", 5)==0) - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = ""; - } - else - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = intClient; - } - AddPinholeArgs[5].elt = "LeaseTime"; - AddPinholeArgs[5].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPinhole", AddPinholeArgs, &bufsize); - free(AddPinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "UniqueID"); - if(p) - { - strncpy(uniqueID, p, 8); - uniqueID[7] = '\0'; - } - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime) -{ - struct UPNParg * UpdatePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg)); - if(UpdatePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - UpdatePinholeArgs[0].elt = "UniqueID"; - UpdatePinholeArgs[0].val = uniqueID; - UpdatePinholeArgs[1].elt = "NewLeaseTime"; - UpdatePinholeArgs[1].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "UpdatePinhole", UpdatePinholeArgs, &bufsize); - free(UpdatePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePinholeArgs = calloc(2, sizeof(struct UPNParg)); - if(DeletePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePinholeArgs[0].elt = "UniqueID"; - DeletePinholeArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePinhole", DeletePinholeArgs, &bufsize); - free(DeletePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking) -{ - struct NameValueParserData pdata; - struct UPNParg * CheckPinholeWorkingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg)); - if(CheckPinholeWorkingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - CheckPinholeWorkingArgs[0].elt = "UniqueID"; - CheckPinholeWorkingArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); - free(CheckPinholeWorkingArgs); - if(!buffer) - { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "IsWorking"); - if(p) - { - *isWorking=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - else - *isWorking = 0; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPinholePacketsArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPinholePacketsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPinholePacketsArgs[0].elt = "UniqueID"; - GetPinholePacketsArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPinholePackets", GetPinholePacketsArgs, &bufsize); - free(GetPinholePacketsArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "PinholePackets"); - if(p) - { - *packets=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - - diff --git a/external/miniupnpc/upnpcommands.h b/external/miniupnpc/upnpcommands.h deleted file mode 100644 index 55b7b060d..000000000 --- a/external/miniupnpc/upnpcommands.h +++ /dev/null @@ -1,348 +0,0 @@ -/* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */ -/* Miniupnp project : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided within this distribution */ -#ifndef UPNPCOMMANDS_H_INCLUDED -#define UPNPCOMMANDS_H_INCLUDED - -#include "upnpreplyparse.h" -#include "portlistingparse.h" -#include "miniupnpc_declspec.h" -#include "miniupnpctypes.h" - -/* MiniUPnPc return codes : */ -#define UPNPCOMMAND_SUCCESS (0) -#define UPNPCOMMAND_UNKNOWN_ERROR (-1) -#define UPNPCOMMAND_INVALID_ARGS (-2) -#define UPNPCOMMAND_HTTP_ERROR (-3) -#define UPNPCOMMAND_INVALID_RESPONSE (-4) -#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5) - -#ifdef __cplusplus -extern "C" { -#endif - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype); - -/* UPNP_GetStatusInfo() - * status and lastconnerror are 64 byte buffers - * Return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror); - -/* UPNP_GetConnectionTypeInfo() - * argument connectionType is a 64 character buffer - * Return Values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType); - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * possible UPnP Errors : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd); - -/* UPNP_GetLinkLayerMaxBitRates() - * call WANCommonInterfaceConfig:1#GetCommonLinkProperties - * - * return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char* controlURL, - const char* servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp); - -/* UPNP_AddPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 718 ConflictInMappingEntry - The port mapping entry specified conflicts - * with a mapping assigned previously to another client - * 724 SamePortValuesRequired - Internal and External port values - * must be the same - * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports - * permanent lease times on port mappings - * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard - * and cannot be a specific IP address or DNS name - * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and - * cannot be a specific port value - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration); - -/* UPNP_AddAnyPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort); - -/* UPNP_DeletePortMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost); - -/* UPNP_DeletePortRangeMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 730 PortMappingNotFound - This error message is returned if no port - * mapping is found in the specified range. - * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage); - -/* UPNP_GetPortMappingNumberOfEntries() - * not supported by all routers */ -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char* controlURL, - const char* servicetype, - unsigned int * num); - -/* UPNP_GetSpecificPortMappingEntry() - * retrieves an existing port mapping - * params : - * in extPort - * in proto - * in remoteHost - * out intClient (16 bytes) - * out intPort (6 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out leaseDuration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * List of possible UPnP errors for _GetSpecificPortMappingEntry : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array. - */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration); - -/* UPNP_GetGenericPortMappingEntry() - * params : - * in index - * out extPort (6 bytes) - * out intClient (16 bytes) - * out intPort (6 bytes) - * out protocol (4 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out rHost (64 bytes) - * out duration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * Possible UPNP Error codes : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds - */ -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration); - -/* UPNP_GetListOfPortMappings() Available in IGD v2 - * - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data); - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed); - -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout); - -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID); - -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime); - -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); - -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking); - -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/miniupnpc/upnpdev.c b/external/miniupnpc/upnpdev.c deleted file mode 100644 index d89a9934c..000000000 --- a/external/miniupnpc/upnpdev.c +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#include <stdlib.h> -#include "upnpdev.h" - -/* freeUPNPDevlist() should be used to - * free the chained list returned by upnpDiscover() */ -void freeUPNPDevlist(struct UPNPDev * devlist) -{ - struct UPNPDev * next; - while(devlist) - { - next = devlist->pNext; - free(devlist); - devlist = next; - } -} - diff --git a/external/miniupnpc/upnpdev.h b/external/miniupnpc/upnpdev.h deleted file mode 100644 index f49fbe17c..000000000 --- a/external/miniupnpc/upnpdev.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#ifndef UPNPDEV_H_INCLUDED -#define UPNPDEV_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct UPNPDev { - struct UPNPDev * pNext; - char * descURL; - char * st; - unsigned int scope_id; - char * usn; - char buffer[3]; -}; - -/* freeUPNPDevlist() - * free list returned by upnpDiscover() */ -MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); - - -#ifdef __cplusplus -} -#endif - - -#endif /* UPNPDEV_H_INCLUDED */ diff --git a/external/miniupnpc/upnperrors.c b/external/miniupnpc/upnperrors.c deleted file mode 100644 index 40a2e7857..000000000 --- a/external/miniupnpc/upnperrors.c +++ /dev/null @@ -1,107 +0,0 @@ -/* $Id: upnperrors.c,v 1.5 2011/04/10 11:19:36 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2007 Thomas Bernard - * All Right reserved. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include <string.h> -#include "upnperrors.h" -#include "upnpcommands.h" -#include "miniupnpc.h" - -const char * strupnperror(int err) -{ - const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "WildcardNotPermittedInSrcIP"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; - } - return s; -} diff --git a/external/miniupnpc/upnperrors.h b/external/miniupnpc/upnperrors.h deleted file mode 100644 index 8499d9a1c..000000000 --- a/external/miniupnpc/upnperrors.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */ -/* (c) 2007-2015 Thomas Bernard - * All rights reserved. - * MiniUPnP Project. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef UPNPERRORS_H_INCLUDED -#define UPNPERRORS_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* strupnperror() - * Return a string description of the UPnP error code - * or NULL for undefinded errors */ -MINIUPNP_LIBSPEC const char * strupnperror(int err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/external/miniupnpc/upnpreplyparse.c b/external/miniupnpc/upnpreplyparse.c deleted file mode 100644 index 5de5796a3..000000000 --- a/external/miniupnpc/upnpreplyparse.c +++ /dev/null @@ -1,197 +0,0 @@ -/* $Id: upnpreplyparse.c,v 1.19 2015/07/15 10:29:11 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2015 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -#include "upnpreplyparse.h" -#include "minixml.h" - -static void -NameValueParserStartElt(void * d, const char * name, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - data->topelt = 1; - if(l>63) - l = 63; - memcpy(data->curelt, name, l); - data->curelt[l] = '\0'; - data->cdata = NULL; - data->cdatalen = 0; -} - -static void -NameValueParserEndElt(void * d, const char * name, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - struct NameValue * nv; - (void)name; - (void)l; - if(!data->topelt) - return; - if(strcmp(data->curelt, "NewPortListing") != 0) - { - int l; - /* standard case. Limited to n chars strings */ - l = data->cdatalen; - nv = malloc(sizeof(struct NameValue)); - if(nv == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserEndElt"); -#endif /* DEBUG */ - return; - } - if(l>=(int)sizeof(nv->value)) - l = sizeof(nv->value) - 1; - strncpy(nv->name, data->curelt, 64); - nv->name[63] = '\0'; - if(data->cdata != NULL) - { - memcpy(nv->value, data->cdata, l); - nv->value[l] = '\0'; - } - else - { - nv->value[0] = '\0'; - } - nv->l_next = data->l_head; /* insert in list */ - data->l_head = nv; - } - data->cdata = NULL; - data->cdatalen = 0; - data->topelt = 0; -} - -static void -NameValueParserGetData(void * d, const char * datas, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - if(strcmp(data->curelt, "NewPortListing") == 0) - { - /* specific case for NewPortListing which is a XML Document */ - data->portListing = malloc(l + 1); - if(!data->portListing) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserGetData"); -#endif /* DEBUG */ - return; - } - memcpy(data->portListing, datas, l); - data->portListing[l] = '\0'; - data->portListingLength = l; - } - else - { - /* standard case. */ - data->cdata = datas; - data->cdatalen = l; - } -} - -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data) -{ - struct xmlparser parser; - data->l_head = NULL; - data->portListing = NULL; - data->portListingLength = 0; - /* init xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = NameValueParserStartElt; - parser.endeltfunc = NameValueParserEndElt; - parser.datafunc = NameValueParserGetData; - parser.attfunc = 0; - parsexml(&parser); -} - -void -ClearNameValueList(struct NameValueParserData * pdata) -{ - struct NameValue * nv; - if(pdata->portListing) - { - free(pdata->portListing); - pdata->portListing = NULL; - pdata->portListingLength = 0; - } - while((nv = pdata->l_head) != NULL) - { - pdata->l_head = nv->l_next; - free(nv); - } -} - -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - for(nv = pdata->l_head; - (nv != NULL) && (p == NULL); - nv = nv->l_next) - { - if(strcmp(nv->name, Name) == 0) - p = nv->value; - } - return p; -} - -#if 0 -/* useless now that minixml ignores namespaces by itself */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - char * pname; - for(nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); - nv = nv->entries.le_next) - { - pname = strrchr(nv->name, ':'); - if(pname) - pname++; - else - pname = nv->name; - if(strcmp(pname, Name)==0) - p = nv->value; - } - return p; -} -#endif - -/* debug all-in-one function - * do parsing then display to stdout */ -#ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize) -{ - struct NameValueParserData pdata; - struct NameValue * nv; - ParseNameValue(buffer, bufsize, &pdata); - for(nv = pdata.l_head; - nv != NULL; - nv = nv->l_next) - { - printf("%s = %s\n", nv->name, nv->value); - } - ClearNameValueList(&pdata); -} -#endif /* DEBUG */ - diff --git a/external/miniupnpc/upnpreplyparse.h b/external/miniupnpc/upnpreplyparse.h deleted file mode 100644 index 6badd15b2..000000000 --- a/external/miniupnpc/upnpreplyparse.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2013 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#ifndef UPNPREPLYPARSE_H_INCLUDED -#define UPNPREPLYPARSE_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -struct NameValue { - struct NameValue * l_next; - char name[64]; - char value[128]; -}; - -struct NameValueParserData { - struct NameValue * l_head; - char curelt[64]; - char * portListing; - int portListingLength; - int topelt; - const char * cdata; - int cdatalen; -}; - -/* ParseNameValue() */ -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data); - -/* ClearNameValueList() */ -void -ClearNameValueList(struct NameValueParserData * pdata); - -/* GetValueFromNameValueList() */ -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name); - -#if 0 -/* GetValueFromNameValueListIgnoreNS() */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name); -#endif - -/* DisplayNameValueList() */ -#ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/external/miniupnpc/wingenminiupnpcstrings.c b/external/miniupnpc/wingenminiupnpcstrings.c deleted file mode 100644 index 50df06a76..000000000 --- a/external/miniupnpc/wingenminiupnpcstrings.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $Id: wingenminiupnpcstrings.c,v 1.4 2015/02/08 08:46:06 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENSE file provided within this distribution */ -#include <stdio.h> -#include <windows.h> - -/* This program display the Windows version and is used to - * generate the miniupnpcstrings.h - * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h - */ -int main(int argc, char * * argv) { - char buffer[256]; - OSVERSIONINFO osvi; - FILE * fin; - FILE * fout; - int n; - char miniupnpcVersion[32]; - /* dwMajorVersion : - The major version number of the operating system. For more information, see Remarks. - dwMinorVersion : - The minor version number of the operating system. For more information, see Remarks. - dwBuildNumber : - The build number of the operating system. - dwPlatformId - The operating system platform. This member can be the following value. - szCSDVersion - A null-terminated string, such as "Service Pack 3", that indicates the - latest Service Pack installed on the system. If no Service Pack has - been installed, the string is empty. - */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - GetVersionEx(&osvi); - - printf("Windows %lu.%lu Build %lu %s\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, - osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion)); - - fin = fopen("VERSION", "r"); - fgets(miniupnpcVersion, sizeof(miniupnpcVersion), fin); - fclose(fin); - for(n = 0; n < sizeof(miniupnpcVersion); n++) { - if(miniupnpcVersion[n] < ' ') - miniupnpcVersion[n] = '\0'; - } - printf("MiniUPnPc version %s\n", miniupnpcVersion); - - if(argc >= 3) { - fin = fopen(argv[1], "r"); - if(!fin) { - fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); - return 1; - } - fout = fopen(argv[2], "w"); - if(!fout) { - fprintf(stderr, "Cannot open %s for writing.\n", argv[2]); - fclose(fin); - return 1; - } - n = 0; - while(fgets(buffer, sizeof(buffer), fin)) { - if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) { - sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); - } else if(0 == memcmp(buffer, "#define MINIUPNPC_VERSION_STRING \"version\"", 42)) { - sprintf(buffer, "#define MINIUPNPC_VERSION_STRING \"%s\"\n", - miniupnpcVersion); - } - /*fputs(buffer, stdout);*/ - fputs(buffer, fout); - n++; - } - fclose(fin); - fclose(fout); - printf("%d lines written to %s.\n", n, argv[2]); - } - return 0; -} diff --git a/external/rapidjson b/external/rapidjson new file mode 160000 +Subproject af223d44f4e8d3772cb1ac0ce8bc2a132b51717 diff --git a/external/rapidjson/allocators.h b/external/rapidjson/allocators.h deleted file mode 100644 index 98affe03f..000000000 --- a/external/rapidjson/allocators.h +++ /dev/null @@ -1,271 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ALLOCATORS_H_ -#define RAPIDJSON_ALLOCATORS_H_ - -#include "rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Allocator - -/*! \class rapidjson::Allocator - \brief Concept for allocating, resizing and freeing memory block. - - Note that Malloc() and Realloc() are non-static but Free() is static. - - So if an allocator need to support Free(), it needs to put its pointer in - the header of memory block. - -\code -concept Allocator { - static const bool kNeedFree; //!< Whether this allocator needs to call Free(). - - // Allocate a memory block. - // \param size of the memory block in bytes. - // \returns pointer to the memory block. - void* Malloc(size_t size); - - // Resize a memory block. - // \param originalPtr The pointer to current memory block. Null pointer is permitted. - // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) - // \param newSize the new size in bytes. - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); - - // Free a memory block. - // \param pointer to the memory block. Null pointer is permitted. - static void Free(void *ptr); -}; -\endcode -*/ - -/////////////////////////////////////////////////////////////////////////////// -// CrtAllocator - -//! C-runtime library allocator. -/*! This class is just wrapper for standard C library memory routines. - \note implements Allocator concept -*/ -class CrtAllocator { -public: - static const bool kNeedFree = true; - void* Malloc(size_t size) { - if (size) // behavior of malloc(0) is implementation defined. - return std::malloc(size); - else - return NULL; // standardize to returning NULL. - } - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { - (void)originalSize; - if (newSize == 0) { - std::free(originalPtr); - return NULL; - } - return std::realloc(originalPtr, newSize); - } - static void Free(void *ptr) { std::free(ptr); } -}; - -/////////////////////////////////////////////////////////////////////////////// -// MemoryPoolAllocator - -//! Default memory allocator used by the parser and DOM. -/*! This allocator allocate memory blocks from pre-allocated memory chunks. - - It does not free memory blocks. And Realloc() only allocate new memory. - - The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. - - User may also supply a buffer as the first chunk. - - If the user-buffer is full then additional chunks are allocated by BaseAllocator. - - The user-buffer is not deallocated by this allocator. - - \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. - \note implements Allocator concept -*/ -template <typename BaseAllocator = CrtAllocator> -class MemoryPoolAllocator { -public: - static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) - - //! Constructor with chunkSize. - /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - } - - //! Constructor with user-supplied buffer. - /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. - - The user buffer will not be deallocated when this allocator is destructed. - - \param buffer User supplied buffer. - \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). - \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. - \param baseAllocator The allocator for allocating memory chunks. - */ - MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : - chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) - { - RAPIDJSON_ASSERT(buffer != 0); - RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); - chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer); - chunkHead_->capacity = size - sizeof(ChunkHeader); - chunkHead_->size = 0; - chunkHead_->next = 0; - } - - //! Destructor. - /*! This deallocates all memory chunks, excluding the user-supplied buffer. - */ - ~MemoryPoolAllocator() { - Clear(); - RAPIDJSON_DELETE(ownBaseAllocator_); - } - - //! Deallocates all memory chunks, excluding the user-supplied buffer. - void Clear() { - while (chunkHead_ && chunkHead_ != userBuffer_) { - ChunkHeader* next = chunkHead_->next; - baseAllocator_->Free(chunkHead_); - chunkHead_ = next; - } - if (chunkHead_ && chunkHead_ == userBuffer_) - chunkHead_->size = 0; // Clear user buffer - } - - //! Computes the total capacity of allocated memory chunks. - /*! \return total capacity in bytes. - */ - size_t Capacity() const { - size_t capacity = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - capacity += c->capacity; - return capacity; - } - - //! Computes the memory blocks allocated. - /*! \return total used bytes. - */ - size_t Size() const { - size_t size = 0; - for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) - size += c->size; - return size; - } - - //! Allocates a memory block. (concept Allocator) - void* Malloc(size_t size) { - if (!size) - return NULL; - - size = RAPIDJSON_ALIGN(size); - if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) - if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) - return NULL; - - void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; - chunkHead_->size += size; - return buffer; - } - - //! Resizes a memory block (concept Allocator) - void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { - if (originalPtr == 0) - return Malloc(newSize); - - if (newSize == 0) - return NULL; - - originalSize = RAPIDJSON_ALIGN(originalSize); - newSize = RAPIDJSON_ALIGN(newSize); - - // Do not shrink if new size is smaller than original - if (originalSize >= newSize) - return originalPtr; - - // Simply expand it if it is the last allocation and there is sufficient space - if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { - size_t increment = static_cast<size_t>(newSize - originalSize); - if (chunkHead_->size + increment <= chunkHead_->capacity) { - chunkHead_->size += increment; - return originalPtr; - } - } - - // Realloc process: allocate and copy memory, do not free original buffer. - if (void* newBuffer = Malloc(newSize)) { - if (originalSize) - std::memcpy(newBuffer, originalPtr, originalSize); - return newBuffer; - } - else - return NULL; - } - - //! Frees a memory block (concept Allocator) - static void Free(void *ptr) { (void)ptr; } // Do nothing - -private: - //! Copy constructor is not permitted. - MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; - //! Copy assignment operator is not permitted. - MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; - - //! Creates a new chunk. - /*! \param capacity Capacity of the chunk in bytes. - \return true if success. - */ - bool AddChunk(size_t capacity) { - if (!baseAllocator_) - ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator()); - if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { - chunk->capacity = capacity; - chunk->size = 0; - chunk->next = chunkHead_; - chunkHead_ = chunk; - return true; - } - else - return false; - } - - static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. - - //! Chunk header for perpending to each chunk. - /*! Chunks are stored as a singly linked list. - */ - struct ChunkHeader { - size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). - size_t size; //!< Current size of allocated memory in bytes. - ChunkHeader *next; //!< Next chunk in the linked list. - }; - - ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. - size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. - void *userBuffer_; //!< User supplied buffer. - BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. - BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. -}; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/external/rapidjson/document.h b/external/rapidjson/document.h deleted file mode 100644 index 19f5a6a5f..000000000 --- a/external/rapidjson/document.h +++ /dev/null @@ -1,2575 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_DOCUMENT_H_ -#define RAPIDJSON_DOCUMENT_H_ - -/*! \file document.h */ - -#include "reader.h" -#include "internal/meta.h" -#include "internal/strfunc.h" -#include "memorystream.h" -#include "encodedstream.h" -#include <new> // placement new -#include <limits> - -RAPIDJSON_DIAG_PUSH -#ifdef _MSC_VER -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_OFF(effc++) -#if __GNUC__ >= 6 -RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions -#endif -#endif // __GNUC__ - -#ifndef RAPIDJSON_NOMEMBERITERATORCLASS -#include <iterator> // std::iterator, std::random_access_iterator_tag -#endif - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS -#include <utility> // std::move -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -// Forward declaration. -template <typename Encoding, typename Allocator> -class GenericValue; - -template <typename Encoding, typename Allocator, typename StackAllocator> -class GenericDocument; - -//! Name-value pair in a JSON object value. -/*! - This class was internal to GenericValue. It used to be a inner struct. - But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. - https://code.google.com/p/rapidjson/issues/detail?id=64 -*/ -template <typename Encoding, typename Allocator> -struct GenericMember { - GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) - GenericValue<Encoding, Allocator> value; //!< value of member. -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericMemberIterator - -#ifndef RAPIDJSON_NOMEMBERITERATORCLASS - -//! (Constant) member iterator for a JSON object value -/*! - \tparam Const Is this a constant iterator? - \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) - \tparam Allocator Allocator type for allocating memory of object, array and string. - - This class implements a Random Access Iterator for GenericMember elements - of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. - - \note This iterator implementation is mainly intended to avoid implicit - conversions from iterator values to \c NULL, - e.g. from GenericValue::FindMember. - - \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a - pointer-based implementation, if your platform doesn't provide - the C++ <iterator> header. - - \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator - */ -template <bool Const, typename Encoding, typename Allocator> -class GenericMemberIterator - : public std::iterator<std::random_access_iterator_tag - , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> { - - friend class GenericValue<Encoding,Allocator>; - template <bool, typename, typename> friend class GenericMemberIterator; - - typedef GenericMember<Encoding,Allocator> PlainType; - typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; - typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType; - -public: - //! Iterator type itself - typedef GenericMemberIterator Iterator; - //! Constant iterator type - typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator; - //! Non-constant iterator type - typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator; - - //! Pointer to (const) GenericMember - typedef typename BaseType::pointer Pointer; - //! Reference to (const) GenericMember - typedef typename BaseType::reference Reference; - //! Signed integer type (e.g. \c ptrdiff_t) - typedef typename BaseType::difference_type DifferenceType; - - //! Default constructor (singular value) - /*! Creates an iterator pointing to no element. - \note All operations, except for comparisons, are undefined on such values. - */ - GenericMemberIterator() : ptr_() {} - - //! Iterator conversions to more const - /*! - \param it (Non-const) iterator to copy from - - Allows the creation of an iterator from another GenericMemberIterator - that is "less const". Especially, creating a non-constant iterator - from a constant iterator are disabled: - \li const -> non-const (not ok) - \li const -> const (ok) - \li non-const -> const (ok) - \li non-const -> non-const (ok) - - \note If the \c Const template parameter is already \c false, this - constructor effectively defines a regular copy-constructor. - Otherwise, the copy constructor is implicitly defined. - */ - GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} - Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } - - //! @name stepping - //@{ - Iterator& operator++(){ ++ptr_; return *this; } - Iterator& operator--(){ --ptr_; return *this; } - Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } - Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } - //@} - - //! @name increment/decrement - //@{ - Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } - Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } - - Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } - Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } - //@} - - //! @name relations - //@{ - bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } - bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } - bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } - bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } - bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } - bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } - //@} - - //! @name dereference - //@{ - Reference operator*() const { return *ptr_; } - Pointer operator->() const { return ptr_; } - Reference operator[](DifferenceType n) const { return ptr_[n]; } - //@} - - //! Distance - DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } - -private: - //! Internal constructor from plain pointer - explicit GenericMemberIterator(Pointer p) : ptr_(p) {} - - Pointer ptr_; //!< raw pointer -}; - -#else // RAPIDJSON_NOMEMBERITERATORCLASS - -// class-based member iterator implementation disabled, use plain pointers - -template <bool Const, typename Encoding, typename Allocator> -struct GenericMemberIterator; - -//! non-const GenericMemberIterator -template <typename Encoding, typename Allocator> -struct GenericMemberIterator<false,Encoding,Allocator> { - //! use plain pointer as iterator type - typedef GenericMember<Encoding,Allocator>* Iterator; -}; -//! const GenericMemberIterator -template <typename Encoding, typename Allocator> -struct GenericMemberIterator<true,Encoding,Allocator> { - //! use plain const pointer as iterator type - typedef const GenericMember<Encoding,Allocator>* Iterator; -}; - -#endif // RAPIDJSON_NOMEMBERITERATORCLASS - -/////////////////////////////////////////////////////////////////////////////// -// GenericStringRef - -//! Reference to a constant string (not taking a copy) -/*! - \tparam CharType character type of the string - - This helper class is used to automatically infer constant string - references for string literals, especially from \c const \b (!) - character arrays. - - The main use is for creating JSON string values without copying the - source string via an \ref Allocator. This requires that the referenced - string pointers have a sufficient lifetime, which exceeds the lifetime - of the associated GenericValue. - - \b Example - \code - Value v("foo"); // ok, no need to copy & calculate length - const char foo[] = "foo"; - v.SetString(foo); // ok - - const char* bar = foo; - // Value x(bar); // not ok, can't rely on bar's lifetime - Value x(StringRef(bar)); // lifetime explicitly guaranteed by user - Value y(StringRef(bar, 3)); // ok, explicitly pass length - \endcode - - \see StringRef, GenericValue::SetString -*/ -template<typename CharType> -struct GenericStringRef { - typedef CharType Ch; //!< character type of the string - - //! Create string reference from \c const character array -#ifndef __clang__ // -Wdocumentation - /*! - This constructor implicitly creates a constant string reference from - a \c const character array. It has better performance than - \ref StringRef(const CharType*) by inferring the string \ref length - from the array length, and also supports strings containing null - characters. - - \tparam N length of the string, automatically inferred - - \param str Constant character array, lifetime assumed to be longer - than the use of the string in e.g. a GenericValue - - \post \ref s == str - - \note Constant complexity. - \note There is a hidden, private overload to disallow references to - non-const character arrays to be created via this constructor. - By this, e.g. function-scope arrays used to be filled via - \c snprintf are excluded from consideration. - In such cases, the referenced string should be \b copied to the - GenericValue instead. - */ -#endif - template<SizeType N> - GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT - : s(str), length(N-1) {} - - //! Explicitly create string reference from \c const character pointer -#ifndef __clang__ // -Wdocumentation - /*! - This constructor can be used to \b explicitly create a reference to - a constant string pointer. - - \see StringRef(const CharType*) - - \param str Constant character pointer, lifetime assumed to be longer - than the use of the string in e.g. a GenericValue - - \post \ref s == str - - \note There is a hidden, private overload to disallow references to - non-const character arrays to be created via this constructor. - By this, e.g. function-scope arrays used to be filled via - \c snprintf are excluded from consideration. - In such cases, the referenced string should be \b copied to the - GenericValue instead. - */ -#endif - explicit GenericStringRef(const CharType* str) - : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); } - - //! Create constant string reference from pointer and length -#ifndef __clang__ // -Wdocumentation - /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \param len length of the string, excluding the trailing NULL terminator - - \post \ref s == str && \ref length == len - \note Constant complexity. - */ -#endif - GenericStringRef(const CharType* str, SizeType len) - : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); } - - GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} - - //! implicit conversion to plain CharType pointer - operator const Ch *() const { return s; } - - const Ch* const s; //!< plain CharType pointer - const SizeType length; //!< length of the string (excluding the trailing NULL terminator) - -private: - //! Disallow construction from non-const array - template<SizeType N> - GenericStringRef(CharType (&str)[N]) /* = delete */; - //! Copy assignment operator not permitted - immutable type - GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; -}; - -//! Mark a character pointer as constant string -/*! Mark a plain character pointer as a "string literal". This function - can be used to avoid copying a character string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - \tparam CharType Character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \return GenericStringRef string reference object - \relatesalso GenericStringRef - - \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember -*/ -template<typename CharType> -inline GenericStringRef<CharType> StringRef(const CharType* str) { - return GenericStringRef<CharType>(str, internal::StrLen(str)); -} - -//! Mark a character pointer as constant string -/*! Mark a plain character pointer as a "string literal". This function - can be used to avoid copying a character string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - - This version has better performance with supplied length, and also - supports string containing null characters. - - \tparam CharType character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \param length The length of source string. - \return GenericStringRef string reference object - \relatesalso GenericStringRef -*/ -template<typename CharType> -inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) { - return GenericStringRef<CharType>(str, SizeType(length)); -} - -#if RAPIDJSON_HAS_STDSTRING -//! Mark a string object as constant string -/*! Mark a string object (e.g. \c std::string) as a "string literal". - This function can be used to avoid copying a string to be referenced as a - value in a JSON GenericValue object, if the string's lifetime is known - to be valid long enough. - - \tparam CharType character type of the string - \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue - \return GenericStringRef string reference object - \relatesalso GenericStringRef - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. -*/ -template<typename CharType> -inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) { - return GenericStringRef<CharType>(str.data(), SizeType(str.size())); -} -#endif - -/////////////////////////////////////////////////////////////////////////////// -// GenericValue type traits -namespace internal { - -template <typename T, typename Encoding = void, typename Allocator = void> -struct IsGenericValueImpl : FalseType {}; - -// select candidates according to nested encoding and allocator types -template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type> - : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {}; - -// helper to match arbitrary GenericValue instantiations, including derived classes -template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// TypeHelper - -namespace internal { - -template <typename ValueType, typename T> -struct TypeHelper {}; - -template<typename ValueType> -struct TypeHelper<ValueType, bool> { - static bool Is(const ValueType& v) { return v.IsBool(); } - static bool Get(const ValueType& v) { return v.GetBool(); } - static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } - static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, int> { - static bool Is(const ValueType& v) { return v.IsInt(); } - static int Get(const ValueType& v) { return v.GetInt(); } - static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } - static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, unsigned> { - static bool Is(const ValueType& v) { return v.IsUint(); } - static unsigned Get(const ValueType& v) { return v.GetUint(); } - static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } - static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, int64_t> { - static bool Is(const ValueType& v) { return v.IsInt64(); } - static int64_t Get(const ValueType& v) { return v.GetInt64(); } - static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } - static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, uint64_t> { - static bool Is(const ValueType& v) { return v.IsUint64(); } - static uint64_t Get(const ValueType& v) { return v.GetUint64(); } - static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } - static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, double> { - static bool Is(const ValueType& v) { return v.IsDouble(); } - static double Get(const ValueType& v) { return v.GetDouble(); } - static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } - static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, float> { - static bool Is(const ValueType& v) { return v.IsFloat(); } - static float Get(const ValueType& v) { return v.GetFloat(); } - static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } - static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, const typename ValueType::Ch*> { - typedef const typename ValueType::Ch* StringType; - static bool Is(const ValueType& v) { return v.IsString(); } - static StringType Get(const ValueType& v) { return v.GetString(); } - static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } - static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } -}; - -#if RAPIDJSON_HAS_STDSTRING -template<typename ValueType> -struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > { - typedef std::basic_string<typename ValueType::Ch> StringType; - static bool Is(const ValueType& v) { return v.IsString(); } - static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } - static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } -}; -#endif - -template<typename ValueType> -struct TypeHelper<ValueType, typename ValueType::Array> { - typedef typename ValueType::Array ArrayType; - static bool Is(const ValueType& v) { return v.IsArray(); } - static ArrayType Get(ValueType& v) { return v.GetArray(); } - static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } - static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, typename ValueType::ConstArray> { - typedef typename ValueType::ConstArray ArrayType; - static bool Is(const ValueType& v) { return v.IsArray(); } - static ArrayType Get(const ValueType& v) { return v.GetArray(); } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, typename ValueType::Object> { - typedef typename ValueType::Object ObjectType; - static bool Is(const ValueType& v) { return v.IsObject(); } - static ObjectType Get(ValueType& v) { return v.GetObject(); } - static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } - static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; } -}; - -template<typename ValueType> -struct TypeHelper<ValueType, typename ValueType::ConstObject> { - typedef typename ValueType::ConstObject ObjectType; - static bool Is(const ValueType& v) { return v.IsObject(); } - static ObjectType Get(const ValueType& v) { return v.GetObject(); } -}; - -} // namespace internal - -// Forward declarations -template <bool, typename> class GenericArray; -template <bool, typename> class GenericObject; - -/////////////////////////////////////////////////////////////////////////////// -// GenericValue - -//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. -/*! - A JSON value can be one of 7 types. This class is a variant type supporting - these types. - - Use the Value if UTF8 and default allocator - - \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) - \tparam Allocator Allocator type for allocating memory of object, array and string. -*/ -template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > -class GenericValue { -public: - //! Name-value pair in an object. - typedef GenericMember<Encoding, Allocator> Member; - typedef Encoding EncodingType; //!< Encoding type from template parameter. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string - typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object. - typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. - typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. - typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. - typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself. - typedef GenericArray<false, ValueType> Array; - typedef GenericArray<true, ValueType> ConstArray; - typedef GenericObject<false, ValueType> Object; - typedef GenericObject<true, ValueType> ConstObject; - - //!@name Constructors and destructor. - //@{ - - //! Default constructor creates a null value. - GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { - rhs.data_.f.flags = kNullFlag; // give up contents - } -#endif - -private: - //! Copy constructor is not permitted. - GenericValue(const GenericValue& rhs); - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Moving from a GenericDocument is not permitted. - template <typename StackAllocator> - GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); - - //! Move assignment from a GenericDocument is not permitted. - template <typename StackAllocator> - GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); -#endif - -public: - - //! Constructor with JSON value type. - /*! This creates a Value of specified type with default content. - \param type Type of the value. - \note Default content for number is zero. - */ - explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { - static const uint16_t defaultFlags[7] = { - kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, - kNumberAnyFlag - }; - RAPIDJSON_ASSERT(type <= kNumberType); - data_.f.flags = defaultFlags[type]; - - // Use ShortString to store empty string. - if (type == kStringType) - data_.ss.SetLength(0); - } - - //! Explicit copy constructor (with allocator) - /*! Creates a copy of a Value by using the given Allocator - \tparam SourceAllocator allocator of \c rhs - \param rhs Value to copy from (read-only) - \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). - \see CopyFrom() - */ - template< typename SourceAllocator > - GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator); - - //! Constructor for boolean value. - /*! \param b Boolean value - \note This constructor is limited to \em real boolean values and rejects - implicitly converted types like arbitrary pointers. Use an explicit cast - to \c bool, if you want to construct a boolean JSON value in such cases. - */ -#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen - template <typename T> - explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472 -#else - explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT -#endif - : data_() { - // safe-guard against failing SFINAE - RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value)); - data_.f.flags = b ? kTrueFlag : kFalseFlag; - } - - //! Constructor for int value. - explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { - data_.n.i64 = i; - data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; - } - - //! Constructor for unsigned value. - explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { - data_.n.u64 = u; - data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); - } - - //! Constructor for int64_t value. - explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { - data_.n.i64 = i64; - data_.f.flags = kNumberInt64Flag; - if (i64 >= 0) { - data_.f.flags |= kNumberUint64Flag; - if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) - data_.f.flags |= kUintFlag; - if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - - //! Constructor for uint64_t value. - explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { - data_.n.u64 = u64; - data_.f.flags = kNumberUint64Flag; - if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) - data_.f.flags |= kInt64Flag; - if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) - data_.f.flags |= kUintFlag; - if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) - data_.f.flags |= kIntFlag; - } - - //! Constructor for double value. - explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } - - //! Constructor for constant string (i.e. do not make a copy of string) - GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } - - //! Constructor for constant string (i.e. do not make a copy of string) - explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } - - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } - - //! Constructor for copy-string (i.e. do make a copy of string) - GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } - -#if RAPIDJSON_HAS_STDSTRING - //! Constructor for copy-string from a string object (i.e. do make a copy of string) - /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } -#endif - - //! Constructor for Array. - /*! - \param a An array obtained by \c GetArray(). - \note \c Array is always pass-by-value. - \note the source array is moved into this value and the sourec array becomes empty. - */ - GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { - a.value_.data_ = Data(); - a.value_.data_.f.flags = kArrayFlag; - } - - //! Constructor for Object. - /*! - \param o An object obtained by \c GetObject(). - \note \c Object is always pass-by-value. - \note the source object is moved into this value and the sourec object becomes empty. - */ - GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { - o.value_.data_ = Data(); - o.value_.data_.f.flags = kObjectFlag; - } - - //! Destructor. - /*! Need to destruct elements of array, members of object, or copy-string. - */ - ~GenericValue() { - if (Allocator::kNeedFree) { // Shortcut by Allocator's trait - switch(data_.f.flags) { - case kArrayFlag: - { - GenericValue* e = GetElementsPointer(); - for (GenericValue* v = e; v != e + data_.a.size; ++v) - v->~GenericValue(); - Allocator::Free(e); - } - break; - - case kObjectFlag: - for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) - m->~Member(); - Allocator::Free(GetMembersPointer()); - break; - - case kCopyStringFlag: - Allocator::Free(const_cast<Ch*>(GetStringPointer())); - break; - - default: - break; // Do nothing for other types. - } - } - } - - //@} - - //!@name Assignment operators - //@{ - - //! Assignment with move semantics. - /*! \param rhs Source of the assignment. It will become a null value after assignment. - */ - GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { - RAPIDJSON_ASSERT(this != &rhs); - this->~GenericValue(); - RawAssign(rhs); - return *this; - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move assignment in C++11 - GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { - return *this = rhs.Move(); - } -#endif - - //! Assignment of constant string reference (no copy) - /*! \param str Constant string reference to be assigned - \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. - \see GenericStringRef, operator=(T) - */ - GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { - GenericValue s(str); - return *this = s; - } - - //! Assignment with primitive types. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param value The value to be assigned. - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref SetString(const Ch*, Allocator&) (for copying) or - \ref StringRef() (to explicitly mark the pointer as constant) instead. - All other pointer types would implicitly convert to \c bool, - use \ref SetBool() instead. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&)) - operator=(T value) { - GenericValue v(value); - return *this = v; - } - - //! Deep-copy assignment from Value - /*! Assigns a \b copy of the Value to the current Value object - \tparam SourceAllocator Allocator type of \c rhs - \param rhs Value to copy from (read-only) - \param allocator Allocator to use for copying - */ - template <typename SourceAllocator> - GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { - RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs)); - this->~GenericValue(); - new (this) GenericValue(rhs, allocator); - return *this; - } - - //! Exchange the contents of this value with those of other. - /*! - \param other Another value. - \note Constant complexity. - */ - GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { - GenericValue temp; - temp.RawAssign(*this); - RawAssign(other); - other.RawAssign(temp); - return *this; - } - - //! free-standing swap function helper - /*! - Helper function to enable support for common swap implementation pattern based on \c std::swap: - \code - void swap(MyClass& a, MyClass& b) { - using std::swap; - swap(a.value, b.value); - // ... - } - \endcode - \see Swap() - */ - friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } - - //! Prepare Value for move semantics - /*! \return *this */ - GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } - //@} - - //!@name Equal-to and not-equal-to operators - //@{ - //! Equal-to operator - /*! - \note If an object contains duplicated named member, comparing equality with any object is always \c false. - \note Linear time complexity (number of all values in the subtree and total lengths of all strings). - */ - template <typename SourceAllocator> - bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const { - typedef GenericValue<Encoding, SourceAllocator> RhsType; - if (GetType() != rhs.GetType()) - return false; - - switch (GetType()) { - case kObjectType: // Warning: O(n^2) inner-loop - if (data_.o.size != rhs.data_.o.size) - return false; - for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { - typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); - if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) - return false; - } - return true; - - case kArrayType: - if (data_.a.size != rhs.data_.a.size) - return false; - for (SizeType i = 0; i < data_.a.size; i++) - if ((*this)[i] != rhs[i]) - return false; - return true; - - case kStringType: - return StringEqual(rhs); - - case kNumberType: - if (IsDouble() || rhs.IsDouble()) { - double a = GetDouble(); // May convert from integer to double. - double b = rhs.GetDouble(); // Ditto - return a >= b && a <= b; // Prevent -Wfloat-equal - } - else - return data_.n.u64 == rhs.data_.n.u64; - - default: - return true; - } - } - - //! Equal-to operator with const C-string pointer - bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } - -#if RAPIDJSON_HAS_STDSTRING - //! Equal-to operator with string object - /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); } -#endif - - //! Equal-to operator with primitive types - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false - */ - template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } - - //! Not-equal-to operator - /*! \return !(*this == rhs) - */ - template <typename SourceAllocator> - bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); } - - //! Not-equal-to operator with const C-string pointer - bool operator!=(const Ch* rhs) const { return !(*this == rhs); } - - //! Not-equal-to operator with arbitrary types - /*! \return !(*this == rhs) - */ - template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } - - //! Equal-to operator with arbitrary types (symmetric version) - /*! \return (rhs == lhs) - */ - template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } - - //! Not-Equal-to operator with arbitrary types (symmetric version) - /*! \return !(rhs == lhs) - */ - template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } - //@} - - //!@name Type - //@{ - - Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); } - bool IsNull() const { return data_.f.flags == kNullFlag; } - bool IsFalse() const { return data_.f.flags == kFalseFlag; } - bool IsTrue() const { return data_.f.flags == kTrueFlag; } - bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } - bool IsObject() const { return data_.f.flags == kObjectFlag; } - bool IsArray() const { return data_.f.flags == kArrayFlag; } - bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } - bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } - bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } - bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } - bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } - bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } - bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } - - // Checks whether a number can be losslessly converted to a double. - bool IsLosslessDouble() const { - if (!IsNumber()) return false; - if (IsUint64()) { - uint64_t u = GetUint64(); - volatile double d = static_cast<double>(u); - return (d >= 0.0) - && (d < static_cast<double>(std::numeric_limits<uint64_t>::max())) - && (u == static_cast<uint64_t>(d)); - } - if (IsInt64()) { - int64_t i = GetInt64(); - volatile double d = static_cast<double>(i); - return (d >= static_cast<double>(std::numeric_limits<int64_t>::min())) - && (d < static_cast<double>(std::numeric_limits<int64_t>::max())) - && (i == static_cast<int64_t>(d)); - } - return true; // double, int, uint are always lossless - } - - // Checks whether a number is a float (possible lossy). - bool IsFloat() const { - if ((data_.f.flags & kDoubleFlag) == 0) - return false; - double d = GetDouble(); - return d >= -3.4028234e38 && d <= 3.4028234e38; - } - // Checks whether a number can be losslessly converted to a float. - bool IsLosslessFloat() const { - if (!IsNumber()) return false; - double a = GetDouble(); - if (a < static_cast<double>(-std::numeric_limits<float>::max()) - || a > static_cast<double>(std::numeric_limits<float>::max())) - return false; - double b = static_cast<double>(static_cast<float>(a)); - return a >= b && a <= b; // Prevent -Wfloat-equal - } - - //@} - - //!@name Null - //@{ - - GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } - - //@} - - //!@name Bool - //@{ - - bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } - //!< Set boolean value - /*! \post IsBool() == true */ - GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } - - //@} - - //!@name Object - //@{ - - //! Set this value as an empty object. - /*! \post IsObject() == true */ - GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } - - //! Get the number of members in the object. - SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } - - //! Check whether the object is empty. - bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } - - //! Get a value from an object associated with the name. - /*! \pre IsObject() == true - \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) - \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. - Since 0.2, if the name is not correct, it will assert. - If user is unsure whether a member exists, user should use HasMember() first. - A better approach is to use FindMember(). - \note Linear time complexity. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) { - GenericValue n(StringRef(name)); - return (*this)[n]; - } - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; } - - //! Get a value from an object associated with the name. - /*! \pre IsObject() == true - \tparam SourceAllocator Allocator of the \c name value - - \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). - And it can also handle strings with embedded null characters. - - \note Linear time complexity. - */ - template <typename SourceAllocator> - GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) { - MemberIterator member = FindMember(name); - if (member != MemberEnd()) - return member->value; - else { - RAPIDJSON_ASSERT(false); // see above note - - // This will generate -Wexit-time-destructors in clang - // static GenericValue NullValue; - // return NullValue; - - // Use static buffer and placement-new to prevent destruction - static char buffer[sizeof(GenericValue)]; - return *new (buffer) GenericValue(); - } - } - template <typename SourceAllocator> - const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; } - -#if RAPIDJSON_HAS_STDSTRING - //! Get a value from an object associated with name (string object). - GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; } - const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; } -#endif - - //! Const member iterator - /*! \pre IsObject() == true */ - ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } - //! Const \em past-the-end member iterator - /*! \pre IsObject() == true */ - ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } - //! Member iterator - /*! \pre IsObject() == true */ - MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } - //! \em Past-the-end member iterator - /*! \pre IsObject() == true */ - MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } - - //! Check whether a member exists in the object. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } - -#if RAPIDJSON_HAS_STDSTRING - //! Check whether a member exists in the object with string object. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); } -#endif - - //! Check whether a member exists in the object with GenericValue name. - /*! - This version is faster because it does not need a StrLen(). It can also handle string with null character. - \param name Member name to be searched. - \pre IsObject() == true - \return Whether a member with that name exists. - \note It is better to use FindMember() directly if you need the obtain the value as well. - \note Linear time complexity. - */ - template <typename SourceAllocator> - bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); } - - //! Find member by name. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - - \note Earlier versions of Rapidjson returned a \c NULL pointer, in case - the requested member doesn't exist. For consistency with e.g. - \c std::map, this has been changed to MemberEnd() now. - \note Linear time complexity. - */ - MemberIterator FindMember(const Ch* name) { - GenericValue n(StringRef(name)); - return FindMember(n); - } - - ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } - - //! Find member by name. - /*! - This version is faster because it does not need a StrLen(). It can also handle string with null character. - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - - \note Earlier versions of Rapidjson returned a \c NULL pointer, in case - the requested member doesn't exist. For consistency with e.g. - \c std::map, this has been changed to MemberEnd() now. - \note Linear time complexity. - */ - template <typename SourceAllocator> - MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(name.IsString()); - MemberIterator member = MemberBegin(); - for ( ; member != MemberEnd(); ++member) - if (name.StringEqual(member->name)) - break; - return member; - } - template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); } - -#if RAPIDJSON_HAS_STDSTRING - //! Find member by string object name. - /*! - \param name Member name to be searched. - \pre IsObject() == true - \return Iterator to member, if it exists. - Otherwise returns \ref MemberEnd(). - */ - MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); } - ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); } -#endif - - //! Add a member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value Value of any type. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note The ownership of \c name and \c value will be transferred to this object on success. - \pre IsObject() && name.IsString() - \post name.IsNull() && value.IsNull() - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(name.IsString()); - - ObjectData& o = data_.o; - if (o.size >= o.capacity) { - if (o.capacity == 0) { - o.capacity = kDefaultObjectCapacity; - SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)))); - } - else { - SizeType oldCapacity = o.capacity; - o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 - SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member)))); - } - } - Member* members = GetMembersPointer(); - members[o.size].name.RawAssign(name); - members[o.size].value.RawAssign(value); - o.size++; - return *this; - } - - //! Add a constant string value as member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Add a string object as member (name-value pair) to the object. - /*! \param name A string value as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) { - GenericValue v(value, allocator); - return AddMember(name, v, allocator); - } -#endif - - //! Add any primitive value as member (name-value pair) to the object. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param name A string value as name of member. - \param value Value of primitive type \c T as value of member - \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref - AddMember(StringRefType, StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized Constant time complexity. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) - AddMember(GenericValue& name, T value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { - return AddMember(name, value, allocator); - } - GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - - - //! Add a member (name-value pair) to the object. - /*! \param name A constant string reference as name of member. - \param value Value of any type. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note The ownership of \c value will be transferred to this object on success. - \pre IsObject() - \post value.IsNull() - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } - - //! Add a constant string value as member (name-value pair) to the object. - /*! \param name A constant string reference as name of member. - \param value constant string reference as value of member. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. - \note Amortized Constant time complexity. - */ - GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { - GenericValue v(value); - return AddMember(name, v, allocator); - } - - //! Add any primitive value as member (name-value pair) to the object. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param name A constant string reference as name of member. - \param value Value of primitive type \c T as value of member - \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \pre IsObject() - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref - AddMember(StringRefType, StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized Constant time complexity. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) - AddMember(StringRefType name, T value, Allocator& allocator) { - GenericValue n(name); - return AddMember(n, value, allocator); - } - - //! Remove all members in the object. - /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. - \note Linear time complexity. - */ - void RemoveAllMembers() { - RAPIDJSON_ASSERT(IsObject()); - for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) - m->~Member(); - data_.o.size = 0; - } - - //! Remove a member in object by its name. - /*! \param name Name of member to be removed. - \return Whether the member existed. - \note This function may reorder the object members. Use \ref - EraseMember(ConstMemberIterator) if you need to preserve the - relative order of the remaining members. - \note Linear time complexity. - */ - bool RemoveMember(const Ch* name) { - GenericValue n(StringRef(name)); - return RemoveMember(n); - } - -#if RAPIDJSON_HAS_STDSTRING - bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); } -#endif - - template <typename SourceAllocator> - bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) { - MemberIterator m = FindMember(name); - if (m != MemberEnd()) { - RemoveMember(m); - return true; - } - else - return false; - } - - //! Remove a member in object by iterator. - /*! \param m member iterator (obtained by FindMember() or MemberBegin()). - \return the new iterator after removal. - \note This function may reorder the object members. Use \ref - EraseMember(ConstMemberIterator) if you need to preserve the - relative order of the remaining members. - \note Constant time complexity. - */ - MemberIterator RemoveMember(MemberIterator m) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(data_.o.size > 0); - RAPIDJSON_ASSERT(GetMembersPointer() != 0); - RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); - - MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); - if (data_.o.size > 1 && m != last) - *m = *last; // Move the last one to this place - else - m->~Member(); // Only one left, just destroy - --data_.o.size; - return m; - } - - //! Remove a member from an object by iterator. - /*! \param pos iterator to the member to remove - \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() - \return Iterator following the removed element. - If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. - \note This function preserves the relative order of the remaining object - members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). - \note Linear time complexity. - */ - MemberIterator EraseMember(ConstMemberIterator pos) { - return EraseMember(pos, pos +1); - } - - //! Remove members in the range [first, last) from an object. - /*! \param first iterator to the first member to remove - \param last iterator following the last member to remove - \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() - \return Iterator following the last removed element. - \note This function preserves the relative order of the remaining object - members. - \note Linear time complexity. - */ - MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { - RAPIDJSON_ASSERT(IsObject()); - RAPIDJSON_ASSERT(data_.o.size > 0); - RAPIDJSON_ASSERT(GetMembersPointer() != 0); - RAPIDJSON_ASSERT(first >= MemberBegin()); - RAPIDJSON_ASSERT(first <= last); - RAPIDJSON_ASSERT(last <= MemberEnd()); - - MemberIterator pos = MemberBegin() + (first - MemberBegin()); - for (MemberIterator itr = pos; itr != last; ++itr) - itr->~Member(); - std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member)); - data_.o.size -= static_cast<SizeType>(last - first); - return pos; - } - - //! Erase a member in object by its name. - /*! \param name Name of member to be removed. - \return Whether the member existed. - \note Linear time complexity. - */ - bool EraseMember(const Ch* name) { - GenericValue n(StringRef(name)); - return EraseMember(n); - } - -#if RAPIDJSON_HAS_STDSTRING - bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); } -#endif - - template <typename SourceAllocator> - bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) { - MemberIterator m = FindMember(name); - if (m != MemberEnd()) { - EraseMember(m); - return true; - } - else - return false; - } - - Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } - ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } - - //@} - - //!@name Array - //@{ - - //! Set this value as an empty array. - /*! \post IsArray == true */ - GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } - - //! Get the number of elements in array. - SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } - - //! Get the capacity of array. - SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } - - //! Check whether the array is empty. - bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } - - //! Remove all elements in the array. - /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. - \note Linear time complexity. - */ - void Clear() { - RAPIDJSON_ASSERT(IsArray()); - GenericValue* e = GetElementsPointer(); - for (GenericValue* v = e; v != e + data_.a.size; ++v) - v->~GenericValue(); - data_.a.size = 0; - } - - //! Get an element from array by index. - /*! \pre IsArray() == true - \param index Zero-based index of element. - \see operator[](T*) - */ - GenericValue& operator[](SizeType index) { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(index < data_.a.size); - return GetElementsPointer()[index]; - } - const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } - - //! Element iterator - /*! \pre IsArray() == true */ - ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } - //! \em Past-the-end element iterator - /*! \pre IsArray() == true */ - ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } - //! Constant element iterator - /*! \pre IsArray() == true */ - ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } - //! Constant \em past-the-end element iterator - /*! \pre IsArray() == true */ - ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } - - //! Request the array to have enough capacity to store elements. - /*! \param newCapacity The capacity that the array at least need to have. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \note Linear time complexity. - */ - GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (newCapacity > data_.a.capacity) { - SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); - data_.a.capacity = newCapacity; - } - return *this; - } - - //! Append a GenericValue at the end of the array. - /*! \param value Value to be appended. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \post value.IsNull() == true - \return The value itself for fluent API. - \note The ownership of \c value will be transferred to this array on success. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - \note Amortized constant time complexity. - */ - GenericValue& PushBack(GenericValue& value, Allocator& allocator) { - RAPIDJSON_ASSERT(IsArray()); - if (data_.a.size >= data_.a.capacity) - Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); - GetElementsPointer()[data_.a.size++].RawAssign(value); - return *this; - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { - return PushBack(value, allocator); - } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - - //! Append a constant string reference at the end of the array. - /*! \param value Constant string reference to be appended. - \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \return The value itself for fluent API. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - \note Amortized constant time complexity. - \see GenericStringRef - */ - GenericValue& PushBack(StringRefType value, Allocator& allocator) { - return (*this).template PushBack<StringRefType>(value, allocator); - } - - //! Append a primitive value at the end of the array. - /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t - \param value Value of primitive type T to be appended. - \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). - \pre IsArray() == true - \return The value itself for fluent API. - \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. - - \note The source type \c T explicitly disallows all pointer types, - especially (\c const) \ref Ch*. This helps avoiding implicitly - referencing character strings with insufficient lifetime, use - \ref PushBack(GenericValue&, Allocator&) or \ref - PushBack(StringRefType, Allocator&). - All other pointer types would implicitly convert to \c bool, - use an explicit cast instead, if needed. - \note Amortized constant time complexity. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) - PushBack(T value, Allocator& allocator) { - GenericValue v(value); - return PushBack(v, allocator); - } - - //! Remove the last element in the array. - /*! - \note Constant time complexity. - */ - GenericValue& PopBack() { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(!Empty()); - GetElementsPointer()[--data_.a.size].~GenericValue(); - return *this; - } - - //! Remove an element of array by iterator. - /*! - \param pos iterator to the element to remove - \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() - \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. - \note Linear time complexity. - */ - ValueIterator Erase(ConstValueIterator pos) { - return Erase(pos, pos + 1); - } - - //! Remove elements in the range [first, last) of the array. - /*! - \param first iterator to the first element to remove - \param last iterator following the last element to remove - \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() - \return Iterator following the last removed element. - \note Linear time complexity. - */ - ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { - RAPIDJSON_ASSERT(IsArray()); - RAPIDJSON_ASSERT(data_.a.size > 0); - RAPIDJSON_ASSERT(GetElementsPointer() != 0); - RAPIDJSON_ASSERT(first >= Begin()); - RAPIDJSON_ASSERT(first <= last); - RAPIDJSON_ASSERT(last <= End()); - ValueIterator pos = Begin() + (first - Begin()); - for (ValueIterator itr = pos; itr != last; ++itr) - itr->~GenericValue(); - std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue)); - data_.a.size -= static_cast<SizeType>(last - first); - return pos; - } - - Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } - ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } - - //@} - - //!@name Number - //@{ - - int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } - unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } - int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } - uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } - - //! Get the value as double type. - /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. - */ - double GetDouble() const { - RAPIDJSON_ASSERT(IsNumber()); - if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. - if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double - if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double - if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision) - RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision) - } - - //! Get the value as float type. - /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. - */ - float GetFloat() const { - return static_cast<float>(GetDouble()); - } - - GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } - GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } - GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } - GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } - GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } - GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; } - - //@} - - //!@name String - //@{ - - const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } - - //! Get the length of string. - /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). - */ - SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } - - //! Set this value as a string without copying source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string pointer. - \param length The length of source string, excluding the trailing null terminator. - \return The value itself for fluent API. - \post IsString() == true && GetString() == s && GetStringLength() == length - \see SetString(StringRefType) - */ - GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } - - //! Set this value as a string without copying source string. - /*! \param s source string reference - \return The value itself for fluent API. - \post IsString() == true && GetString() == s && GetStringLength() == s.length - */ - GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } - - //! Set this value as a string by copying from source string. - /*! This version has better performance with supplied length, and also support string containing null character. - \param s source string. - \param length The length of source string, excluding the trailing null terminator. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length - */ - GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } - - //! Set this value as a string by copying from source string. - /*! \param s source string. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length - */ - GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } - -#if RAPIDJSON_HAS_STDSTRING - //! Set this value as a string by copying from source string. - /*! \param s source string. - \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). - \return The value itself for fluent API. - \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } -#endif - - //@} - - //!@name Array - //@{ - - //! Templated version for checking whether this value is type T. - /*! - \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string<Ch> - */ - template <typename T> - bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); } - - template <typename T> - T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); } - - template <typename T> - T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); } - - template<typename T> - ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); } - - template<typename T> - ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); } - - //@} - - //! Generate events of this value to a Handler. - /*! This function adopts the GoF visitor pattern. - Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. - It can also be used to deep clone this value via GenericDocument, which is also a Handler. - \tparam Handler type of handler. - \param handler An object implementing concept Handler. - */ - template <typename Handler> - bool Accept(Handler& handler) const { - switch(GetType()) { - case kNullType: return handler.Null(); - case kFalseType: return handler.Bool(false); - case kTrueType: return handler.Bool(true); - - case kObjectType: - if (RAPIDJSON_UNLIKELY(!handler.StartObject())) - return false; - for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { - RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. - if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) - return false; - if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) - return false; - } - return handler.EndObject(data_.o.size); - - case kArrayType: - if (RAPIDJSON_UNLIKELY(!handler.StartArray())) - return false; - for (const GenericValue* v = Begin(); v != End(); ++v) - if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) - return false; - return handler.EndArray(data_.a.size); - - case kStringType: - return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); - - default: - RAPIDJSON_ASSERT(GetType() == kNumberType); - if (IsDouble()) return handler.Double(data_.n.d); - else if (IsInt()) return handler.Int(data_.n.i.i); - else if (IsUint()) return handler.Uint(data_.n.u.u); - else if (IsInt64()) return handler.Int64(data_.n.i64); - else return handler.Uint64(data_.n.u64); - } - } - -private: - template <typename, typename> friend class GenericValue; - template <typename, typename, typename> friend class GenericDocument; - - enum { - kBoolFlag = 0x0008, - kNumberFlag = 0x0010, - kIntFlag = 0x0020, - kUintFlag = 0x0040, - kInt64Flag = 0x0080, - kUint64Flag = 0x0100, - kDoubleFlag = 0x0200, - kStringFlag = 0x0400, - kCopyFlag = 0x0800, - kInlineStrFlag = 0x1000, - - // Initial flags of different types. - kNullFlag = kNullType, - kTrueFlag = kTrueType | kBoolFlag, - kFalseFlag = kFalseType | kBoolFlag, - kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, - kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, - kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, - kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, - kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, - kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, - kConstStringFlag = kStringType | kStringFlag, - kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, - kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, - kObjectFlag = kObjectType, - kArrayFlag = kArrayType, - - kTypeMask = 0x07 - }; - - static const SizeType kDefaultArrayCapacity = 16; - static const SizeType kDefaultObjectCapacity = 16; - - struct Flag { -#if RAPIDJSON_48BITPOINTER_OPTIMIZATION - char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer -#elif RAPIDJSON_64BIT - char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes -#else - char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes -#endif - uint16_t flags; - }; - - struct String { - SizeType length; - SizeType hashcode; //!< reserved - const Ch* str; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars - // (excluding the terminating zero) and store a value to determine the length of the contained - // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string - // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as - // the string terminator as well. For getting the string length back from that value just use - // "MaxSize - str[LenPos]". - // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, - // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). - struct ShortString { - enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; - Ch str[MaxChars]; - - inline static bool Usable(SizeType len) { return (MaxSize >= len); } - inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); } - inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); } - }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - // By using proper binary layout, retrieval of different integer types do not need conversions. - union Number { -#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN - struct I { - int i; - char padding[4]; - }i; - struct U { - unsigned u; - char padding2[4]; - }u; -#else - struct I { - char padding[4]; - int i; - }i; - struct U { - char padding2[4]; - unsigned u; - }u; -#endif - int64_t i64; - uint64_t u64; - double d; - }; // 8 bytes - - struct ObjectData { - SizeType size; - SizeType capacity; - Member* members; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - struct ArrayData { - SizeType size; - SizeType capacity; - GenericValue* elements; - }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode - - union Data { - String s; - ShortString ss; - Number n; - ObjectData o; - ArrayData a; - Flag f; - }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION - - RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } - RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } - RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } - RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } - RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } - RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } - - // Initialize this value as array with initial data, without calling destructor. - void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { - data_.f.flags = kArrayFlag; - if (count) { - GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue))); - SetElementsPointer(e); - std::memcpy(e, values, count * sizeof(GenericValue)); - } - else - SetElementsPointer(0); - data_.a.size = data_.a.capacity = count; - } - - //! Initialize this value as object with initial data, without calling destructor. - void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { - data_.f.flags = kObjectFlag; - if (count) { - Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member))); - SetMembersPointer(m); - std::memcpy(m, members, count * sizeof(Member)); - } - else - SetMembersPointer(0); - data_.o.size = data_.o.capacity = count; - } - - //! Initialize this value as constant string, without calling destructor. - void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { - data_.f.flags = kConstStringFlag; - SetStringPointer(s); - data_.s.length = s.length; - } - - //! Initialize this value as copy string with initial data, without calling destructor. - void SetStringRaw(StringRefType s, Allocator& allocator) { - Ch* str = 0; - if (ShortString::Usable(s.length)) { - data_.f.flags = kShortStringFlag; - data_.ss.SetLength(s.length); - str = data_.ss.str; - } else { - data_.f.flags = kCopyStringFlag; - data_.s.length = s.length; - str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch))); - SetStringPointer(str); - } - std::memcpy(str, s, s.length * sizeof(Ch)); - str[s.length] = '\0'; - } - - //! Assignment without calling destructor - void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { - data_ = rhs.data_; - // data_.f.flags = rhs.data_.f.flags; - rhs.data_.f.flags = kNullFlag; - } - - template <typename SourceAllocator> - bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const { - RAPIDJSON_ASSERT(IsString()); - RAPIDJSON_ASSERT(rhs.IsString()); - - const SizeType len1 = GetStringLength(); - const SizeType len2 = rhs.GetStringLength(); - if(len1 != len2) { return false; } - - const Ch* const str1 = GetString(); - const Ch* const str2 = rhs.GetString(); - if(str1 == str2) { return true; } // fast path for constant string - - return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); - } - - Data data_; -}; - -//! GenericValue with UTF8 encoding -typedef GenericValue<UTF8<> > Value; - -/////////////////////////////////////////////////////////////////////////////// -// GenericDocument - -//! A document for parsing JSON text as DOM. -/*! - \note implements Handler concept - \tparam Encoding Encoding for both parsing and string storage. - \tparam Allocator Allocator for allocating memory for the DOM - \tparam StackAllocator Allocator for allocating memory for stack during parsing. - \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. -*/ -template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator> -class GenericDocument : public GenericValue<Encoding, Allocator> { -public: - typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. - typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document. - typedef Allocator AllocatorType; //!< Allocator type from template parameter. - - //! Constructor - /*! Creates an empty document of specified type. - \param type Mandatory type of object to create. - \param allocator Optional allocator for allocating memory. - \param stackCapacity Optional initial capacity of stack in bytes. - \param stackAllocator Optional allocator for allocating memory for stack. - */ - explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : - GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - } - - //! Constructor - /*! Creates an empty document which type is Null. - \param allocator Optional allocator for allocating memory. - \param stackCapacity Optional initial capacity of stack in bytes. - \param stackAllocator Optional allocator for allocating memory for stack. - */ - GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : - allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT - : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document - allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - stack_(std::move(rhs.stack_)), - parseResult_(rhs.parseResult_) - { - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.parseResult_ = ParseResult(); - } -#endif - - ~GenericDocument() { - Destroy(); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move assignment in C++11 - GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT - { - // The cast to ValueType is necessary here, because otherwise it would - // attempt to call GenericValue's templated assignment operator. - ValueType::operator=(std::forward<ValueType>(rhs)); - - // Calling the destructor here would prematurely call stack_'s destructor - Destroy(); - - allocator_ = rhs.allocator_; - ownAllocator_ = rhs.ownAllocator_; - stack_ = std::move(rhs.stack_); - parseResult_ = rhs.parseResult_; - - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.parseResult_ = ParseResult(); - - return *this; - } -#endif - - //! Exchange the contents of this document with those of another. - /*! - \param rhs Another document. - \note Constant complexity. - \see GenericValue::Swap - */ - GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { - ValueType::Swap(rhs); - stack_.Swap(rhs.stack_); - internal::Swap(allocator_, rhs.allocator_); - internal::Swap(ownAllocator_, rhs.ownAllocator_); - internal::Swap(parseResult_, rhs.parseResult_); - return *this; - } - - //! free-standing swap function helper - /*! - Helper function to enable support for common swap implementation pattern based on \c std::swap: - \code - void swap(MyClass& a, MyClass& b) { - using std::swap; - swap(a.doc, b.doc); - // ... - } - \endcode - \see Swap() - */ - friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } - - //! Populate this document by a generator which produces SAX events. - /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype. - \param g Generator functor which sends SAX events to the parameter. - \return The document itself for fluent API. - */ - template <typename Generator> - GenericDocument& Populate(Generator& g) { - ClearStackOnExit scope(*this); - if (g(*this)) { - RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object - ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document - } - return *this; - } - - //!@name Parse from stream - //!@{ - - //! Parse JSON text from an input stream (with Encoding conversion) - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam SourceEncoding Encoding of input stream - \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template <unsigned parseFlags, typename SourceEncoding, typename InputStream> - GenericDocument& ParseStream(InputStream& is) { - GenericReader<SourceEncoding, Encoding, StackAllocator> reader( - stack_.HasAllocator() ? &stack_.GetAllocator() : 0); - ClearStackOnExit scope(*this); - parseResult_ = reader.template Parse<parseFlags>(is, *this); - if (parseResult_) { - RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object - ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document - } - return *this; - } - - //! Parse JSON text from an input stream - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template <unsigned parseFlags, typename InputStream> - GenericDocument& ParseStream(InputStream& is) { - return ParseStream<parseFlags, Encoding, InputStream>(is); - } - - //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) - /*! \tparam InputStream Type of input stream, implementing Stream concept - \param is Input stream to be parsed. - \return The document itself for fluent API. - */ - template <typename InputStream> - GenericDocument& ParseStream(InputStream& is) { - return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is); - } - //!@} - - //!@name Parse in-place from mutable string - //!@{ - - //! Parse JSON text from a mutable string - /*! \tparam parseFlags Combination of \ref ParseFlag. - \param str Mutable zero-terminated string to be parsed. - \return The document itself for fluent API. - */ - template <unsigned parseFlags> - GenericDocument& ParseInsitu(Ch* str) { - GenericInsituStringStream<Encoding> s(str); - return ParseStream<parseFlags | kParseInsituFlag>(s); - } - - //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) - /*! \param str Mutable zero-terminated string to be parsed. - \return The document itself for fluent API. - */ - GenericDocument& ParseInsitu(Ch* str) { - return ParseInsitu<kParseDefaultFlags>(str); - } - //!@} - - //!@name Parse from read-only string - //!@{ - - //! Parse JSON text from a read-only string (with Encoding conversion) - /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). - \tparam SourceEncoding Transcoding from input Encoding - \param str Read-only zero-terminated string to be parsed. - */ - template <unsigned parseFlags, typename SourceEncoding> - GenericDocument& Parse(const typename SourceEncoding::Ch* str) { - RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); - GenericStringStream<SourceEncoding> s(str); - return ParseStream<parseFlags, SourceEncoding>(s); - } - - //! Parse JSON text from a read-only string - /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). - \param str Read-only zero-terminated string to be parsed. - */ - template <unsigned parseFlags> - GenericDocument& Parse(const Ch* str) { - return Parse<parseFlags, Encoding>(str); - } - - //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) - /*! \param str Read-only zero-terminated string to be parsed. - */ - GenericDocument& Parse(const Ch* str) { - return Parse<kParseDefaultFlags>(str); - } - - template <unsigned parseFlags, typename SourceEncoding> - GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { - RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); - MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch)); - EncodedInputStream<SourceEncoding, MemoryStream> is(ms); - ParseStream<parseFlags, SourceEncoding>(is); - return *this; - } - - template <unsigned parseFlags> - GenericDocument& Parse(const Ch* str, size_t length) { - return Parse<parseFlags, Encoding>(str, length); - } - - GenericDocument& Parse(const Ch* str, size_t length) { - return Parse<kParseDefaultFlags>(str, length); - } - -#if RAPIDJSON_HAS_STDSTRING - template <unsigned parseFlags, typename SourceEncoding> - GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) { - // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) - return Parse<parseFlags, SourceEncoding>(str.c_str()); - } - - template <unsigned parseFlags> - GenericDocument& Parse(const std::basic_string<Ch>& str) { - return Parse<parseFlags, Encoding>(str.c_str()); - } - - GenericDocument& Parse(const std::basic_string<Ch>& str) { - return Parse<kParseDefaultFlags>(str); - } -#endif // RAPIDJSON_HAS_STDSTRING - - //!@} - - //!@name Handling parse errors - //!@{ - - //! Whether a parse error has occured in the last parsing. - bool HasParseError() const { return parseResult_.IsError(); } - - //! Get the \ref ParseErrorCode of last parsing. - ParseErrorCode GetParseError() const { return parseResult_.Code(); } - - //! Get the position of last parsing error in input, 0 otherwise. - size_t GetErrorOffset() const { return parseResult_.Offset(); } - - //! Implicit conversion to get the last parse result -#ifndef __clang // -Wdocumentation - /*! \return \ref ParseResult of the last parse operation - - \code - Document doc; - ParseResult ok = doc.Parse(json); - if (!ok) - printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); - \endcode - */ -#endif - operator ParseResult() const { return parseResult_; } - //!@} - - //! Get the allocator of this document. - Allocator& GetAllocator() { - RAPIDJSON_ASSERT(allocator_); - return *allocator_; - } - - //! Get the capacity of stack in bytes. - size_t GetStackCapacity() const { return stack_.GetCapacity(); } - -private: - // clear stack on any exit from ParseStream, e.g. due to exception - struct ClearStackOnExit { - explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} - ~ClearStackOnExit() { d_.ClearStack(); } - private: - ClearStackOnExit(const ClearStackOnExit&); - ClearStackOnExit& operator=(const ClearStackOnExit&); - GenericDocument& d_; - }; - - // callers of the following private Handler functions - // template <typename,typename,typename> friend class GenericReader; // for parsing - template <typename, typename> friend class GenericValue; // for deep copying - -public: - // Implementation of Handler - bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; } - bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; } - bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } - bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } - bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } - bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } - bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; } - - bool RawNumber(const Ch* str, SizeType length, bool copy) { - if (copy) - new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); - else - new (stack_.template Push<ValueType>()) ValueType(str, length); - return true; - } - - bool String(const Ch* str, SizeType length, bool copy) { - if (copy) - new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); - else - new (stack_.template Push<ValueType>()) ValueType(str, length); - return true; - } - - bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; } - - bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } - - bool EndObject(SizeType memberCount) { - typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); - stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator()); - return true; - } - - bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; } - - bool EndArray(SizeType elementCount) { - ValueType* elements = stack_.template Pop<ValueType>(elementCount); - stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); - return true; - } - -private: - //! Prohibit copying - GenericDocument(const GenericDocument&); - //! Prohibit assignment - GenericDocument& operator=(const GenericDocument&); - - void ClearStack() { - if (Allocator::kNeedFree) - while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) - (stack_.template Pop<ValueType>(1))->~ValueType(); - else - stack_.Clear(); - stack_.ShrinkToFit(); - } - - void Destroy() { - RAPIDJSON_DELETE(ownAllocator_); - } - - static const size_t kDefaultStackCapacity = 1024; - Allocator* allocator_; - Allocator* ownAllocator_; - internal::Stack<StackAllocator> stack_; - ParseResult parseResult_; -}; - -//! GenericDocument with UTF8 encoding -typedef GenericDocument<UTF8<> > Document; - -// defined here due to the dependency on GenericDocument -template <typename Encoding, typename Allocator> -template <typename SourceAllocator> -inline -GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) -{ - switch (rhs.GetType()) { - case kObjectType: - case kArrayType: { // perform deep copy via SAX Handler - GenericDocument<Encoding,Allocator> d(&allocator); - rhs.Accept(d); - RawAssign(*d.stack_.template Pop<GenericValue>(1)); - } - break; - case kStringType: - if (rhs.data_.f.flags == kConstStringFlag) { - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast<const Data*>(&rhs.data_); - } else { - SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); - } - break; - default: - data_.f.flags = rhs.data_.f.flags; - data_ = *reinterpret_cast<const Data*>(&rhs.data_); - break; - } -} - -//! Helper class for accessing Value of array type. -/*! - Instance of this helper class is obtained by \c GenericValue::GetArray(). - In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. -*/ -template <bool Const, typename ValueT> -class GenericArray { -public: - typedef GenericArray<true, ValueT> ConstArray; - typedef GenericArray<false, ValueT> Array; - typedef ValueT PlainType; - typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; - typedef ValueType* ValueIterator; // This may be const or non-const iterator - typedef const ValueT* ConstValueIterator; - typedef typename ValueType::AllocatorType AllocatorType; - typedef typename ValueType::StringRefType StringRefType; - - template <typename, typename> - friend class GenericValue; - - GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} - GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } - ~GenericArray() {} - - SizeType Size() const { return value_.Size(); } - SizeType Capacity() const { return value_.Capacity(); } - bool Empty() const { return value_.Empty(); } - void Clear() const { value_.Clear(); } - ValueType& operator[](SizeType index) const { return value_[index]; } - ValueIterator Begin() const { return value_.Begin(); } - ValueIterator End() const { return value_.End(); } - GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } - GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } - template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } - GenericArray PopBack() const { value_.PopBack(); return *this; } - ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } - ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } - -#if RAPIDJSON_HAS_CXX11_RANGE_FOR - ValueIterator begin() const { return value_.Begin(); } - ValueIterator end() const { return value_.End(); } -#endif - -private: - GenericArray(); - GenericArray(ValueType& value) : value_(value) {} - ValueType& value_; -}; - -//! Helper class for accessing Value of object type. -/*! - Instance of this helper class is obtained by \c GenericValue::GetObject(). - In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. -*/ -template <bool Const, typename ValueT> -class GenericObject { -public: - typedef GenericObject<true, ValueT> ConstObject; - typedef GenericObject<false, ValueT> Object; - typedef ValueT PlainType; - typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; - typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator - typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator; - typedef typename ValueType::AllocatorType AllocatorType; - typedef typename ValueType::StringRefType StringRefType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename ValueType::Ch Ch; - - template <typename, typename> - friend class GenericValue; - - GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} - GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } - ~GenericObject() {} - - SizeType MemberCount() const { return value_.MemberCount(); } - bool ObjectEmpty() const { return value_.ObjectEmpty(); } - template <typename T> ValueType& operator[](T* name) const { return value_[name]; } - template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; } -#if RAPIDJSON_HAS_STDSTRING - ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; } -#endif - MemberIterator MemberBegin() const { return value_.MemberBegin(); } - MemberIterator MemberEnd() const { return value_.MemberEnd(); } - bool HasMember(const Ch* name) const { return value_.HasMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); } -#endif - template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); } - MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } - template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); } -#if RAPIDJSON_HAS_STDSTRING - MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); } -#endif - GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#if RAPIDJSON_HAS_STDSTRING - GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#endif - template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } - void RemoveAllMembers() { return value_.RemoveAllMembers(); } - bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); } -#endif - template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); } - MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } - MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } - MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } - bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } -#if RAPIDJSON_HAS_STDSTRING - bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); } -#endif - template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); } - -#if RAPIDJSON_HAS_CXX11_RANGE_FOR - MemberIterator begin() const { return value_.MemberBegin(); } - MemberIterator end() const { return value_.MemberEnd(); } -#endif - -private: - GenericObject(); - GenericObject(ValueType& value) : value_(value) {} - ValueType& value_; -}; - -RAPIDJSON_NAMESPACE_END -RAPIDJSON_DIAG_POP - -#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/external/rapidjson/encodedstream.h b/external/rapidjson/encodedstream.h deleted file mode 100644 index 145068386..000000000 --- a/external/rapidjson/encodedstream.h +++ /dev/null @@ -1,299 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ENCODEDSTREAM_H_ -#define RAPIDJSON_ENCODEDSTREAM_H_ - -#include "stream.h" -#include "memorystream.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Input byte stream wrapper with a statically bound encoding. -/*! - \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. - \tparam InputByteStream Type of input byte stream. For example, FileReadStream. -*/ -template <typename Encoding, typename InputByteStream> -class EncodedInputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); -public: - typedef typename Encoding::Ch Ch; - - EncodedInputStream(InputByteStream& is) : is_(is) { - current_ = Encoding::TakeBOM(is_); - } - - Ch Peek() const { return current_; } - Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } - size_t Tell() const { return is_.Tell(); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - EncodedInputStream(const EncodedInputStream&); - EncodedInputStream& operator=(const EncodedInputStream&); - - InputByteStream& is_; - Ch current_; -}; - -//! Specialized for UTF8 MemoryStream. -template <> -class EncodedInputStream<UTF8<>, MemoryStream> { -public: - typedef UTF8<>::Ch Ch; - - EncodedInputStream(MemoryStream& is) : is_(is) { - if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take(); - if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take(); - if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take(); - } - Ch Peek() const { return is_.Peek(); } - Ch Take() { return is_.Take(); } - size_t Tell() const { return is_.Tell(); } - - // Not implemented - void Put(Ch) {} - void Flush() {} - Ch* PutBegin() { return 0; } - size_t PutEnd(Ch*) { return 0; } - - MemoryStream& is_; - -private: - EncodedInputStream(const EncodedInputStream&); - EncodedInputStream& operator=(const EncodedInputStream&); -}; - -//! Output byte stream wrapper with statically bound encoding. -/*! - \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. - \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. -*/ -template <typename Encoding, typename OutputByteStream> -class EncodedOutputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); -public: - typedef typename Encoding::Ch Ch; - - EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { - if (putBOM) - Encoding::PutBOM(os_); - } - - void Put(Ch c) { Encoding::Put(os_, c); } - void Flush() { os_.Flush(); } - - // Not implemented - Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} - Ch Take() { RAPIDJSON_ASSERT(false); return 0;} - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - EncodedOutputStream(const EncodedOutputStream&); - EncodedOutputStream& operator=(const EncodedOutputStream&); - - OutputByteStream& os_; -}; - -#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x - -//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. -/*! - \tparam CharType Type of character for reading. - \tparam InputByteStream type of input byte stream to be wrapped. -*/ -template <typename CharType, typename InputByteStream> -class AutoUTFInputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); -public: - typedef CharType Ch; - - //! Constructor. - /*! - \param is input stream to be wrapped. - \param type UTF encoding type if it is not detected from the stream. - */ - AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { - RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); - DetectType(); - static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; - takeFunc_ = f[type_]; - current_ = takeFunc_(*is_); - } - - UTFType GetType() const { return type_; } - bool HasBOM() const { return hasBOM_; } - - Ch Peek() const { return current_; } - Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } - size_t Tell() const { return is_->Tell(); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - AutoUTFInputStream(const AutoUTFInputStream&); - AutoUTFInputStream& operator=(const AutoUTFInputStream&); - - // Detect encoding type with BOM or RFC 4627 - void DetectType() { - // BOM (Byte Order Mark): - // 00 00 FE FF UTF-32BE - // FF FE 00 00 UTF-32LE - // FE FF UTF-16BE - // FF FE UTF-16LE - // EF BB BF UTF-8 - - const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4()); - if (!c) - return; - - unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); - hasBOM_ = false; - if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } - else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } - else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } - else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } - else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } - - // RFC 4627: Section 3 - // "Since the first two characters of a JSON text will always be ASCII - // characters [RFC0020], it is possible to determine whether an octet - // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking - // at the pattern of nulls in the first four octets." - // 00 00 00 xx UTF-32BE - // 00 xx 00 xx UTF-16BE - // xx 00 00 00 UTF-32LE - // xx 00 xx 00 UTF-16LE - // xx xx xx xx UTF-8 - - if (!hasBOM_) { - unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); - switch (pattern) { - case 0x08: type_ = kUTF32BE; break; - case 0x0A: type_ = kUTF16BE; break; - case 0x01: type_ = kUTF32LE; break; - case 0x05: type_ = kUTF16LE; break; - case 0x0F: type_ = kUTF8; break; - default: break; // Use type defined by user. - } - } - - // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. - if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); - if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); - } - - typedef Ch (*TakeFunc)(InputByteStream& is); - InputByteStream* is_; - UTFType type_; - Ch current_; - TakeFunc takeFunc_; - bool hasBOM_; -}; - -//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. -/*! - \tparam CharType Type of character for writing. - \tparam OutputByteStream type of output byte stream to be wrapped. -*/ -template <typename CharType, typename OutputByteStream> -class AutoUTFOutputStream { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); -public: - typedef CharType Ch; - - //! Constructor. - /*! - \param os output stream to be wrapped. - \param type UTF encoding type. - \param putBOM Whether to write BOM at the beginning of the stream. - */ - AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { - RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); - - // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. - if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); - if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); - - static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; - putFunc_ = f[type_]; - - if (putBOM) - PutBOM(); - } - - UTFType GetType() const { return type_; } - - void Put(Ch c) { putFunc_(*os_, c); } - void Flush() { os_->Flush(); } - - // Not implemented - Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} - Ch Take() { RAPIDJSON_ASSERT(false); return 0;} - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - AutoUTFOutputStream(const AutoUTFOutputStream&); - AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); - - void PutBOM() { - typedef void (*PutBOMFunc)(OutputByteStream&); - static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; - f[type_](*os_); - } - - typedef void (*PutFunc)(OutputByteStream&, Ch); - - OutputByteStream* os_; - UTFType type_; - PutFunc putFunc_; -}; - -#undef RAPIDJSON_ENCODINGS_FUNC - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/encodings.h b/external/rapidjson/encodings.h deleted file mode 100644 index baa7c2b17..000000000 --- a/external/rapidjson/encodings.h +++ /dev/null @@ -1,716 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ENCODINGS_H_ -#define RAPIDJSON_ENCODINGS_H_ - -#include "rapidjson.h" - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data -RAPIDJSON_DIAG_OFF(4702) // unreachable code -#elif defined(__GNUC__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -RAPIDJSON_DIAG_OFF(overflow) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Encoding - -/*! \class rapidjson::Encoding - \brief Concept for encoding of Unicode characters. - -\code -concept Encoding { - typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. - - enum { supportUnicode = 1 }; // or 0 if not supporting unicode - - //! \brief Encode a Unicode codepoint to an output stream. - //! \param os Output stream. - //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. - template<typename OutputStream> - static void Encode(OutputStream& os, unsigned codepoint); - - //! \brief Decode a Unicode codepoint from an input stream. - //! \param is Input stream. - //! \param codepoint Output of the unicode codepoint. - //! \return true if a valid codepoint can be decoded from the stream. - template <typename InputStream> - static bool Decode(InputStream& is, unsigned* codepoint); - - //! \brief Validate one Unicode codepoint from an encoded stream. - //! \param is Input stream to obtain codepoint. - //! \param os Output for copying one codepoint. - //! \return true if it is valid. - //! \note This function just validating and copying the codepoint without actually decode it. - template <typename InputStream, typename OutputStream> - static bool Validate(InputStream& is, OutputStream& os); - - // The following functions are deal with byte streams. - - //! Take a character from input byte stream, skip BOM if exist. - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is); - - //! Take a character from input byte stream. - template <typename InputByteStream> - static Ch Take(InputByteStream& is); - - //! Put BOM to output byte stream. - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os); - - //! Put a character to output byte stream. - template <typename OutputByteStream> - static void Put(OutputByteStream& os, Ch c); -}; -\endcode -*/ - -/////////////////////////////////////////////////////////////////////////////// -// UTF8 - -//! UTF-8 encoding. -/*! http://en.wikipedia.org/wiki/UTF-8 - http://tools.ietf.org/html/rfc3629 - \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. - \note implements Encoding concept -*/ -template<typename CharType = char> -struct UTF8 { - typedef CharType Ch; - - enum { supportUnicode = 1 }; - - template<typename OutputStream> - static void Encode(OutputStream& os, unsigned codepoint) { - if (codepoint <= 0x7F) - os.Put(static_cast<Ch>(codepoint & 0xFF)); - else if (codepoint <= 0x7FF) { - os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); - os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); - } - else if (codepoint <= 0xFFFF) { - os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); - os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); - os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); - os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); - os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); - os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); - } - } - - template<typename OutputStream> - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - if (codepoint <= 0x7F) - PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); - else if (codepoint <= 0x7FF) { - PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); - PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); - } - else if (codepoint <= 0xFFFF) { - PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); - PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); - PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); - PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); - PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); - PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); - } - } - - template <typename InputStream> - static bool Decode(InputStream& is, unsigned* codepoint) { -#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu) -#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) -#define TAIL() COPY(); TRANS(0x70) - typename InputStream::Ch c = is.Take(); - if (!(c & 0x80)) { - *codepoint = static_cast<unsigned char>(c); - return true; - } - - unsigned char type = GetRange(static_cast<unsigned char>(c)); - if (type >= 32) { - *codepoint = 0; - } else { - *codepoint = (0xFF >> type) & static_cast<unsigned char>(c); - } - bool result = true; - switch (type) { - case 2: TAIL(); return result; - case 3: TAIL(); TAIL(); return result; - case 4: COPY(); TRANS(0x50); TAIL(); return result; - case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; - case 6: TAIL(); TAIL(); TAIL(); return result; - case 10: COPY(); TRANS(0x20); TAIL(); return result; - case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; - default: return false; - } -#undef COPY -#undef TRANS -#undef TAIL - } - - template <typename InputStream, typename OutputStream> - static bool Validate(InputStream& is, OutputStream& os) { -#define COPY() os.Put(c = is.Take()) -#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) -#define TAIL() COPY(); TRANS(0x70) - Ch c; - COPY(); - if (!(c & 0x80)) - return true; - - bool result = true; - switch (GetRange(static_cast<unsigned char>(c))) { - case 2: TAIL(); return result; - case 3: TAIL(); TAIL(); return result; - case 4: COPY(); TRANS(0x50); TAIL(); return result; - case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; - case 6: TAIL(); TAIL(); TAIL(); return result; - case 10: COPY(); TRANS(0x20); TAIL(); return result; - case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; - default: return false; - } -#undef COPY -#undef TRANS -#undef TAIL - } - - static unsigned char GetRange(unsigned char c) { - // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ - // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. - static const unsigned char type[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, - 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - }; - return type[c]; - } - - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - typename InputByteStream::Ch c = Take(is); - if (static_cast<unsigned char>(c) != 0xEFu) return c; - c = is.Take(); - if (static_cast<unsigned char>(c) != 0xBBu) return c; - c = is.Take(); - if (static_cast<unsigned char>(c) != 0xBFu) return c; - c = is.Take(); - return c; - } - - template <typename InputByteStream> - static Ch Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - return static_cast<Ch>(is.Take()); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu)); - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, Ch c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(c)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// UTF16 - -//! UTF-16 encoding. -/*! http://en.wikipedia.org/wiki/UTF-16 - http://tools.ietf.org/html/rfc2781 - \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. - \note implements Encoding concept - - \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. - For streaming, use UTF16LE and UTF16BE, which handle endianness. -*/ -template<typename CharType = wchar_t> -struct UTF16 { - typedef CharType Ch; - RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); - - enum { supportUnicode = 1 }; - - template<typename OutputStream> - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - if (codepoint <= 0xFFFF) { - RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair - os.Put(static_cast<typename OutputStream::Ch>(codepoint)); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - unsigned v = codepoint - 0x10000; - os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); - os.Put((v & 0x3FF) | 0xDC00); - } - } - - - template<typename OutputStream> - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - if (codepoint <= 0xFFFF) { - RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair - PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint)); - } - else { - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - unsigned v = codepoint - 0x10000; - PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); - PutUnsafe(os, (v & 0x3FF) | 0xDC00); - } - } - - template <typename InputStream> - static bool Decode(InputStream& is, unsigned* codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); - typename InputStream::Ch c = is.Take(); - if (c < 0xD800 || c > 0xDFFF) { - *codepoint = static_cast<unsigned>(c); - return true; - } - else if (c <= 0xDBFF) { - *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10; - c = is.Take(); - *codepoint |= (static_cast<unsigned>(c) & 0x3FF); - *codepoint += 0x10000; - return c >= 0xDC00 && c <= 0xDFFF; - } - return false; - } - - template <typename InputStream, typename OutputStream> - static bool Validate(InputStream& is, OutputStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); - typename InputStream::Ch c; - os.Put(static_cast<typename OutputStream::Ch>(c = is.Take())); - if (c < 0xD800 || c > 0xDFFF) - return true; - else if (c <= 0xDBFF) { - os.Put(c = is.Take()); - return c >= 0xDC00 && c <= 0xDFFF; - } - return false; - } -}; - -//! UTF-16 little endian encoding. -template<typename CharType = wchar_t> -struct UTF16LE : UTF16<CharType> { - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; - } - - template <typename InputByteStream> - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast<uint8_t>(is.Take()); - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; - return static_cast<CharType>(c); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); - } -}; - -//! UTF-16 big endian encoding. -template<typename CharType = wchar_t> -struct UTF16BE : UTF16<CharType> { - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; - } - - template <typename InputByteStream> - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; - c |= static_cast<uint8_t>(is.Take()); - return static_cast<CharType>(c); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// UTF32 - -//! UTF-32 encoding. -/*! http://en.wikipedia.org/wiki/UTF-32 - \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. - \note implements Encoding concept - - \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. - For streaming, use UTF32LE and UTF32BE, which handle endianness. -*/ -template<typename CharType = unsigned> -struct UTF32 { - typedef CharType Ch; - RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); - - enum { supportUnicode = 1 }; - - template<typename OutputStream> - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - os.Put(codepoint); - } - - template<typename OutputStream> - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); - RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); - PutUnsafe(os, codepoint); - } - - template <typename InputStream> - static bool Decode(InputStream& is, unsigned* codepoint) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); - Ch c = is.Take(); - *codepoint = c; - return c <= 0x10FFFF; - } - - template <typename InputStream, typename OutputStream> - static bool Validate(InputStream& is, OutputStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); - Ch c; - os.Put(c = is.Take()); - return c <= 0x10FFFF; - } -}; - -//! UTF-32 little endian enocoding. -template<typename CharType = unsigned> -struct UTF32LE : UTF32<CharType> { - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; - } - - template <typename InputByteStream> - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast<uint8_t>(is.Take()); - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; - return static_cast<CharType>(c); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); - os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); - } -}; - -//! UTF-32 big endian encoding. -template<typename CharType = unsigned> -struct UTF32BE : UTF32<CharType> { - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - CharType c = Take(is); - return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; - } - - template <typename InputByteStream> - static CharType Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; - c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())); - return static_cast<CharType>(c); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); - os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); - os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, CharType c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); - os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// ASCII - -//! ASCII encoding. -/*! http://en.wikipedia.org/wiki/ASCII - \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. - \note implements Encoding concept -*/ -template<typename CharType = char> -struct ASCII { - typedef CharType Ch; - - enum { supportUnicode = 0 }; - - template<typename OutputStream> - static void Encode(OutputStream& os, unsigned codepoint) { - RAPIDJSON_ASSERT(codepoint <= 0x7F); - os.Put(static_cast<Ch>(codepoint & 0xFF)); - } - - template<typename OutputStream> - static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - RAPIDJSON_ASSERT(codepoint <= 0x7F); - PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); - } - - template <typename InputStream> - static bool Decode(InputStream& is, unsigned* codepoint) { - uint8_t c = static_cast<uint8_t>(is.Take()); - *codepoint = c; - return c <= 0X7F; - } - - template <typename InputStream, typename OutputStream> - static bool Validate(InputStream& is, OutputStream& os) { - uint8_t c = static_cast<uint8_t>(is.Take()); - os.Put(static_cast<typename OutputStream::Ch>(c)); - return c <= 0x7F; - } - - template <typename InputByteStream> - static CharType TakeBOM(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - uint8_t c = static_cast<uint8_t>(Take(is)); - return static_cast<Ch>(c); - } - - template <typename InputByteStream> - static Ch Take(InputByteStream& is) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); - return static_cast<Ch>(is.Take()); - } - - template <typename OutputByteStream> - static void PutBOM(OutputByteStream& os) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - (void)os; - } - - template <typename OutputByteStream> - static void Put(OutputByteStream& os, Ch c) { - RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); - os.Put(static_cast<typename OutputByteStream::Ch>(c)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// AutoUTF - -//! Runtime-specified UTF encoding type of a stream. -enum UTFType { - kUTF8 = 0, //!< UTF-8. - kUTF16LE = 1, //!< UTF-16 little endian. - kUTF16BE = 2, //!< UTF-16 big endian. - kUTF32LE = 3, //!< UTF-32 little endian. - kUTF32BE = 4 //!< UTF-32 big endian. -}; - -//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. -/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). -*/ -template<typename CharType> -struct AutoUTF { - typedef CharType Ch; - - enum { supportUnicode = 1 }; - -#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x - - template<typename OutputStream> - RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { - typedef void (*EncodeFunc)(OutputStream&, unsigned); - static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; - (*f[os.GetType()])(os, codepoint); - } - - template<typename OutputStream> - RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { - typedef void (*EncodeFunc)(OutputStream&, unsigned); - static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; - (*f[os.GetType()])(os, codepoint); - } - - template <typename InputStream> - RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { - typedef bool (*DecodeFunc)(InputStream&, unsigned*); - static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; - return (*f[is.GetType()])(is, codepoint); - } - - template <typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { - typedef bool (*ValidateFunc)(InputStream&, OutputStream&); - static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; - return (*f[is.GetType()])(is, os); - } - -#undef RAPIDJSON_ENCODINGS_FUNC -}; - -/////////////////////////////////////////////////////////////////////////////// -// Transcoder - -//! Encoding conversion. -template<typename SourceEncoding, typename TargetEncoding> -struct Transcoder { - //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { - unsigned codepoint; - if (!SourceEncoding::Decode(is, &codepoint)) - return false; - TargetEncoding::Encode(os, codepoint); - return true; - } - - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { - unsigned codepoint; - if (!SourceEncoding::Decode(is, &codepoint)) - return false; - TargetEncoding::EncodeUnsafe(os, codepoint); - return true; - } - - //! Validate one Unicode codepoint from an encoded stream. - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { - return Transcode(is, os); // Since source/target encoding is different, must transcode. - } -}; - -// Forward declaration. -template<typename Stream> -inline void PutUnsafe(Stream& stream, typename Stream::Ch c); - -//! Specialization of Transcoder with same source and target encoding. -template<typename Encoding> -struct Transcoder<Encoding, Encoding> { - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { - os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. - return true; - } - - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { - PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. - return true; - } - - template<typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { - return Encoding::Validate(is, os); // source/target encoding are the same - } -}; - -RAPIDJSON_NAMESPACE_END - -#if defined(__GNUC__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/external/rapidjson/error/en.h b/external/rapidjson/error/en.h deleted file mode 100644 index 2db838bff..000000000 --- a/external/rapidjson/error/en.h +++ /dev/null @@ -1,74 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ERROR_EN_H_ -#define RAPIDJSON_ERROR_EN_H_ - -#include "error.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(switch-enum) -RAPIDJSON_DIAG_OFF(covered-switch-default) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Maps error code of parsing into error message. -/*! - \ingroup RAPIDJSON_ERRORS - \param parseErrorCode Error code obtained in parsing. - \return the error message. - \note User can make a copy of this function for localization. - Using switch-case is safer for future modification of error codes. -*/ -inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { - switch (parseErrorCode) { - case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); - - case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); - case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); - - case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); - - case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); - case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); - case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); - - case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); - - case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); - case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); - case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); - case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); - case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); - - case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); - case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); - case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); - - case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); - case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); - - default: return RAPIDJSON_ERROR_STRING("Unknown error."); - } -} - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/external/rapidjson/error/error.h b/external/rapidjson/error/error.h deleted file mode 100644 index 95cb31a72..000000000 --- a/external/rapidjson/error/error.h +++ /dev/null @@ -1,155 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ERROR_ERROR_H_ -#define RAPIDJSON_ERROR_ERROR_H_ - -#include "../rapidjson.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -/*! \file error.h */ - -/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ERROR_CHARTYPE - -//! Character type of error messages. -/*! \ingroup RAPIDJSON_ERRORS - The default character type is \c char. - On Windows, user can define this macro as \c TCHAR for supporting both - unicode/non-unicode settings. -*/ -#ifndef RAPIDJSON_ERROR_CHARTYPE -#define RAPIDJSON_ERROR_CHARTYPE char -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ERROR_STRING - -//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. -/*! \ingroup RAPIDJSON_ERRORS - By default this conversion macro does nothing. - On Windows, user can define this macro as \c _T(x) for supporting both - unicode/non-unicode settings. -*/ -#ifndef RAPIDJSON_ERROR_STRING -#define RAPIDJSON_ERROR_STRING(x) x -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// ParseErrorCode - -//! Error code of parsing. -/*! \ingroup RAPIDJSON_ERRORS - \see GenericReader::Parse, GenericReader::GetParseErrorCode -*/ -enum ParseErrorCode { - kParseErrorNone = 0, //!< No error. - - kParseErrorDocumentEmpty, //!< The document is empty. - kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. - - kParseErrorValueInvalid, //!< Invalid value. - - kParseErrorObjectMissName, //!< Missing a name for object member. - kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. - kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. - - kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. - - kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. - kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. - kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. - kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. - kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. - - kParseErrorNumberTooBig, //!< Number too big to be stored in double. - kParseErrorNumberMissFraction, //!< Miss fraction part in number. - kParseErrorNumberMissExponent, //!< Miss exponent in number. - - kParseErrorTermination, //!< Parsing was terminated. - kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. -}; - -//! Result of parsing (wraps ParseErrorCode) -/*! - \ingroup RAPIDJSON_ERRORS - \code - Document doc; - ParseResult ok = doc.Parse("[42]"); - if (!ok) { - fprintf(stderr, "JSON parse error: %s (%u)", - GetParseError_En(ok.Code()), ok.Offset()); - exit(EXIT_FAILURE); - } - \endcode - \see GenericReader::Parse, GenericDocument::Parse -*/ -struct ParseResult { -public: - //! Default constructor, no error. - ParseResult() : code_(kParseErrorNone), offset_(0) {} - //! Constructor to set an error. - ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} - - //! Get the error code. - ParseErrorCode Code() const { return code_; } - //! Get the error offset, if \ref IsError(), 0 otherwise. - size_t Offset() const { return offset_; } - - //! Conversion to \c bool, returns \c true, iff !\ref IsError(). - operator bool() const { return !IsError(); } - //! Whether the result is an error. - bool IsError() const { return code_ != kParseErrorNone; } - - bool operator==(const ParseResult& that) const { return code_ == that.code_; } - bool operator==(ParseErrorCode code) const { return code_ == code; } - friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } - - //! Reset error code. - void Clear() { Set(kParseErrorNone); } - //! Update error code and offset. - void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } - -private: - ParseErrorCode code_; - size_t offset_; -}; - -//! Function pointer type of GetParseError(). -/*! \ingroup RAPIDJSON_ERRORS - - This is the prototype for \c GetParseError_X(), where \c X is a locale. - User can dynamically change locale in runtime, e.g.: -\code - GetParseErrorFunc GetParseError = GetParseError_En; // or whatever - const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); -\endcode -*/ -typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/external/rapidjson/filereadstream.h b/external/rapidjson/filereadstream.h deleted file mode 100644 index b56ea13b3..000000000 --- a/external/rapidjson/filereadstream.h +++ /dev/null @@ -1,99 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FILEREADSTREAM_H_ -#define RAPIDJSON_FILEREADSTREAM_H_ - -#include "stream.h" -#include <cstdio> - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(missing-noreturn) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! File byte stream for input using fread(). -/*! - \note implements Stream concept -*/ -class FileReadStream { -public: - typedef char Ch; //!< Character type (byte). - - //! Constructor. - /*! - \param fp File pointer opened for read. - \param buffer user-supplied buffer. - \param bufferSize size of buffer in bytes. Must >=4 bytes. - */ - FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { - RAPIDJSON_ASSERT(fp_ != 0); - RAPIDJSON_ASSERT(bufferSize >= 4); - Read(); - } - - Ch Peek() const { return *current_; } - Ch Take() { Ch c = *current_; Read(); return c; } - size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); } - - // Not implemented - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - return (current_ + 4 <= bufferLast_) ? current_ : 0; - } - -private: - void Read() { - if (current_ < bufferLast_) - ++current_; - else if (!eof_) { - count_ += readCount_; - readCount_ = fread(buffer_, 1, bufferSize_, fp_); - bufferLast_ = buffer_ + readCount_ - 1; - current_ = buffer_; - - if (readCount_ < bufferSize_) { - buffer_[readCount_] = '\0'; - ++bufferLast_; - eof_ = true; - } - } - } - - std::FILE* fp_; - Ch *buffer_; - size_t bufferSize_; - Ch *bufferLast_; - Ch *current_; - size_t readCount_; - size_t count_; //!< Number of characters read - bool eof_; -}; - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/filewritestream.h b/external/rapidjson/filewritestream.h deleted file mode 100644 index 6378dd60e..000000000 --- a/external/rapidjson/filewritestream.h +++ /dev/null @@ -1,104 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FILEWRITESTREAM_H_ -#define RAPIDJSON_FILEWRITESTREAM_H_ - -#include "stream.h" -#include <cstdio> - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(unreachable-code) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of C file stream for input using fread(). -/*! - \note implements Stream concept -*/ -class FileWriteStream { -public: - typedef char Ch; //!< Character type. Only support char. - - FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { - RAPIDJSON_ASSERT(fp_ != 0); - } - - void Put(char c) { - if (current_ >= bufferEnd_) - Flush(); - - *current_++ = c; - } - - void PutN(char c, size_t n) { - size_t avail = static_cast<size_t>(bufferEnd_ - current_); - while (n > avail) { - std::memset(current_, c, avail); - current_ += avail; - Flush(); - n -= avail; - avail = static_cast<size_t>(bufferEnd_ - current_); - } - - if (n > 0) { - std::memset(current_, c, n); - current_ += n; - } - } - - void Flush() { - if (current_ != buffer_) { - size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_); - if (result < static_cast<size_t>(current_ - buffer_)) { - // failure deliberately ignored at this time - // added to avoid warn_unused_result build errors - } - current_ = buffer_; - } - } - - // Not implemented - char Peek() const { RAPIDJSON_ASSERT(false); return 0; } - char Take() { RAPIDJSON_ASSERT(false); return 0; } - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - // Prohibit copy constructor & assignment operator. - FileWriteStream(const FileWriteStream&); - FileWriteStream& operator=(const FileWriteStream&); - - std::FILE* fp_; - char *buffer_; - char *bufferEnd_; - char *current_; -}; - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(FileWriteStream& stream, char c, size_t n) { - stream.PutN(c, n); -} - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/external/rapidjson/fwd.h b/external/rapidjson/fwd.h deleted file mode 100644 index e8104e841..000000000 --- a/external/rapidjson/fwd.h +++ /dev/null @@ -1,151 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_FWD_H_ -#define RAPIDJSON_FWD_H_ - -#include "rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN - -// encodings.h - -template<typename CharType> struct UTF8; -template<typename CharType> struct UTF16; -template<typename CharType> struct UTF16BE; -template<typename CharType> struct UTF16LE; -template<typename CharType> struct UTF32; -template<typename CharType> struct UTF32BE; -template<typename CharType> struct UTF32LE; -template<typename CharType> struct ASCII; -template<typename CharType> struct AutoUTF; - -template<typename SourceEncoding, typename TargetEncoding> -struct Transcoder; - -// allocators.h - -class CrtAllocator; - -template <typename BaseAllocator> -class MemoryPoolAllocator; - -// stream.h - -template <typename Encoding> -struct GenericStringStream; - -typedef GenericStringStream<UTF8<char> > StringStream; - -template <typename Encoding> -struct GenericInsituStringStream; - -typedef GenericInsituStringStream<UTF8<char> > InsituStringStream; - -// stringbuffer.h - -template <typename Encoding, typename Allocator> -class GenericStringBuffer; - -typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer; - -// filereadstream.h - -class FileReadStream; - -// filewritestream.h - -class FileWriteStream; - -// memorybuffer.h - -template <typename Allocator> -struct GenericMemoryBuffer; - -typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer; - -// memorystream.h - -struct MemoryStream; - -// reader.h - -template<typename Encoding, typename Derived> -struct BaseReaderHandler; - -template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator> -class GenericReader; - -typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader; - -// writer.h - -template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags> -class Writer; - -// prettywriter.h - -template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags> -class PrettyWriter; - -// document.h - -template <typename Encoding, typename Allocator> -struct GenericMember; - -template <bool Const, typename Encoding, typename Allocator> -class GenericMemberIterator; - -template<typename CharType> -struct GenericStringRef; - -template <typename Encoding, typename Allocator> -class GenericValue; - -typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value; - -template <typename Encoding, typename Allocator, typename StackAllocator> -class GenericDocument; - -typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document; - -// pointer.h - -template <typename ValueType, typename Allocator> -class GenericPointer; - -typedef GenericPointer<Value, CrtAllocator> Pointer; - -// schema.h - -template <typename SchemaDocumentType> -class IGenericRemoteSchemaDocumentProvider; - -template <typename ValueT, typename Allocator> -class GenericSchemaDocument; - -typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument; -typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider; - -template < - typename SchemaDocumentType, - typename OutputHandler, - typename StateAllocator> -class GenericSchemaValidator; - -typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/external/rapidjson/internal/biginteger.h b/external/rapidjson/internal/biginteger.h deleted file mode 100644 index 9d3e88c99..000000000 --- a/external/rapidjson/internal/biginteger.h +++ /dev/null @@ -1,290 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_BIGINTEGER_H_ -#define RAPIDJSON_BIGINTEGER_H_ - -#include "../rapidjson.h" - -#if defined(_MSC_VER) && defined(_M_AMD64) -#include <intrin.h> // for _umul128 -#pragma intrinsic(_umul128) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -class BigInteger { -public: - typedef uint64_t Type; - - BigInteger(const BigInteger& rhs) : count_(rhs.count_) { - std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); - } - - explicit BigInteger(uint64_t u) : count_(1) { - digits_[0] = u; - } - - BigInteger(const char* decimals, size_t length) : count_(1) { - RAPIDJSON_ASSERT(length > 0); - digits_[0] = 0; - size_t i = 0; - const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 - while (length >= kMaxDigitPerIteration) { - AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); - length -= kMaxDigitPerIteration; - i += kMaxDigitPerIteration; - } - - if (length > 0) - AppendDecimal64(decimals + i, decimals + i + length); - } - - BigInteger& operator=(const BigInteger &rhs) - { - if (this != &rhs) { - count_ = rhs.count_; - std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); - } - return *this; - } - - BigInteger& operator=(uint64_t u) { - digits_[0] = u; - count_ = 1; - return *this; - } - - BigInteger& operator+=(uint64_t u) { - Type backup = digits_[0]; - digits_[0] += u; - for (size_t i = 0; i < count_ - 1; i++) { - if (digits_[i] >= backup) - return *this; // no carry - backup = digits_[i + 1]; - digits_[i + 1] += 1; - } - - // Last carry - if (digits_[count_ - 1] < backup) - PushBack(1); - - return *this; - } - - BigInteger& operator*=(uint64_t u) { - if (u == 0) return *this = 0; - if (u == 1) return *this; - if (*this == 1) return *this = u; - - uint64_t k = 0; - for (size_t i = 0; i < count_; i++) { - uint64_t hi; - digits_[i] = MulAdd64(digits_[i], u, k, &hi); - k = hi; - } - - if (k > 0) - PushBack(k); - - return *this; - } - - BigInteger& operator*=(uint32_t u) { - if (u == 0) return *this = 0; - if (u == 1) return *this; - if (*this == 1) return *this = u; - - uint64_t k = 0; - for (size_t i = 0; i < count_; i++) { - const uint64_t c = digits_[i] >> 32; - const uint64_t d = digits_[i] & 0xFFFFFFFF; - const uint64_t uc = u * c; - const uint64_t ud = u * d; - const uint64_t p0 = ud + k; - const uint64_t p1 = uc + (p0 >> 32); - digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); - k = p1 >> 32; - } - - if (k > 0) - PushBack(k); - - return *this; - } - - BigInteger& operator<<=(size_t shift) { - if (IsZero() || shift == 0) return *this; - - size_t offset = shift / kTypeBit; - size_t interShift = shift % kTypeBit; - RAPIDJSON_ASSERT(count_ + offset <= kCapacity); - - if (interShift == 0) { - std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); - count_ += offset; - } - else { - digits_[count_] = 0; - for (size_t i = count_; i > 0; i--) - digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); - digits_[offset] = digits_[0] << interShift; - count_ += offset; - if (digits_[count_]) - count_++; - } - - std::memset(digits_, 0, offset * sizeof(Type)); - - return *this; - } - - bool operator==(const BigInteger& rhs) const { - return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; - } - - bool operator==(const Type rhs) const { - return count_ == 1 && digits_[0] == rhs; - } - - BigInteger& MultiplyPow5(unsigned exp) { - static const uint32_t kPow5[12] = { - 5, - 5 * 5, - 5 * 5 * 5, - 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, - 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 - }; - if (exp == 0) return *this; - for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 - for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13 - if (exp > 0) *this *= kPow5[exp - 1]; - return *this; - } - - // Compute absolute difference of this and rhs. - // Assume this != rhs - bool Difference(const BigInteger& rhs, BigInteger* out) const { - int cmp = Compare(rhs); - RAPIDJSON_ASSERT(cmp != 0); - const BigInteger *a, *b; // Makes a > b - bool ret; - if (cmp < 0) { a = &rhs; b = this; ret = true; } - else { a = this; b = &rhs; ret = false; } - - Type borrow = 0; - for (size_t i = 0; i < a->count_; i++) { - Type d = a->digits_[i] - borrow; - if (i < b->count_) - d -= b->digits_[i]; - borrow = (d > a->digits_[i]) ? 1 : 0; - out->digits_[i] = d; - if (d != 0) - out->count_ = i + 1; - } - - return ret; - } - - int Compare(const BigInteger& rhs) const { - if (count_ != rhs.count_) - return count_ < rhs.count_ ? -1 : 1; - - for (size_t i = count_; i-- > 0;) - if (digits_[i] != rhs.digits_[i]) - return digits_[i] < rhs.digits_[i] ? -1 : 1; - - return 0; - } - - size_t GetCount() const { return count_; } - Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } - bool IsZero() const { return count_ == 1 && digits_[0] == 0; } - -private: - void AppendDecimal64(const char* begin, const char* end) { - uint64_t u = ParseUint64(begin, end); - if (IsZero()) - *this = u; - else { - unsigned exp = static_cast<unsigned>(end - begin); - (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u - } - } - - void PushBack(Type digit) { - RAPIDJSON_ASSERT(count_ < kCapacity); - digits_[count_++] = digit; - } - - static uint64_t ParseUint64(const char* begin, const char* end) { - uint64_t r = 0; - for (const char* p = begin; p != end; ++p) { - RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); - r = r * 10u + static_cast<unsigned>(*p - '0'); - } - return r; - } - - // Assume a * b + k < 2^128 - static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { -#if defined(_MSC_VER) && defined(_M_AMD64) - uint64_t low = _umul128(a, b, outHigh) + k; - if (low < k) - (*outHigh)++; - return low; -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) - __extension__ typedef unsigned __int128 uint128; - uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b); - p += k; - *outHigh = static_cast<uint64_t>(p >> 64); - return static_cast<uint64_t>(p); -#else - const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; - uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; - x1 += (x0 >> 32); // can't give carry - x1 += x2; - if (x1 < x2) - x3 += (static_cast<uint64_t>(1) << 32); - uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); - uint64_t hi = x3 + (x1 >> 32); - - lo += k; - if (lo < k) - hi++; - *outHigh = hi; - return lo; -#endif - } - - static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 - static const size_t kCapacity = kBitCount / sizeof(Type); - static const size_t kTypeBit = sizeof(Type) * 8; - - Type digits_[kCapacity]; - size_t count_; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/external/rapidjson/internal/diyfp.h b/external/rapidjson/internal/diyfp.h deleted file mode 100644 index c9fefdc61..000000000 --- a/external/rapidjson/internal/diyfp.h +++ /dev/null @@ -1,258 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -// This is a C++ header-only implementation of Grisu2 algorithm from the publication: -// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with -// integers." ACM Sigplan Notices 45.6 (2010): 233-243. - -#ifndef RAPIDJSON_DIYFP_H_ -#define RAPIDJSON_DIYFP_H_ - -#include "../rapidjson.h" - -#if defined(_MSC_VER) && defined(_M_AMD64) -#include <intrin.h> -#pragma intrinsic(_BitScanReverse64) -#pragma intrinsic(_umul128) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -struct DiyFp { - DiyFp() : f(), e() {} - - DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} - - explicit DiyFp(double d) { - union { - double d; - uint64_t u64; - } u = { d }; - - int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize); - uint64_t significand = (u.u64 & kDpSignificandMask); - if (biased_e != 0) { - f = significand + kDpHiddenBit; - e = biased_e - kDpExponentBias; - } - else { - f = significand; - e = kDpMinExponent + 1; - } - } - - DiyFp operator-(const DiyFp& rhs) const { - return DiyFp(f - rhs.f, e); - } - - DiyFp operator*(const DiyFp& rhs) const { -#if defined(_MSC_VER) && defined(_M_AMD64) - uint64_t h; - uint64_t l = _umul128(f, rhs.f, &h); - if (l & (uint64_t(1) << 63)) // rounding - h++; - return DiyFp(h, e + rhs.e + 64); -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) - __extension__ typedef unsigned __int128 uint128; - uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f); - uint64_t h = static_cast<uint64_t>(p >> 64); - uint64_t l = static_cast<uint64_t>(p); - if (l & (uint64_t(1) << 63)) // rounding - h++; - return DiyFp(h, e + rhs.e + 64); -#else - const uint64_t M32 = 0xFFFFFFFF; - const uint64_t a = f >> 32; - const uint64_t b = f & M32; - const uint64_t c = rhs.f >> 32; - const uint64_t d = rhs.f & M32; - const uint64_t ac = a * c; - const uint64_t bc = b * c; - const uint64_t ad = a * d; - const uint64_t bd = b * d; - uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); - tmp += 1U << 31; /// mult_round - return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); -#endif - } - - DiyFp Normalize() const { -#if defined(_MSC_VER) && defined(_M_AMD64) - unsigned long index; - _BitScanReverse64(&index, f); - return DiyFp(f << (63 - index), e - (63 - index)); -#elif defined(__GNUC__) && __GNUC__ >= 4 - int s = __builtin_clzll(f); - return DiyFp(f << s, e - s); -#else - DiyFp res = *this; - while (!(res.f & (static_cast<uint64_t>(1) << 63))) { - res.f <<= 1; - res.e--; - } - return res; -#endif - } - - DiyFp NormalizeBoundary() const { - DiyFp res = *this; - while (!(res.f & (kDpHiddenBit << 1))) { - res.f <<= 1; - res.e--; - } - res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); - res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); - return res; - } - - void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { - DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); - DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); - mi.f <<= mi.e - pl.e; - mi.e = pl.e; - *plus = pl; - *minus = mi; - } - - double ToDouble() const { - union { - double d; - uint64_t u64; - }u; - const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : - static_cast<uint64_t>(e + kDpExponentBias); - u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); - return u.d; - } - - static const int kDiySignificandSize = 64; - static const int kDpSignificandSize = 52; - static const int kDpExponentBias = 0x3FF + kDpSignificandSize; - static const int kDpMaxExponent = 0x7FF - kDpExponentBias; - static const int kDpMinExponent = -kDpExponentBias; - static const int kDpDenormalExponent = -kDpExponentBias + 1; - static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); - - uint64_t f; - int e; -}; - -inline DiyFp GetCachedPowerByIndex(size_t index) { - // 10^-348, 10^-340, ..., 10^340 - static const uint64_t kCachedPowers_F[] = { - RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), - RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), - RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), - RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), - RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), - RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), - RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), - RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), - RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), - RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), - RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), - RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), - RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), - RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), - RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), - RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), - RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), - RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), - RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), - RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), - RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), - RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), - RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), - RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), - RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), - RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), - RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), - RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), - RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), - RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), - RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), - RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), - RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), - RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), - RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), - RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), - RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), - RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), - RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), - RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), - RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), - RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), - RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), - RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) - }; - static const int16_t kCachedPowers_E[] = { - -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, - -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, - -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, - -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, - -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, - 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, - 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, - 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, - 907, 933, 960, 986, 1013, 1039, 1066 - }; - return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); -} - -inline DiyFp GetCachedPower(int e, int* K) { - - //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374; - double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive - int k = static_cast<int>(dk); - if (dk - k > 0.0) - k++; - - unsigned index = static_cast<unsigned>((k >> 3) + 1); - *K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table - - return GetCachedPowerByIndex(index); -} - -inline DiyFp GetCachedPower10(int exp, int *outExp) { - unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u; - *outExp = -348 + static_cast<int>(index) * 8; - return GetCachedPowerByIndex(index); - } - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -RAPIDJSON_DIAG_OFF(padded) -#endif - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_DIYFP_H_ diff --git a/external/rapidjson/internal/dtoa.h b/external/rapidjson/internal/dtoa.h deleted file mode 100644 index 8d6350e62..000000000 --- a/external/rapidjson/internal/dtoa.h +++ /dev/null @@ -1,245 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -// This is a C++ header-only implementation of Grisu2 algorithm from the publication: -// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with -// integers." ACM Sigplan Notices 45.6 (2010): 233-243. - -#ifndef RAPIDJSON_DTOA_ -#define RAPIDJSON_DTOA_ - -#include "itoa.h" // GetDigitsLut() -#include "diyfp.h" -#include "ieee754.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 -#endif - -inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { - while (rest < wp_w && delta - rest >= ten_kappa && - (rest + ten_kappa < wp_w || /// closer - wp_w - rest > rest + ten_kappa - wp_w)) { - buffer[len - 1]--; - rest += ten_kappa; - } -} - -inline unsigned CountDecimalDigit32(uint32_t n) { - // Simple pure C++ implementation was faster than __builtin_clz version in this situation. - if (n < 10) return 1; - if (n < 100) return 2; - if (n < 1000) return 3; - if (n < 10000) return 4; - if (n < 100000) return 5; - if (n < 1000000) return 6; - if (n < 10000000) return 7; - if (n < 100000000) return 8; - // Will not reach 10 digits in DigitGen() - //if (n < 1000000000) return 9; - //return 10; - return 9; -} - -inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { - static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; - const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); - const DiyFp wp_w = Mp - W; - uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e); - uint64_t p2 = Mp.f & (one.f - 1); - unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] - *len = 0; - - while (kappa > 0) { - uint32_t d = 0; - switch (kappa) { - case 9: d = p1 / 100000000; p1 %= 100000000; break; - case 8: d = p1 / 10000000; p1 %= 10000000; break; - case 7: d = p1 / 1000000; p1 %= 1000000; break; - case 6: d = p1 / 100000; p1 %= 100000; break; - case 5: d = p1 / 10000; p1 %= 10000; break; - case 4: d = p1 / 1000; p1 %= 1000; break; - case 3: d = p1 / 100; p1 %= 100; break; - case 2: d = p1 / 10; p1 %= 10; break; - case 1: d = p1; p1 = 0; break; - default:; - } - if (d || *len) - buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d)); - kappa--; - uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2; - if (tmp <= delta) { - *K += kappa; - GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f); - return; - } - } - - // kappa = 0 - for (;;) { - p2 *= 10; - delta *= 10; - char d = static_cast<char>(p2 >> -one.e); - if (d || *len) - buffer[(*len)++] = static_cast<char>('0' + d); - p2 &= one.f - 1; - kappa--; - if (p2 < delta) { - *K += kappa; - int index = -static_cast<int>(kappa); - GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast<int>(kappa)] : 0)); - return; - } - } -} - -inline void Grisu2(double value, char* buffer, int* length, int* K) { - const DiyFp v(value); - DiyFp w_m, w_p; - v.NormalizedBoundaries(&w_m, &w_p); - - const DiyFp c_mk = GetCachedPower(w_p.e, K); - const DiyFp W = v.Normalize() * c_mk; - DiyFp Wp = w_p * c_mk; - DiyFp Wm = w_m * c_mk; - Wm.f++; - Wp.f--; - DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); -} - -inline char* WriteExponent(int K, char* buffer) { - if (K < 0) { - *buffer++ = '-'; - K = -K; - } - - if (K >= 100) { - *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100)); - K %= 100; - const char* d = GetDigitsLut() + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else if (K >= 10) { - const char* d = GetDigitsLut() + K * 2; - *buffer++ = d[0]; - *buffer++ = d[1]; - } - else - *buffer++ = static_cast<char>('0' + static_cast<char>(K)); - - return buffer; -} - -inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { - const int kk = length + k; // 10^(kk-1) <= v < 10^kk - - if (0 <= k && kk <= 21) { - // 1234e7 -> 12340000000 - for (int i = length; i < kk; i++) - buffer[i] = '0'; - buffer[kk] = '.'; - buffer[kk + 1] = '0'; - return &buffer[kk + 2]; - } - else if (0 < kk && kk <= 21) { - // 1234e-2 -> 12.34 - std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk)); - buffer[kk] = '.'; - if (0 > k + maxDecimalPlaces) { - // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 - // Remove extra trailing zeros (at least one) after truncation. - for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) - if (buffer[i] != '0') - return &buffer[i + 1]; - return &buffer[kk + 2]; // Reserve one zero - } - else - return &buffer[length + 1]; - } - else if (-6 < kk && kk <= 0) { - // 1234e-6 -> 0.001234 - const int offset = 2 - kk; - std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length)); - buffer[0] = '0'; - buffer[1] = '.'; - for (int i = 2; i < offset; i++) - buffer[i] = '0'; - if (length - kk > maxDecimalPlaces) { - // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 - // Remove extra trailing zeros (at least one) after truncation. - for (int i = maxDecimalPlaces + 1; i > 2; i--) - if (buffer[i] != '0') - return &buffer[i + 1]; - return &buffer[3]; // Reserve one zero - } - else - return &buffer[length + offset]; - } - else if (kk < -maxDecimalPlaces) { - // Truncate to zero - buffer[0] = '0'; - buffer[1] = '.'; - buffer[2] = '0'; - return &buffer[3]; - } - else if (length == 1) { - // 1e30 - buffer[1] = 'e'; - return WriteExponent(kk - 1, &buffer[2]); - } - else { - // 1234e30 -> 1.234e33 - std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1)); - buffer[1] = '.'; - buffer[length + 1] = 'e'; - return WriteExponent(kk - 1, &buffer[0 + length + 2]); - } -} - -inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { - RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); - Double d(value); - if (d.IsZero()) { - if (d.Sign()) - *buffer++ = '-'; // -0.0, Issue #289 - buffer[0] = '0'; - buffer[1] = '.'; - buffer[2] = '0'; - return &buffer[3]; - } - else { - if (value < 0) { - *buffer++ = '-'; - value = -value; - } - int length, K; - Grisu2(value, buffer, &length, &K); - return Prettify(buffer, length, K, maxDecimalPlaces); - } -} - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_DTOA_ diff --git a/external/rapidjson/internal/ieee754.h b/external/rapidjson/internal/ieee754.h deleted file mode 100644 index 82bb0b99e..000000000 --- a/external/rapidjson/internal/ieee754.h +++ /dev/null @@ -1,78 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_IEEE754_ -#define RAPIDJSON_IEEE754_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -class Double { -public: - Double() {} - Double(double d) : d_(d) {} - Double(uint64_t u) : u_(u) {} - - double Value() const { return d_; } - uint64_t Uint64Value() const { return u_; } - - double NextPositiveDouble() const { - RAPIDJSON_ASSERT(!Sign()); - return Double(u_ + 1).Value(); - } - - bool Sign() const { return (u_ & kSignMask) != 0; } - uint64_t Significand() const { return u_ & kSignificandMask; } - int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } - - bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } - bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } - bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } - bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } - bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } - - uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } - int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } - uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } - - static unsigned EffectiveSignificandSize(int order) { - if (order >= -1021) - return 53; - else if (order <= -1074) - return 0; - else - return static_cast<unsigned>(order) + 1074; - } - -private: - static const int kSignificandSize = 52; - static const int kExponentBias = 0x3FF; - static const int kDenormalExponent = 1 - kExponentBias; - static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); - static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); - static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); - static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); - - union { - double d_; - uint64_t u_; - }; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_IEEE754_ diff --git a/external/rapidjson/internal/itoa.h b/external/rapidjson/internal/itoa.h deleted file mode 100644 index 01a4e7e72..000000000 --- a/external/rapidjson/internal/itoa.h +++ /dev/null @@ -1,304 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ITOA_ -#define RAPIDJSON_ITOA_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -inline const char* GetDigitsLut() { - static const char cDigitsLut[200] = { - '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', - '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', - '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', - '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', - '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', - '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', - '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', - '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', - '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', - '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' - }; - return cDigitsLut; -} - -inline char* u32toa(uint32_t value, char* buffer) { - const char* cDigitsLut = GetDigitsLut(); - - if (value < 10000) { - const uint32_t d1 = (value / 100) << 1; - const uint32_t d2 = (value % 100) << 1; - - if (value >= 1000) - *buffer++ = cDigitsLut[d1]; - if (value >= 100) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 10) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - } - else if (value < 100000000) { - // value = bbbbcccc - const uint32_t b = value / 10000; - const uint32_t c = value % 10000; - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - if (value >= 10000000) - *buffer++ = cDigitsLut[d1]; - if (value >= 1000000) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 100000) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - else { - // value = aabbbbcccc in decimal - - const uint32_t a = value / 100000000; // 1 to 42 - value %= 100000000; - - if (a >= 10) { - const unsigned i = a << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else - *buffer++ = static_cast<char>('0' + static_cast<char>(a)); - - const uint32_t b = value / 10000; // 0 to 9999 - const uint32_t c = value % 10000; // 0 to 9999 - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - *buffer++ = cDigitsLut[d1]; - *buffer++ = cDigitsLut[d1 + 1]; - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - return buffer; -} - -inline char* i32toa(int32_t value, char* buffer) { - uint32_t u = static_cast<uint32_t>(value); - if (value < 0) { - *buffer++ = '-'; - u = ~u + 1; - } - - return u32toa(u, buffer); -} - -inline char* u64toa(uint64_t value, char* buffer) { - const char* cDigitsLut = GetDigitsLut(); - const uint64_t kTen8 = 100000000; - const uint64_t kTen9 = kTen8 * 10; - const uint64_t kTen10 = kTen8 * 100; - const uint64_t kTen11 = kTen8 * 1000; - const uint64_t kTen12 = kTen8 * 10000; - const uint64_t kTen13 = kTen8 * 100000; - const uint64_t kTen14 = kTen8 * 1000000; - const uint64_t kTen15 = kTen8 * 10000000; - const uint64_t kTen16 = kTen8 * kTen8; - - if (value < kTen8) { - uint32_t v = static_cast<uint32_t>(value); - if (v < 10000) { - const uint32_t d1 = (v / 100) << 1; - const uint32_t d2 = (v % 100) << 1; - - if (v >= 1000) - *buffer++ = cDigitsLut[d1]; - if (v >= 100) - *buffer++ = cDigitsLut[d1 + 1]; - if (v >= 10) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - } - else { - // value = bbbbcccc - const uint32_t b = v / 10000; - const uint32_t c = v % 10000; - - const uint32_t d1 = (b / 100) << 1; - const uint32_t d2 = (b % 100) << 1; - - const uint32_t d3 = (c / 100) << 1; - const uint32_t d4 = (c % 100) << 1; - - if (value >= 10000000) - *buffer++ = cDigitsLut[d1]; - if (value >= 1000000) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= 100000) - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - } - } - else if (value < kTen16) { - const uint32_t v0 = static_cast<uint32_t>(value / kTen8); - const uint32_t v1 = static_cast<uint32_t>(value % kTen8); - - const uint32_t b0 = v0 / 10000; - const uint32_t c0 = v0 % 10000; - - const uint32_t d1 = (b0 / 100) << 1; - const uint32_t d2 = (b0 % 100) << 1; - - const uint32_t d3 = (c0 / 100) << 1; - const uint32_t d4 = (c0 % 100) << 1; - - const uint32_t b1 = v1 / 10000; - const uint32_t c1 = v1 % 10000; - - const uint32_t d5 = (b1 / 100) << 1; - const uint32_t d6 = (b1 % 100) << 1; - - const uint32_t d7 = (c1 / 100) << 1; - const uint32_t d8 = (c1 % 100) << 1; - - if (value >= kTen15) - *buffer++ = cDigitsLut[d1]; - if (value >= kTen14) - *buffer++ = cDigitsLut[d1 + 1]; - if (value >= kTen13) - *buffer++ = cDigitsLut[d2]; - if (value >= kTen12) - *buffer++ = cDigitsLut[d2 + 1]; - if (value >= kTen11) - *buffer++ = cDigitsLut[d3]; - if (value >= kTen10) - *buffer++ = cDigitsLut[d3 + 1]; - if (value >= kTen9) - *buffer++ = cDigitsLut[d4]; - if (value >= kTen8) - *buffer++ = cDigitsLut[d4 + 1]; - - *buffer++ = cDigitsLut[d5]; - *buffer++ = cDigitsLut[d5 + 1]; - *buffer++ = cDigitsLut[d6]; - *buffer++ = cDigitsLut[d6 + 1]; - *buffer++ = cDigitsLut[d7]; - *buffer++ = cDigitsLut[d7 + 1]; - *buffer++ = cDigitsLut[d8]; - *buffer++ = cDigitsLut[d8 + 1]; - } - else { - const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844 - value %= kTen16; - - if (a < 10) - *buffer++ = static_cast<char>('0' + static_cast<char>(a)); - else if (a < 100) { - const uint32_t i = a << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else if (a < 1000) { - *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100)); - - const uint32_t i = (a % 100) << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - } - else { - const uint32_t i = (a / 100) << 1; - const uint32_t j = (a % 100) << 1; - *buffer++ = cDigitsLut[i]; - *buffer++ = cDigitsLut[i + 1]; - *buffer++ = cDigitsLut[j]; - *buffer++ = cDigitsLut[j + 1]; - } - - const uint32_t v0 = static_cast<uint32_t>(value / kTen8); - const uint32_t v1 = static_cast<uint32_t>(value % kTen8); - - const uint32_t b0 = v0 / 10000; - const uint32_t c0 = v0 % 10000; - - const uint32_t d1 = (b0 / 100) << 1; - const uint32_t d2 = (b0 % 100) << 1; - - const uint32_t d3 = (c0 / 100) << 1; - const uint32_t d4 = (c0 % 100) << 1; - - const uint32_t b1 = v1 / 10000; - const uint32_t c1 = v1 % 10000; - - const uint32_t d5 = (b1 / 100) << 1; - const uint32_t d6 = (b1 % 100) << 1; - - const uint32_t d7 = (c1 / 100) << 1; - const uint32_t d8 = (c1 % 100) << 1; - - *buffer++ = cDigitsLut[d1]; - *buffer++ = cDigitsLut[d1 + 1]; - *buffer++ = cDigitsLut[d2]; - *buffer++ = cDigitsLut[d2 + 1]; - *buffer++ = cDigitsLut[d3]; - *buffer++ = cDigitsLut[d3 + 1]; - *buffer++ = cDigitsLut[d4]; - *buffer++ = cDigitsLut[d4 + 1]; - *buffer++ = cDigitsLut[d5]; - *buffer++ = cDigitsLut[d5 + 1]; - *buffer++ = cDigitsLut[d6]; - *buffer++ = cDigitsLut[d6 + 1]; - *buffer++ = cDigitsLut[d7]; - *buffer++ = cDigitsLut[d7 + 1]; - *buffer++ = cDigitsLut[d8]; - *buffer++ = cDigitsLut[d8 + 1]; - } - - return buffer; -} - -inline char* i64toa(int64_t value, char* buffer) { - uint64_t u = static_cast<uint64_t>(value); - if (value < 0) { - *buffer++ = '-'; - u = ~u + 1; - } - - return u64toa(u, buffer); -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ITOA_ diff --git a/external/rapidjson/internal/meta.h b/external/rapidjson/internal/meta.h deleted file mode 100644 index 5a9aaa428..000000000 --- a/external/rapidjson/internal/meta.h +++ /dev/null @@ -1,181 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_META_H_ -#define RAPIDJSON_INTERNAL_META_H_ - -#include "../rapidjson.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif -#if defined(_MSC_VER) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(6334) -#endif - -#if RAPIDJSON_HAS_CXX11_TYPETRAITS -#include <type_traits> -#endif - -//@cond RAPIDJSON_INTERNAL -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching -template <typename T> struct Void { typedef void Type; }; - -/////////////////////////////////////////////////////////////////////////////// -// BoolType, TrueType, FalseType -// -template <bool Cond> struct BoolType { - static const bool Value = Cond; - typedef BoolType Type; -}; -typedef BoolType<true> TrueType; -typedef BoolType<false> FalseType; - - -/////////////////////////////////////////////////////////////////////////////// -// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr -// - -template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; }; -template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; }; -template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {}; -template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {}; - -template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {}; -template <> struct AndExprCond<true, true> : TrueType {}; -template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {}; -template <> struct OrExprCond<false, false> : FalseType {}; - -template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {}; -template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {}; -template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {}; -template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {}; - - -/////////////////////////////////////////////////////////////////////////////// -// AddConst, MaybeAddConst, RemoveConst -template <typename T> struct AddConst { typedef const T Type; }; -template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {}; -template <typename T> struct RemoveConst { typedef T Type; }; -template <typename T> struct RemoveConst<const T> { typedef T Type; }; - - -/////////////////////////////////////////////////////////////////////////////// -// IsSame, IsConst, IsMoreConst, IsPointer -// -template <typename T, typename U> struct IsSame : FalseType {}; -template <typename T> struct IsSame<T, T> : TrueType {}; - -template <typename T> struct IsConst : FalseType {}; -template <typename T> struct IsConst<const T> : TrueType {}; - -template <typename CT, typename T> -struct IsMoreConst - : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>, - BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {}; - -template <typename T> struct IsPointer : FalseType {}; -template <typename T> struct IsPointer<T*> : TrueType {}; - -/////////////////////////////////////////////////////////////////////////////// -// IsBaseOf -// -#if RAPIDJSON_HAS_CXX11_TYPETRAITS - -template <typename B, typename D> struct IsBaseOf - : BoolType< ::std::is_base_of<B,D>::value> {}; - -#else // simplified version adopted from Boost - -template<typename B, typename D> struct IsBaseOfImpl { - RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); - RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); - - typedef char (&Yes)[1]; - typedef char (&No) [2]; - - template <typename T> - static Yes Check(const D*, T); - static No Check(const B*, int); - - struct Host { - operator const B*() const; - operator const D*(); - }; - - enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; -}; - -template <typename B, typename D> struct IsBaseOf - : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {}; - -#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS - - -////////////////////////////////////////////////////////////////////////// -// EnableIf / DisableIf -// -template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; }; -template <typename T> struct EnableIfCond<false, T> { /* empty */ }; - -template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; }; -template <typename T> struct DisableIfCond<true, T> { /* empty */ }; - -template <typename Condition, typename T = void> -struct EnableIf : EnableIfCond<Condition::Value, T> {}; - -template <typename Condition, typename T = void> -struct DisableIf : DisableIfCond<Condition::Value, T> {}; - -// SFINAE helpers -struct SfinaeTag {}; -template <typename T> struct RemoveSfinaeTag; -template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; }; - -#define RAPIDJSON_REMOVEFPTR_(type) \ - typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ - < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type - -#define RAPIDJSON_ENABLEIF(cond) \ - typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ - <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL - -#define RAPIDJSON_DISABLEIF(cond) \ - typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ - <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL - -#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ - typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ - <RAPIDJSON_REMOVEFPTR_(cond), \ - RAPIDJSON_REMOVEFPTR_(returntype)>::Type - -#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ - typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ - <RAPIDJSON_REMOVEFPTR_(cond), \ - RAPIDJSON_REMOVEFPTR_(returntype)>::Type - -} // namespace internal -RAPIDJSON_NAMESPACE_END -//@endcond - -#if defined(__GNUC__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/external/rapidjson/internal/pow10.h b/external/rapidjson/internal/pow10.h deleted file mode 100644 index 02f475d70..000000000 --- a/external/rapidjson/internal/pow10.h +++ /dev/null @@ -1,55 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_POW10_ -#define RAPIDJSON_POW10_ - -#include "../rapidjson.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Computes integer powers of 10 in double (10.0^n). -/*! This function uses lookup table for fast and accurate results. - \param n non-negative exponent. Must <= 308. - \return 10.0^n -*/ -inline double Pow10(int n) { - static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes - 1e+0, - 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, - 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, - 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, - 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, - 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, - 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, - 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, - 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, - 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, - 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, - 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, - 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, - 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, - 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, - 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, - 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 - }; - RAPIDJSON_ASSERT(n >= 0 && n <= 308); - return e[n]; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_POW10_ diff --git a/external/rapidjson/internal/regex.h b/external/rapidjson/internal/regex.h deleted file mode 100644 index 8530cd771..000000000 --- a/external/rapidjson/internal/regex.h +++ /dev/null @@ -1,731 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_REGEX_H_ -#define RAPIDJSON_INTERNAL_REGEX_H_ - -#include "../allocators.h" -#include "../stream.h" -#include "stack.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -RAPIDJSON_DIAG_OFF(implicit-fallthrough) -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -#ifndef RAPIDJSON_REGEX_VERBOSE -#define RAPIDJSON_REGEX_VERBOSE 0 -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -/////////////////////////////////////////////////////////////////////////////// -// DecodedStream - -template <typename SourceStream, typename Encoding> -class DecodedStream { -public: - DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } - unsigned Peek() { return codepoint_; } - unsigned Take() { - unsigned c = codepoint_; - if (c) // No further decoding when '\0' - Decode(); - return c; - } - -private: - void Decode() { - if (!Encoding::Decode(ss_, &codepoint_)) - codepoint_ = 0; - } - - SourceStream& ss_; - unsigned codepoint_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericRegex - -static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 -static const SizeType kRegexInvalidRange = ~SizeType(0); - -template <typename Encoding, typename Allocator> -class GenericRegexSearch; - -//! Regular expression engine with subset of ECMAscript grammar. -/*! - Supported regular expression syntax: - - \c ab Concatenation - - \c a|b Alternation - - \c a? Zero or one - - \c a* Zero or more - - \c a+ One or more - - \c a{3} Exactly 3 times - - \c a{3,} At least 3 times - - \c a{3,5} 3 to 5 times - - \c (ab) Grouping - - \c ^a At the beginning - - \c a$ At the end - - \c . Any character - - \c [abc] Character classes - - \c [a-c] Character class range - - \c [a-z0-9_] Character class combination - - \c [^abc] Negated character classes - - \c [^a-c] Negated character class range - - \c [\b] Backspace (U+0008) - - \c \\| \\\\ ... Escape characters - - \c \\f Form feed (U+000C) - - \c \\n Line feed (U+000A) - - \c \\r Carriage return (U+000D) - - \c \\t Tab (U+0009) - - \c \\v Vertical tab (U+000B) - - \note This is a Thompson NFA engine, implemented with reference to - Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", - https://swtch.com/~rsc/regexp/regexp1.html -*/ -template <typename Encoding, typename Allocator = CrtAllocator> -class GenericRegex { -public: - typedef Encoding EncodingType; - typedef typename Encoding::Ch Ch; - template <typename, typename> friend class GenericRegexSearch; - - GenericRegex(const Ch* source, Allocator* allocator = 0) : - states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), - anchorBegin_(), anchorEnd_() - { - GenericStringStream<Encoding> ss(source); - DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss); - Parse(ds); - } - - ~GenericRegex() {} - - bool IsValid() const { - return root_ != kRegexInvalidState; - } - -private: - enum Operator { - kZeroOrOne, - kZeroOrMore, - kOneOrMore, - kConcatenation, - kAlternation, - kLeftParenthesis - }; - - static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' - static const unsigned kRangeCharacterClass = 0xFFFFFFFE; - static const unsigned kRangeNegationFlag = 0x80000000; - - struct Range { - unsigned start; // - unsigned end; - SizeType next; - }; - - struct State { - SizeType out; //!< Equals to kInvalid for matching state - SizeType out1; //!< Equals to non-kInvalid for split - SizeType rangeStart; - unsigned codepoint; - }; - - struct Frag { - Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} - SizeType start; - SizeType out; //!< link-list of all output states - SizeType minIndex; - }; - - State& GetState(SizeType index) { - RAPIDJSON_ASSERT(index < stateCount_); - return states_.template Bottom<State>()[index]; - } - - const State& GetState(SizeType index) const { - RAPIDJSON_ASSERT(index < stateCount_); - return states_.template Bottom<State>()[index]; - } - - Range& GetRange(SizeType index) { - RAPIDJSON_ASSERT(index < rangeCount_); - return ranges_.template Bottom<Range>()[index]; - } - - const Range& GetRange(SizeType index) const { - RAPIDJSON_ASSERT(index < rangeCount_); - return ranges_.template Bottom<Range>()[index]; - } - - template <typename InputStream> - void Parse(DecodedStream<InputStream, Encoding>& ds) { - Allocator allocator; - Stack<Allocator> operandStack(&allocator, 256); // Frag - Stack<Allocator> operatorStack(&allocator, 256); // Operator - Stack<Allocator> atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis) - - *atomCountStack.template Push<unsigned>() = 0; - - unsigned codepoint; - while (ds.Peek() != 0) { - switch (codepoint = ds.Take()) { - case '^': - anchorBegin_ = true; - break; - - case '$': - anchorEnd_ = true; - break; - - case '|': - while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation) - if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1))) - return; - *operatorStack.template Push<Operator>() = kAlternation; - *atomCountStack.template Top<unsigned>() = 0; - break; - - case '(': - *operatorStack.template Push<Operator>() = kLeftParenthesis; - *atomCountStack.template Push<unsigned>() = 0; - break; - - case ')': - while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis) - if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1))) - return; - if (operatorStack.Empty()) - return; - operatorStack.template Pop<Operator>(1); - atomCountStack.template Pop<unsigned>(1); - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '?': - if (!Eval(operandStack, kZeroOrOne)) - return; - break; - - case '*': - if (!Eval(operandStack, kZeroOrMore)) - return; - break; - - case '+': - if (!Eval(operandStack, kOneOrMore)) - return; - break; - - case '{': - { - unsigned n, m; - if (!ParseUnsigned(ds, &n)) - return; - - if (ds.Peek() == ',') { - ds.Take(); - if (ds.Peek() == '}') - m = kInfinityQuantifier; - else if (!ParseUnsigned(ds, &m) || m < n) - return; - } - else - m = n; - - if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') - return; - ds.Take(); - } - break; - - case '.': - PushOperand(operandStack, kAnyCharacterClass); - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '[': - { - SizeType range; - if (!ParseRange(ds, &range)) - return; - SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); - GetState(s).rangeStart = range; - *operandStack.template Push<Frag>() = Frag(s, s, s); - } - ImplicitConcatenation(atomCountStack, operatorStack); - break; - - case '\\': // Escape character - if (!CharacterEscape(ds, &codepoint)) - return; // Unsupported escape character - // fall through to default - - default: // Pattern character - PushOperand(operandStack, codepoint); - ImplicitConcatenation(atomCountStack, operatorStack); - } - } - - while (!operatorStack.Empty()) - if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1))) - return; - - // Link the operand to matching state. - if (operandStack.GetSize() == sizeof(Frag)) { - Frag* e = operandStack.template Pop<Frag>(1); - Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); - root_ = e->start; - -#if RAPIDJSON_REGEX_VERBOSE - printf("root: %d\n", root_); - for (SizeType i = 0; i < stateCount_ ; i++) { - State& s = GetState(i); - printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); - } - printf("\n"); -#endif - } - } - - SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { - State* s = states_.template Push<State>(); - s->out = out; - s->out1 = out1; - s->codepoint = codepoint; - s->rangeStart = kRegexInvalidRange; - return stateCount_++; - } - - void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) { - SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); - *operandStack.template Push<Frag>() = Frag(s, s, s); - } - - void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) { - if (*atomCountStack.template Top<unsigned>()) - *operatorStack.template Push<Operator>() = kConcatenation; - (*atomCountStack.template Top<unsigned>())++; - } - - SizeType Append(SizeType l1, SizeType l2) { - SizeType old = l1; - while (GetState(l1).out != kRegexInvalidState) - l1 = GetState(l1).out; - GetState(l1).out = l2; - return old; - } - - void Patch(SizeType l, SizeType s) { - for (SizeType next; l != kRegexInvalidState; l = next) { - next = GetState(l).out; - GetState(l).out = s; - } - } - - bool Eval(Stack<Allocator>& operandStack, Operator op) { - switch (op) { - case kConcatenation: - RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); - { - Frag e2 = *operandStack.template Pop<Frag>(1); - Frag e1 = *operandStack.template Pop<Frag>(1); - Patch(e1.out, e2.start); - *operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); - } - return true; - - case kAlternation: - if (operandStack.GetSize() >= sizeof(Frag) * 2) { - Frag e2 = *operandStack.template Pop<Frag>(1); - Frag e1 = *operandStack.template Pop<Frag>(1); - SizeType s = NewState(e1.start, e2.start, 0); - *operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); - return true; - } - return false; - - case kZeroOrOne: - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop<Frag>(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - *operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex); - return true; - } - return false; - - case kZeroOrMore: - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop<Frag>(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - Patch(e.out, s); - *operandStack.template Push<Frag>() = Frag(s, s, e.minIndex); - return true; - } - return false; - - default: - RAPIDJSON_ASSERT(op == kOneOrMore); - if (operandStack.GetSize() >= sizeof(Frag)) { - Frag e = *operandStack.template Pop<Frag>(1); - SizeType s = NewState(kRegexInvalidState, e.start, 0); - Patch(e.out, s); - *operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex); - return true; - } - return false; - } - } - - bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) { - RAPIDJSON_ASSERT(n <= m); - RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); - - if (n == 0) { - if (m == 0) // a{0} not support - return false; - else if (m == kInfinityQuantifier) - Eval(operandStack, kZeroOrMore); // a{0,} -> a* - else { - Eval(operandStack, kZeroOrOne); // a{0,5} -> a? - for (unsigned i = 0; i < m - 1; i++) - CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? - for (unsigned i = 0; i < m - 1; i++) - Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? - } - return true; - } - - for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a - CloneTopOperand(operandStack); - - if (m == kInfinityQuantifier) - Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ - else if (m > n) { - CloneTopOperand(operandStack); // a{3,5} -> a a a a - Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? - for (unsigned i = n; i < m - 1; i++) - CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? - for (unsigned i = n; i < m; i++) - Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? - } - - for (unsigned i = 0; i < n - 1; i++) - Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? - - return true; - } - - static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } - - void CloneTopOperand(Stack<Allocator>& operandStack) { - const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation - SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) - State* s = states_.template Push<State>(count); - memcpy(s, &GetState(src.minIndex), count * sizeof(State)); - for (SizeType j = 0; j < count; j++) { - if (s[j].out != kRegexInvalidState) - s[j].out += count; - if (s[j].out1 != kRegexInvalidState) - s[j].out1 += count; - } - *operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count); - stateCount_ += count; - } - - template <typename InputStream> - bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) { - unsigned r = 0; - if (ds.Peek() < '0' || ds.Peek() > '9') - return false; - while (ds.Peek() >= '0' && ds.Peek() <= '9') { - if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 - return false; // overflow - r = r * 10 + (ds.Take() - '0'); - } - *u = r; - return true; - } - - template <typename InputStream> - bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) { - bool isBegin = true; - bool negate = false; - int step = 0; - SizeType start = kRegexInvalidRange; - SizeType current = kRegexInvalidRange; - unsigned codepoint; - while ((codepoint = ds.Take()) != 0) { - if (isBegin) { - isBegin = false; - if (codepoint == '^') { - negate = true; - continue; - } - } - - switch (codepoint) { - case ']': - if (start == kRegexInvalidRange) - return false; // Error: nothing inside [] - if (step == 2) { // Add trailing '-' - SizeType r = NewRange('-'); - RAPIDJSON_ASSERT(current != kRegexInvalidRange); - GetRange(current).next = r; - } - if (negate) - GetRange(start).start |= kRangeNegationFlag; - *range = start; - return true; - - case '\\': - if (ds.Peek() == 'b') { - ds.Take(); - codepoint = 0x0008; // Escape backspace character - } - else if (!CharacterEscape(ds, &codepoint)) - return false; - // fall through to default - - default: - switch (step) { - case 1: - if (codepoint == '-') { - step++; - break; - } - // fall through to step 0 for other characters - - case 0: - { - SizeType r = NewRange(codepoint); - if (current != kRegexInvalidRange) - GetRange(current).next = r; - if (start == kRegexInvalidRange) - start = r; - current = r; - } - step = 1; - break; - - default: - RAPIDJSON_ASSERT(step == 2); - GetRange(current).end = codepoint; - step = 0; - } - } - } - return false; - } - - SizeType NewRange(unsigned codepoint) { - Range* r = ranges_.template Push<Range>(); - r->start = r->end = codepoint; - r->next = kRegexInvalidRange; - return rangeCount_++; - } - - template <typename InputStream> - bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) { - unsigned codepoint; - switch (codepoint = ds.Take()) { - case '^': - case '$': - case '|': - case '(': - case ')': - case '?': - case '*': - case '+': - case '.': - case '[': - case ']': - case '{': - case '}': - case '\\': - *escapedCodepoint = codepoint; return true; - case 'f': *escapedCodepoint = 0x000C; return true; - case 'n': *escapedCodepoint = 0x000A; return true; - case 'r': *escapedCodepoint = 0x000D; return true; - case 't': *escapedCodepoint = 0x0009; return true; - case 'v': *escapedCodepoint = 0x000B; return true; - default: - return false; // Unsupported escape character - } - } - - Stack<Allocator> states_; - Stack<Allocator> ranges_; - SizeType root_; - SizeType stateCount_; - SizeType rangeCount_; - - static const unsigned kInfinityQuantifier = ~0u; - - // For SearchWithAnchoring() - bool anchorBegin_; - bool anchorEnd_; -}; - -template <typename RegexType, typename Allocator = CrtAllocator> -class GenericRegexSearch { -public: - typedef typename RegexType::EncodingType Encoding; - typedef typename Encoding::Ch Ch; - - GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) : - regex_(regex), allocator_(allocator), ownAllocator_(0), - state0_(allocator, 0), state1_(allocator, 0), stateSet_() - { - RAPIDJSON_ASSERT(regex_.IsValid()); - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize())); - state0_.template Reserve<SizeType>(regex_.stateCount_); - state1_.template Reserve<SizeType>(regex_.stateCount_); - } - - ~GenericRegexSearch() { - Allocator::Free(stateSet_); - RAPIDJSON_DELETE(ownAllocator_); - } - - template <typename InputStream> - bool Match(InputStream& is) { - return SearchWithAnchoring(is, true, true); - } - - bool Match(const Ch* s) { - GenericStringStream<Encoding> is(s); - return Match(is); - } - - template <typename InputStream> - bool Search(InputStream& is) { - return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_); - } - - bool Search(const Ch* s) { - GenericStringStream<Encoding> is(s); - return Search(is); - } - -private: - typedef typename RegexType::State State; - typedef typename RegexType::Range Range; - - template <typename InputStream> - bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) { - DecodedStream<InputStream, Encoding> ds(is); - - state0_.Clear(); - Stack<Allocator> *current = &state0_, *next = &state1_; - const size_t stateSetSize = GetStateSetSize(); - std::memset(stateSet_, 0, stateSetSize); - - bool matched = AddState(*current, regex_.root_); - unsigned codepoint; - while (!current->Empty() && (codepoint = ds.Take()) != 0) { - std::memset(stateSet_, 0, stateSetSize); - next->Clear(); - matched = false; - for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) { - const State& sr = regex_.GetState(*s); - if (sr.codepoint == codepoint || - sr.codepoint == RegexType::kAnyCharacterClass || - (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) - { - matched = AddState(*next, sr.out) || matched; - if (!anchorEnd && matched) - return true; - } - if (!anchorBegin) - AddState(*next, regex_.root_); - } - internal::Swap(current, next); - } - - return matched; - } - - size_t GetStateSetSize() const { - return (regex_.stateCount_ + 31) / 32 * 4; - } - - // Return whether the added states is a match state - bool AddState(Stack<Allocator>& l, SizeType index) { - RAPIDJSON_ASSERT(index != kRegexInvalidState); - - const State& s = regex_.GetState(index); - if (s.out1 != kRegexInvalidState) { // Split - bool matched = AddState(l, s.out); - return AddState(l, s.out1) || matched; - } - else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { - stateSet_[index >> 5] |= (1 << (index & 31)); - *l.template PushUnsafe<SizeType>() = index; - } - return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. - } - - bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { - bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0; - while (rangeIndex != kRegexInvalidRange) { - const Range& r = regex_.GetRange(rangeIndex); - if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end) - return yes; - rangeIndex = r.next; - } - return !yes; - } - - const RegexType& regex_; - Allocator* allocator_; - Allocator* ownAllocator_; - Stack<Allocator> state0_; - Stack<Allocator> state1_; - uint32_t* stateSet_; -}; - -typedef GenericRegex<UTF8<> > Regex; -typedef GenericRegexSearch<Regex> RegexSearch; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/external/rapidjson/internal/stack.h b/external/rapidjson/internal/stack.h deleted file mode 100644 index 022c9aab4..000000000 --- a/external/rapidjson/internal/stack.h +++ /dev/null @@ -1,230 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_STACK_H_ -#define RAPIDJSON_INTERNAL_STACK_H_ - -#include "../allocators.h" -#include "swap.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -/////////////////////////////////////////////////////////////////////////////// -// Stack - -//! A type-unsafe stack for storing different types of data. -/*! \tparam Allocator Allocator for allocating stack memory. -*/ -template <typename Allocator> -class Stack { -public: - // Optimization note: Do not allocate memory for stack_ in constructor. - // Do it lazily when first Push() -> Expand() -> Resize(). - Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Stack(Stack&& rhs) - : allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - stack_(rhs.stack_), - stackTop_(rhs.stackTop_), - stackEnd_(rhs.stackEnd_), - initialCapacity_(rhs.initialCapacity_) - { - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.stack_ = 0; - rhs.stackTop_ = 0; - rhs.stackEnd_ = 0; - rhs.initialCapacity_ = 0; - } -#endif - - ~Stack() { - Destroy(); - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - Stack& operator=(Stack&& rhs) { - if (&rhs != this) - { - Destroy(); - - allocator_ = rhs.allocator_; - ownAllocator_ = rhs.ownAllocator_; - stack_ = rhs.stack_; - stackTop_ = rhs.stackTop_; - stackEnd_ = rhs.stackEnd_; - initialCapacity_ = rhs.initialCapacity_; - - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - rhs.stack_ = 0; - rhs.stackTop_ = 0; - rhs.stackEnd_ = 0; - rhs.initialCapacity_ = 0; - } - return *this; - } -#endif - - void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { - internal::Swap(allocator_, rhs.allocator_); - internal::Swap(ownAllocator_, rhs.ownAllocator_); - internal::Swap(stack_, rhs.stack_); - internal::Swap(stackTop_, rhs.stackTop_); - internal::Swap(stackEnd_, rhs.stackEnd_); - internal::Swap(initialCapacity_, rhs.initialCapacity_); - } - - void Clear() { stackTop_ = stack_; } - - void ShrinkToFit() { - if (Empty()) { - // If the stack is empty, completely deallocate the memory. - Allocator::Free(stack_); - stack_ = 0; - stackTop_ = 0; - stackEnd_ = 0; - } - else - Resize(GetSize()); - } - - // Optimization note: try to minimize the size of this function for force inline. - // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. - template<typename T> - RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { - // Expand the stack if needed - if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) - Expand<T>(count); - } - - template<typename T> - RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { - Reserve<T>(count); - return PushUnsafe<T>(count); - } - - template<typename T> - RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { - RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); - T* ret = reinterpret_cast<T*>(stackTop_); - stackTop_ += sizeof(T) * count; - return ret; - } - - template<typename T> - T* Pop(size_t count) { - RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); - stackTop_ -= count * sizeof(T); - return reinterpret_cast<T*>(stackTop_); - } - - template<typename T> - T* Top() { - RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); - return reinterpret_cast<T*>(stackTop_ - sizeof(T)); - } - - template<typename T> - const T* Top() const { - RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); - return reinterpret_cast<T*>(stackTop_ - sizeof(T)); - } - - template<typename T> - T* End() { return reinterpret_cast<T*>(stackTop_); } - - template<typename T> - const T* End() const { return reinterpret_cast<T*>(stackTop_); } - - template<typename T> - T* Bottom() { return reinterpret_cast<T*>(stack_); } - - template<typename T> - const T* Bottom() const { return reinterpret_cast<T*>(stack_); } - - bool HasAllocator() const { - return allocator_ != 0; - } - - Allocator& GetAllocator() { - RAPIDJSON_ASSERT(allocator_); - return *allocator_; - } - - bool Empty() const { return stackTop_ == stack_; } - size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); } - size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); } - -private: - template<typename T> - void Expand(size_t count) { - // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. - size_t newCapacity; - if (stack_ == 0) { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - newCapacity = initialCapacity_; - } else { - newCapacity = GetCapacity(); - newCapacity += (newCapacity + 1) / 2; - } - size_t newSize = GetSize() + sizeof(T) * count; - if (newCapacity < newSize) - newCapacity = newSize; - - Resize(newCapacity); - } - - void Resize(size_t newCapacity) { - const size_t size = GetSize(); // Backup the current size - stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); - stackTop_ = stack_ + size; - stackEnd_ = stack_ + newCapacity; - } - - void Destroy() { - Allocator::Free(stack_); - RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack - } - - // Prohibit copy constructor & assignment operator. - Stack(const Stack&); - Stack& operator=(const Stack&); - - Allocator* allocator_; - Allocator* ownAllocator_; - char *stack_; - char *stackTop_; - char *stackEnd_; - size_t initialCapacity_; -}; - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_STACK_H_ diff --git a/external/rapidjson/internal/strfunc.h b/external/rapidjson/internal/strfunc.h deleted file mode 100644 index de41d8f9c..000000000 --- a/external/rapidjson/internal/strfunc.h +++ /dev/null @@ -1,58 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ -#define RAPIDJSON_INTERNAL_STRFUNC_H_ - -#include "../stream.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Custom strlen() which works on different character types. -/*! \tparam Ch Character type (e.g. char, wchar_t, short) - \param s Null-terminated input string. - \return Number of characters in the string. - \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. -*/ -template <typename Ch> -inline SizeType StrLen(const Ch* s) { - RAPIDJSON_ASSERT(s != 0); - const Ch* p = s; - while (*p) ++p; - return SizeType(p - s); -} - -//! Returns number of code points in a encoded string. -template<typename Encoding> -bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { - RAPIDJSON_ASSERT(s != 0); - RAPIDJSON_ASSERT(outCount != 0); - GenericStringStream<Encoding> is(s); - const typename Encoding::Ch* end = s + length; - SizeType count = 0; - while (is.src_ < end) { - unsigned codepoint; - if (!Encoding::Decode(is, &codepoint)) - return false; - count++; - } - *outCount = count; - return true; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/external/rapidjson/internal/strtod.h b/external/rapidjson/internal/strtod.h deleted file mode 100644 index 289c413b0..000000000 --- a/external/rapidjson/internal/strtod.h +++ /dev/null @@ -1,269 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_STRTOD_ -#define RAPIDJSON_STRTOD_ - -#include "ieee754.h" -#include "biginteger.h" -#include "diyfp.h" -#include "pow10.h" - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -inline double FastPath(double significand, int exp) { - if (exp < -308) - return 0.0; - else if (exp >= 0) - return significand * internal::Pow10(exp); - else - return significand / internal::Pow10(-exp); -} - -inline double StrtodNormalPrecision(double d, int p) { - if (p < -308) { - // Prevent expSum < -308, making Pow10(p) = 0 - d = FastPath(d, -308); - d = FastPath(d, p + 308); - } - else - d = FastPath(d, p); - return d; -} - -template <typename T> -inline T Min3(T a, T b, T c) { - T m = a; - if (m > b) m = b; - if (m > c) m = c; - return m; -} - -inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { - const Double db(b); - const uint64_t bInt = db.IntegerSignificand(); - const int bExp = db.IntegerExponent(); - const int hExp = bExp - 1; - - int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; - - // Adjust for decimal exponent - if (dExp >= 0) { - dS_Exp2 += dExp; - dS_Exp5 += dExp; - } - else { - bS_Exp2 -= dExp; - bS_Exp5 -= dExp; - hS_Exp2 -= dExp; - hS_Exp5 -= dExp; - } - - // Adjust for binary exponent - if (bExp >= 0) - bS_Exp2 += bExp; - else { - dS_Exp2 -= bExp; - hS_Exp2 -= bExp; - } - - // Adjust for half ulp exponent - if (hExp >= 0) - hS_Exp2 += hExp; - else { - dS_Exp2 -= hExp; - bS_Exp2 -= hExp; - } - - // Remove common power of two factor from all three scaled values - int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); - dS_Exp2 -= common_Exp2; - bS_Exp2 -= common_Exp2; - hS_Exp2 -= common_Exp2; - - BigInteger dS = d; - dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2); - - BigInteger bS(bInt); - bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2); - - BigInteger hS(1); - hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2); - - BigInteger delta(0); - dS.Difference(bS, &delta); - - return delta.Compare(hS); -} - -inline bool StrtodFast(double d, int p, double* result) { - // Use fast path for string-to-double conversion if possible - // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ - if (p > 22 && p < 22 + 16) { - // Fast Path Cases In Disguise - d *= internal::Pow10(p - 22); - p = 22; - } - - if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 - *result = FastPath(d, p); - return true; - } - else - return false; -} - -// Compute an approximation and see if it is within 1/2 ULP -inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { - uint64_t significand = 0; - size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 - for (; i < length; i++) { - if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || - (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) - break; - significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0'); - } - - if (i < length && decimals[i] >= '5') // Rounding - significand++; - - size_t remaining = length - i; - const unsigned kUlpShift = 3; - const unsigned kUlp = 1 << kUlpShift; - int64_t error = (remaining == 0) ? 0 : kUlp / 2; - - DiyFp v(significand, 0); - v = v.Normalize(); - error <<= -v.e; - - const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp; - - int actualExp; - DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); - if (actualExp != dExp) { - static const DiyFp kPow10[] = { - DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 - DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 - DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 - DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 - DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 - DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 - DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 - }; - int adjustment = dExp - actualExp - 1; - RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); - v = v * kPow10[adjustment]; - if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit - error += kUlp / 2; - } - - v = v * cachedPower; - - error += kUlp + (error == 0 ? 0 : 1); - - const int oldExp = v.e; - v = v.Normalize(); - error <<= oldExp - v.e; - - const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); - unsigned precisionSize = 64 - effectiveSignificandSize; - if (precisionSize + kUlpShift >= 64) { - unsigned scaleExp = (precisionSize + kUlpShift) - 63; - v.f >>= scaleExp; - v.e += scaleExp; - error = (error >> scaleExp) + 1 + static_cast<int>(kUlp); - precisionSize -= scaleExp; - } - - DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize)); - const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; - const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; - if (precisionBits >= halfWay + static_cast<unsigned>(error)) { - rounded.f++; - if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) - rounded.f >>= 1; - rounded.e++; - } - } - - *result = rounded.ToDouble(); - - return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error); -} - -inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { - const BigInteger dInt(decimals, length); - const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp; - Double a(approx); - int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); - if (cmp < 0) - return a.Value(); // within half ULP - else if (cmp == 0) { - // Round towards even - if (a.Significand() & 1) - return a.NextPositiveDouble(); - else - return a.Value(); - } - else // adjustment - return a.NextPositiveDouble(); -} - -inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { - RAPIDJSON_ASSERT(d >= 0.0); - RAPIDJSON_ASSERT(length >= 1); - - double result; - if (StrtodFast(d, p, &result)) - return result; - - // Trim leading zeros - while (*decimals == '0' && length > 1) { - length--; - decimals++; - decimalPosition--; - } - - // Trim trailing zeros - while (decimals[length - 1] == '0' && length > 1) { - length--; - decimalPosition--; - exp++; - } - - // Trim right-most digits - const int kMaxDecimalDigit = 780; - if (static_cast<int>(length) > kMaxDecimalDigit) { - int delta = (static_cast<int>(length) - kMaxDecimalDigit); - exp += delta; - decimalPosition -= static_cast<unsigned>(delta); - length = kMaxDecimalDigit; - } - - // If too small, underflow to zero - if (int(length) + exp < -324) - return 0.0; - - if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) - return result; - - // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison - return StrtodBigInteger(result, decimals, length, decimalPosition, exp); -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_STRTOD_ diff --git a/external/rapidjson/internal/swap.h b/external/rapidjson/internal/swap.h deleted file mode 100644 index 666e49f97..000000000 --- a/external/rapidjson/internal/swap.h +++ /dev/null @@ -1,46 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_INTERNAL_SWAP_H_ -#define RAPIDJSON_INTERNAL_SWAP_H_ - -#include "../rapidjson.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN -namespace internal { - -//! Custom swap() to avoid dependency on C++ <algorithm> header -/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. - \note This has the same semantics as std::swap(). -*/ -template <typename T> -inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { - T tmp = a; - a = b; - b = tmp; -} - -} // namespace internal -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/external/rapidjson/istreamwrapper.h b/external/rapidjson/istreamwrapper.h deleted file mode 100644 index f5fe28977..000000000 --- a/external/rapidjson/istreamwrapper.h +++ /dev/null @@ -1,115 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ -#define RAPIDJSON_ISTREAMWRAPPER_H_ - -#include "stream.h" -#include <iosfwd> - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. -/*! - The classes can be wrapped including but not limited to: - - - \c std::istringstream - - \c std::stringstream - - \c std::wistringstream - - \c std::wstringstream - - \c std::ifstream - - \c std::fstream - - \c std::wifstream - - \c std::wfstream - - \tparam StreamType Class derived from \c std::basic_istream. -*/ - -template <typename StreamType> -class BasicIStreamWrapper { -public: - typedef typename StreamType::char_type Ch; - BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} - - Ch Peek() const { - typename StreamType::int_type c = stream_.peek(); - return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : '\0'; - } - - Ch Take() { - typename StreamType::int_type c = stream_.get(); - if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { - count_++; - return static_cast<Ch>(c); - } - else - return '\0'; - } - - // tellg() may return -1 when failed. So we count by ourself. - size_t Tell() const { return count_; } - - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. - int i; - bool hasError = false; - for (i = 0; i < 4; ++i) { - typename StreamType::int_type c = stream_.get(); - if (c == StreamType::traits_type::eof()) { - hasError = true; - stream_.clear(); - break; - } - peekBuffer_[i] = static_cast<Ch>(c); - } - for (--i; i >= 0; --i) - stream_.putback(peekBuffer_[i]); - return !hasError ? peekBuffer_ : 0; - } - -private: - BasicIStreamWrapper(const BasicIStreamWrapper&); - BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); - - StreamType& stream_; - size_t count_; //!< Number of characters read. Note: - mutable Ch peekBuffer_[4]; -}; - -typedef BasicIStreamWrapper<std::istream> IStreamWrapper; -typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper; - -#if defined(__clang__) || defined(_MSC_VER) -RAPIDJSON_DIAG_POP -#endif - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/external/rapidjson/memorybuffer.h b/external/rapidjson/memorybuffer.h deleted file mode 100644 index 39bee1dec..000000000 --- a/external/rapidjson/memorybuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_MEMORYBUFFER_H_ -#define RAPIDJSON_MEMORYBUFFER_H_ - -#include "stream.h" -#include "internal/stack.h" - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory output byte stream. -/*! - This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. - - It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. - - Differences between MemoryBuffer and StringBuffer: - 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. - 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. - - \tparam Allocator type for allocating memory buffer. - \note implements Stream concept -*/ -template <typename Allocator = CrtAllocator> -struct GenericMemoryBuffer { - typedef char Ch; // byte - - GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - - void Put(Ch c) { *stack_.template Push<Ch>() = c; } - void Flush() {} - - void Clear() { stack_.Clear(); } - void ShrinkToFit() { stack_.ShrinkToFit(); } - Ch* Push(size_t count) { return stack_.template Push<Ch>(count); } - void Pop(size_t count) { stack_.template Pop<Ch>(count); } - - const Ch* GetBuffer() const { - return stack_.template Bottom<Ch>(); - } - - size_t GetSize() const { return stack_.GetSize(); } - - static const size_t kDefaultCapacity = 256; - mutable internal::Stack<Allocator> stack_; -}; - -typedef GenericMemoryBuffer<> MemoryBuffer; - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { - std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c)); -} - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/external/rapidjson/memorystream.h b/external/rapidjson/memorystream.h deleted file mode 100644 index 1d71d8a4f..000000000 --- a/external/rapidjson/memorystream.h +++ /dev/null @@ -1,71 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_MEMORYSTREAM_H_ -#define RAPIDJSON_MEMORYSTREAM_H_ - -#include "stream.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(unreachable-code) -RAPIDJSON_DIAG_OFF(missing-noreturn) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory input byte stream. -/*! - This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. - - It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. - - Differences between MemoryStream and StringStream: - 1. StringStream has encoding but MemoryStream is a byte stream. - 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. - 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). - \note implements Stream concept -*/ -struct MemoryStream { - typedef char Ch; // byte - - MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} - - Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } - Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } - size_t Tell() const { return static_cast<size_t>(src_ - begin_); } - - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - // For encoding detection only. - const Ch* Peek4() const { - return Tell() + 4 <= size_ ? src_ : 0; - } - - const Ch* src_; //!< Current read position. - const Ch* begin_; //!< Original head of the string. - const Ch* end_; //!< End of stream. - size_t size_; //!< Size of the stream. -}; - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/external/rapidjson/msinttypes/inttypes.h b/external/rapidjson/msinttypes/inttypes.h deleted file mode 100644 index 18111286b..000000000 --- a/external/rapidjson/msinttypes/inttypes.h +++ /dev/null @@ -1,316 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 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. Neither the name of the product nor the names of its contributors 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. -// -/////////////////////////////////////////////////////////////////////////////// - -// The above software in this distribution may have been modified by -// THL A29 Limited ("Tencent Modifications"). -// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// miloyip: VC supports inttypes.h since VC2013 -#if _MSC_VER >= 1800 -#include <inttypes.h> -#else - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - -#endif // _MSC_VER >= 1800 - -#endif // _MSC_INTTYPES_H_ ] diff --git a/external/rapidjson/msinttypes/stdint.h b/external/rapidjson/msinttypes/stdint.h deleted file mode 100644 index 3d4477b9a..000000000 --- a/external/rapidjson/msinttypes/stdint.h +++ /dev/null @@ -1,300 +0,0 @@ -// 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-2013 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. Neither the name of the product nor the names of its contributors 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. -// -/////////////////////////////////////////////////////////////////////////////// - -// The above software in this distribution may have been modified by -// THL A29 Limited ("Tencent Modifications"). -// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. - -#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 - -// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. -#if _MSC_VER >= 1600 // [ -#include <stdint.h> - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -#undef INT8_C -#undef INT16_C -#undef INT32_C -#undef INT64_C -#undef UINT8_C -#undef UINT16_C -#undef UINT32_C -#undef UINT64_C - -// 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 -// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -# define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -# define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#else // ] _MSC_VER >= 1700 [ - -#include <limits.h> - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}' -// or compiler would give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#if defined(__cplusplus) && !defined(_M_ARM) -extern "C" { -#endif -# include <wchar.h> -#if defined(__cplusplus) && !defined(_M_ARM) -} -#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 -// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -# define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -# define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#endif // _MSC_VER >= 1600 ] - -#endif // _MSC_STDINT_H_ ] diff --git a/external/rapidjson/ostreamwrapper.h b/external/rapidjson/ostreamwrapper.h deleted file mode 100644 index 6f4667c08..000000000 --- a/external/rapidjson/ostreamwrapper.h +++ /dev/null @@ -1,81 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ -#define RAPIDJSON_OSTREAMWRAPPER_H_ - -#include "stream.h" -#include <iosfwd> - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. -/*! - The classes can be wrapped including but not limited to: - - - \c std::ostringstream - - \c std::stringstream - - \c std::wpstringstream - - \c std::wstringstream - - \c std::ifstream - - \c std::fstream - - \c std::wofstream - - \c std::wfstream - - \tparam StreamType Class derived from \c std::basic_ostream. -*/ - -template <typename StreamType> -class BasicOStreamWrapper { -public: - typedef typename StreamType::char_type Ch; - BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} - - void Put(Ch c) { - stream_.put(c); - } - - void Flush() { - stream_.flush(); - } - - // Not implemented - char Peek() const { RAPIDJSON_ASSERT(false); return 0; } - char Take() { RAPIDJSON_ASSERT(false); return 0; } - size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } - char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } - -private: - BasicOStreamWrapper(const BasicOStreamWrapper&); - BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); - - StreamType& stream_; -}; - -typedef BasicOStreamWrapper<std::ostream> OStreamWrapper; -typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper; - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/external/rapidjson/pointer.h b/external/rapidjson/pointer.h deleted file mode 100644 index 0206ac1c8..000000000 --- a/external/rapidjson/pointer.h +++ /dev/null @@ -1,1358 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_POINTER_H_ -#define RAPIDJSON_POINTER_H_ - -#include "document.h" -#include "internal/itoa.h" - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(switch-enum) -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token - -//! Error code of parsing. -/*! \ingroup RAPIDJSON_ERRORS - \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode -*/ -enum PointerParseErrorCode { - kPointerParseErrorNone = 0, //!< The parse is successful - - kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' - kPointerParseErrorInvalidEscape, //!< Invalid escape - kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment - kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericPointer - -//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. -/*! - This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" - (https://tools.ietf.org/html/rfc6901). - - A JSON pointer is for identifying a specific value in a JSON document - (GenericDocument). It can simplify coding of DOM tree manipulation, because it - can access multiple-level depth of DOM tree with single API call. - - After it parses a string representation (e.g. "/foo/0" or URI fragment - representation (e.g. "#/foo/0") into its internal representation (tokens), - it can be used to resolve a specific value in multiple documents, or sub-tree - of documents. - - Contrary to GenericValue, Pointer can be copy constructed and copy assigned. - Apart from assignment, a Pointer cannot be modified after construction. - - Although Pointer is very convenient, please aware that constructing Pointer - involves parsing and dynamic memory allocation. A special constructor with user- - supplied tokens eliminates these. - - GenericPointer depends on GenericDocument and GenericValue. - - \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> > - \tparam Allocator The allocator type for allocating memory for internal representation. - - \note GenericPointer uses same encoding of ValueType. - However, Allocator of GenericPointer is independent of Allocator of Value. -*/ -template <typename ValueType, typename Allocator = CrtAllocator> -class GenericPointer { -public: - typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value - typedef typename ValueType::Ch Ch; //!< Character type from Value - - //! A token is the basic units of internal representation. - /*! - A JSON pointer string representation "/foo/123" is parsed to two tokens: - "foo" and 123. 123 will be represented in both numeric form and string form. - They are resolved according to the actual value type (object or array). - - For token that are not numbers, or the numeric value is out of bound - (greater than limits of SizeType), they are only treated as string form - (i.e. the token's index will be equal to kPointerInvalidIndex). - - This struct is public so that user can create a Pointer without parsing and - allocation, using a special constructor. - */ - struct Token { - const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. - SizeType length; //!< Length of the name. - SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. - }; - - //!@name Constructors and destructor. - //@{ - - //! Default constructor. - GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} - - //! Constructor that parses a string or URI fragment representation. - /*! - \param source A null-terminated, string or URI fragment representation of JSON pointer. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - */ - explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source, internal::StrLen(source)); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Constructor that parses a string or URI fragment representation. - /*! - \param source A string or URI fragment representation of JSON pointer. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. - */ - explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source.c_str(), source.size()); - } -#endif - - //! Constructor that parses a string or URI fragment representation, with length of the source string. - /*! - \param source A string or URI fragment representation of JSON pointer. - \param length Length of source. - \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. - \note Slightly faster than the overload without length. - */ - GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - Parse(source, length); - } - - //! Constructor with user-supplied tokens. - /*! - This constructor let user supplies const array of tokens. - This prevents the parsing process and eliminates allocation. - This is preferred for memory constrained environments. - - \param tokens An constant array of tokens representing the JSON pointer. - \param tokenCount Number of tokens. - - \b Example - \code - #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } - #define INDEX(i) { #i, sizeof(#i) - 1, i } - - static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; - static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); - // Equivalent to static const Pointer p("/foo/123"); - - #undef NAME - #undef INDEX - \endcode - */ - GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} - - //! Copy constructor. - GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { - *this = rhs; - } - - //! Destructor. - ~GenericPointer() { - if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. - Allocator::Free(tokens_); - RAPIDJSON_DELETE(ownAllocator_); - } - - //! Assignment operator. - GenericPointer& operator=(const GenericPointer& rhs) { - if (this != &rhs) { - // Do not delete ownAllcator - if (nameBuffer_) - Allocator::Free(tokens_); - - tokenCount_ = rhs.tokenCount_; - parseErrorOffset_ = rhs.parseErrorOffset_; - parseErrorCode_ = rhs.parseErrorCode_; - - if (rhs.nameBuffer_) - CopyFromRaw(rhs); // Normally parsed tokens. - else { - tokens_ = rhs.tokens_; // User supplied const tokens. - nameBuffer_ = 0; - } - } - return *this; - } - - //@} - - //!@name Append token - //@{ - - //! Append a token and return a new Pointer - /*! - \param token Token to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const Token& token, Allocator* allocator = 0) const { - GenericPointer r; - r.allocator_ = allocator; - Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); - std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); - r.tokens_[tokenCount_].name = p; - r.tokens_[tokenCount_].length = token.length; - r.tokens_[tokenCount_].index = token.index; - return r; - } - - //! Append a name token with length, and return a new Pointer - /*! - \param name Name to be appended. - \param length Length of name. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { - Token token = { name, length, kPointerInvalidIndex }; - return Append(token, allocator); - } - - //! Append a name token without length, and return a new Pointer - /*! - \param name Name (const Ch*) to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer)) - Append(T* name, Allocator* allocator = 0) const { - return Append(name, StrLen(name), allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Append a name token, and return a new Pointer - /*! - \param name Name to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const { - return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator); - } -#endif - - //! Append a index token, and return a new Pointer - /*! - \param index Index to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(SizeType index, Allocator* allocator = 0) const { - char buffer[21]; - char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); - SizeType length = static_cast<SizeType>(end - buffer); - buffer[length] = '\0'; - - if (sizeof(Ch) == 1) { - Token token = { reinterpret_cast<Ch*>(buffer), length, index }; - return Append(token, allocator); - } - else { - Ch name[21]; - for (size_t i = 0; i <= length; i++) - name[i] = buffer[i]; - Token token = { name, length, index }; - return Append(token, allocator); - } - } - - //! Append a token by value, and return a new Pointer - /*! - \param token token to be appended. - \param allocator Allocator for the newly return Pointer. - \return A new Pointer with appended token. - */ - GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { - if (token.IsString()) - return Append(token.GetString(), token.GetStringLength(), allocator); - else { - RAPIDJSON_ASSERT(token.IsUint64()); - RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); - return Append(static_cast<SizeType>(token.GetUint64()), allocator); - } - } - - //!@name Handling Parse Error - //@{ - - //! Check whether this is a valid pointer. - bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } - - //! Get the parsing error offset in code unit. - size_t GetParseErrorOffset() const { return parseErrorOffset_; } - - //! Get the parsing error code. - PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } - - //@} - - //! Get the allocator of this pointer. - Allocator& GetAllocator() { return *allocator_; } - - //!@name Tokens - //@{ - - //! Get the token array (const version only). - const Token* GetTokens() const { return tokens_; } - - //! Get the number of tokens. - size_t GetTokenCount() const { return tokenCount_; } - - //@} - - //!@name Equality/inequality operators - //@{ - - //! Equality operator. - /*! - \note When any pointers are invalid, always returns false. - */ - bool operator==(const GenericPointer& rhs) const { - if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) - return false; - - for (size_t i = 0; i < tokenCount_; i++) { - if (tokens_[i].index != rhs.tokens_[i].index || - tokens_[i].length != rhs.tokens_[i].length || - (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) - { - return false; - } - } - - return true; - } - - //! Inequality operator. - /*! - \note When any pointers are invalid, always returns true. - */ - bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } - - //@} - - //!@name Stringify - //@{ - - //! Stringify the pointer into string representation. - /*! - \tparam OutputStream Type of output stream. - \param os The output stream. - */ - template<typename OutputStream> - bool Stringify(OutputStream& os) const { - return Stringify<false, OutputStream>(os); - } - - //! Stringify the pointer into URI fragment representation. - /*! - \tparam OutputStream Type of output stream. - \param os The output stream. - */ - template<typename OutputStream> - bool StringifyUriFragment(OutputStream& os) const { - return Stringify<true, OutputStream>(os); - } - - //@} - - //!@name Create value - //@{ - - //! Create a value in a subtree. - /*! - If the value is not exist, it creates all parent values and a JSON Null value. - So it always succeed and return the newly created or existing value. - - Remind that it may change types of parents according to tokens, so it - potentially removes previously stored values. For example, if a document - was an array, and "/foo" is used to create a value, then the document - will be changed to an object, and all existing array elements are lost. - - \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \param alreadyExist If non-null, it stores whether the resolved value is already exist. - \return The resolved newly created (a JSON Null value), or already exists value. - */ - ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { - RAPIDJSON_ASSERT(IsValid()); - ValueType* v = &root; - bool exist = true; - for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - if (v->IsArray() && t->name[0] == '-' && t->length == 1) { - v->PushBack(ValueType().Move(), allocator); - v = &((*v)[v->Size() - 1]); - exist = false; - } - else { - if (t->index == kPointerInvalidIndex) { // must be object name - if (!v->IsObject()) - v->SetObject(); // Change to Object - } - else { // object name or array index - if (!v->IsArray() && !v->IsObject()) - v->SetArray(); // Change to Array - } - - if (v->IsArray()) { - if (t->index >= v->Size()) { - v->Reserve(t->index + 1, allocator); - while (t->index >= v->Size()) - v->PushBack(ValueType().Move(), allocator); - exist = false; - } - v = &((*v)[t->index]); - } - else { - typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length)); - if (m == v->MemberEnd()) { - v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); - v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end - exist = false; - } - else - v = &m->value; - } - } - } - - if (alreadyExist) - *alreadyExist = exist; - - return *v; - } - - //! Creates a value in a document. - /*! - \param document A document to be resolved. - \param alreadyExist If non-null, it stores whether the resolved value is already exist. - \return The resolved newly created, or already exists value. - */ - template <typename stackAllocator> - ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const { - return Create(document, document.GetAllocator(), alreadyExist); - } - - //@} - - //!@name Query value - //@{ - - //! Query a value in a subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. - \return Pointer to the value if it can be resolved. Otherwise null. - - \note - There are only 3 situations when a value cannot be resolved: - 1. A value in the path is not an array nor object. - 2. An object value does not contain the token. - 3. A token is out of range of an array value. - - Use unresolvedTokenIndex to retrieve the token index. - */ - ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { - RAPIDJSON_ASSERT(IsValid()); - ValueType* v = &root; - for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - switch (v->GetType()) { - case kObjectType: - { - typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length)); - if (m == v->MemberEnd()) - break; - v = &m->value; - } - continue; - case kArrayType: - if (t->index == kPointerInvalidIndex || t->index >= v->Size()) - break; - v = &((*v)[t->index]); - continue; - default: - break; - } - - // Error: unresolved token - if (unresolvedTokenIndex) - *unresolvedTokenIndex = static_cast<size_t>(t - tokens_); - return 0; - } - return v; - } - - //! Query a const value in a const subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \return Pointer to the value if it can be resolved. Otherwise null. - */ - const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { - return Get(const_cast<ValueType&>(root), unresolvedTokenIndex); - } - - //@} - - //!@name Query a value with default - //@{ - - //! Query a value in a subtree with default value. - /*! - Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. - So that this function always succeed. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param defaultValue Default value to be cloned if the value was not exists. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - Value& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); - } - - //! Query a value in a subtree with default null-terminated string. - ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - Value& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.SetString(defaultValue, allocator); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Query a value in a subtree with default std::basic_string. - ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const { - bool alreadyExist; - Value& v = Create(root, allocator, &alreadyExist); - return alreadyExist ? v : v.SetString(defaultValue, allocator); - } -#endif - - //! Query a value in a subtree with default primitive value. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) - GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { - return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); - } - - //! Query a value in a document with default value. - template <typename stackAllocator> - ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - - //! Query a value in a document with default null-terminated string. - template <typename stackAllocator> - ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Query a value in a document with default std::basic_string. - template <typename stackAllocator> - ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } -#endif - - //! Query a value in a document with default primitive value. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template <typename T, typename stackAllocator> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) - GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const { - return GetWithDefault(document, defaultValue, document.GetAllocator()); - } - - //@} - - //!@name Set a value - //@{ - - //! Set a value in a subtree, with move semantics. - /*! - It creates all parents if they are not exist or types are different to the tokens. - So this function always succeeds but potentially remove existing values. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param value Value to be set. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = value; - } - - //! Set a value in a subtree, with copy semantics. - ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator).CopyFrom(value, allocator); - } - - //! Set a null-terminated string in a subtree. - ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value, allocator).Move(); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Set a std::basic_string in a subtree. - ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value, allocator).Move(); - } -#endif - - //! Set a primitive value in a subtree. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template <typename T> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) - Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator) = ValueType(value).Move(); - } - - //! Set a value in a document, with move semantics. - template <typename stackAllocator> - ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const { - return Create(document) = value; - } - - //! Set a value in a document, with copy semantics. - template <typename stackAllocator> - ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const { - return Create(document).CopyFrom(value, document.GetAllocator()); - } - - //! Set a null-terminated string in a document. - template <typename stackAllocator> - ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const { - return Create(document) = ValueType(value, document.GetAllocator()).Move(); - } - -#if RAPIDJSON_HAS_STDSTRING - //! Sets a std::basic_string in a document. - template <typename stackAllocator> - ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const { - return Create(document) = ValueType(value, document.GetAllocator()).Move(); - } -#endif - - //! Set a primitive value in a document. - /*! - \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool - */ - template <typename T, typename stackAllocator> - RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) - Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const { - return Create(document) = value; - } - - //@} - - //!@name Swap a value - //@{ - - //! Swap a value with a value in a subtree. - /*! - It creates all parents if they are not exist or types are different to the tokens. - So this function always succeeds but potentially remove existing values. - - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \param value Value to be swapped. - \param allocator Allocator for creating the values if the specified value or its parents are not exist. - \see Create() - */ - ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { - return Create(root, allocator).Swap(value); - } - - //! Swap a value with a value in a document. - template <typename stackAllocator> - ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const { - return Create(document).Swap(value); - } - - //@} - - //! Erase a value in a subtree. - /*! - \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. - \return Whether the resolved value is found and erased. - - \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. - */ - bool Erase(ValueType& root) const { - RAPIDJSON_ASSERT(IsValid()); - if (tokenCount_ == 0) // Cannot erase the root - return false; - - ValueType* v = &root; - const Token* last = tokens_ + (tokenCount_ - 1); - for (const Token *t = tokens_; t != last; ++t) { - switch (v->GetType()) { - case kObjectType: - { - typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length)); - if (m == v->MemberEnd()) - return false; - v = &m->value; - } - break; - case kArrayType: - if (t->index == kPointerInvalidIndex || t->index >= v->Size()) - return false; - v = &((*v)[t->index]); - break; - default: - return false; - } - } - - switch (v->GetType()) { - case kObjectType: - return v->EraseMember(GenericStringRef<Ch>(last->name, last->length)); - case kArrayType: - if (last->index == kPointerInvalidIndex || last->index >= v->Size()) - return false; - v->Erase(v->Begin() + last->index); - return true; - default: - return false; - } - } - -private: - //! Clone the content from rhs to this. - /*! - \param rhs Source pointer. - \param extraToken Extra tokens to be allocated. - \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. - \return Start of non-occupied name buffer, for storing extra names. - */ - Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { - if (!allocator_) // allocator is independently owned. - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - - size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens - for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) - nameBufferSize += t->length; - - tokenCount_ = rhs.tokenCount_ + extraToken; - tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); - nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_); - if (rhs.tokenCount_ > 0) { - std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); - } - if (nameBufferSize > 0) { - std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); - } - - // Adjust pointers to name buffer - std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; - for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) - t->name += diff; - - return nameBuffer_ + nameBufferSize; - } - - //! Check whether a character should be percent-encoded. - /*! - According to RFC 3986 2.3 Unreserved Characters. - \param c The character (code unit) to be tested. - */ - bool NeedPercentEncode(Ch c) const { - return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); - } - - //! Parse a JSON String or its URI fragment representation into tokens. -#ifndef __clang__ // -Wdocumentation - /*! - \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. - \param length Length of the source string. - \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. - */ -#endif - void Parse(const Ch* source, size_t length) { - RAPIDJSON_ASSERT(source != NULL); - RAPIDJSON_ASSERT(nameBuffer_ == 0); - RAPIDJSON_ASSERT(tokens_ == 0); - - // Create own allocator if user did not supply. - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - - // Count number of '/' as tokenCount - tokenCount_ = 0; - for (const Ch* s = source; s != source + length; s++) - if (*s == '/') - tokenCount_++; - - Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); - Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_); - size_t i = 0; - - // Detect if it is a URI fragment - bool uriFragment = false; - if (source[i] == '#') { - uriFragment = true; - i++; - } - - if (i != length && source[i] != '/') { - parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; - goto error; - } - - while (i < length) { - RAPIDJSON_ASSERT(source[i] == '/'); - i++; // consumes '/' - - token->name = name; - bool isNumber = true; - - while (i < length && source[i] != '/') { - Ch c = source[i]; - if (uriFragment) { - // Decoding percent-encoding for URI fragment - if (c == '%') { - PercentDecodeStream is(&source[i], source + length); - GenericInsituStringStream<EncodingType> os(name); - Ch* begin = os.PutBegin(); - if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) { - parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; - goto error; - } - size_t len = os.PutEnd(begin); - i += is.Tell() - 1; - if (len == 1) - c = *name; - else { - name += len; - isNumber = false; - i++; - continue; - } - } - else if (NeedPercentEncode(c)) { - parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; - goto error; - } - } - - i++; - - // Escaping "~0" -> '~', "~1" -> '/' - if (c == '~') { - if (i < length) { - c = source[i]; - if (c == '0') c = '~'; - else if (c == '1') c = '/'; - else { - parseErrorCode_ = kPointerParseErrorInvalidEscape; - goto error; - } - i++; - } - else { - parseErrorCode_ = kPointerParseErrorInvalidEscape; - goto error; - } - } - - // First check for index: all of characters are digit - if (c < '0' || c > '9') - isNumber = false; - - *name++ = c; - } - token->length = static_cast<SizeType>(name - token->name); - if (token->length == 0) - isNumber = false; - *name++ = '\0'; // Null terminator - - // Second check for index: more than one digit cannot have leading zero - if (isNumber && token->length > 1 && token->name[0] == '0') - isNumber = false; - - // String to SizeType conversion - SizeType n = 0; - if (isNumber) { - for (size_t j = 0; j < token->length; j++) { - SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0'); - if (m < n) { // overflow detection - isNumber = false; - break; - } - n = m; - } - } - - token->index = isNumber ? n : kPointerInvalidIndex; - token++; - } - - RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer - parseErrorCode_ = kPointerParseErrorNone; - return; - - error: - Allocator::Free(tokens_); - nameBuffer_ = 0; - tokens_ = 0; - tokenCount_ = 0; - parseErrorOffset_ = i; - return; - } - - //! Stringify to string or URI fragment representation. - /*! - \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. - \tparam OutputStream type of output stream. - \param os The output stream. - */ - template<bool uriFragment, typename OutputStream> - bool Stringify(OutputStream& os) const { - RAPIDJSON_ASSERT(IsValid()); - - if (uriFragment) - os.Put('#'); - - for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - os.Put('/'); - for (size_t j = 0; j < t->length; j++) { - Ch c = t->name[j]; - if (c == '~') { - os.Put('~'); - os.Put('0'); - } - else if (c == '/') { - os.Put('~'); - os.Put('1'); - } - else if (uriFragment && NeedPercentEncode(c)) { - // Transcode to UTF8 sequence - GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]); - PercentEncodeStream<OutputStream> target(os); - if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target)) - return false; - j += source.Tell() - 1; - } - else - os.Put(c); - } - } - return true; - } - - //! A helper stream for decoding a percent-encoded sequence into code unit. - /*! - This stream decodes %XY triplet into code unit (0-255). - If it encounters invalid characters, it sets output code unit as 0 and - mark invalid, and to be checked by IsValid(). - */ - class PercentDecodeStream { - public: - typedef typename ValueType::Ch Ch; - - //! Constructor - /*! - \param source Start of the stream - \param end Past-the-end of the stream. - */ - PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} - - Ch Take() { - if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet - valid_ = false; - return 0; - } - src_++; - Ch c = 0; - for (int j = 0; j < 2; j++) { - c = static_cast<Ch>(c << 4); - Ch h = *src_; - if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0'); - else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10); - else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10); - else { - valid_ = false; - return 0; - } - src_++; - } - return c; - } - - size_t Tell() const { return static_cast<size_t>(src_ - head_); } - bool IsValid() const { return valid_; } - - private: - const Ch* src_; //!< Current read position. - const Ch* head_; //!< Original head of the string. - const Ch* end_; //!< Past-the-end position. - bool valid_; //!< Whether the parsing is valid. - }; - - //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. - template <typename OutputStream> - class PercentEncodeStream { - public: - PercentEncodeStream(OutputStream& os) : os_(os) {} - void Put(char c) { // UTF-8 must be byte - unsigned char u = static_cast<unsigned char>(c); - static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - os_.Put('%'); - os_.Put(hexDigits[u >> 4]); - os_.Put(hexDigits[u & 15]); - } - private: - OutputStream& os_; - }; - - Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. - Allocator* ownAllocator_; //!< Allocator owned by this Pointer. - Ch* nameBuffer_; //!< A buffer containing all names in tokens. - Token* tokens_; //!< A list of tokens. - size_t tokenCount_; //!< Number of tokens in tokens_. - size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. - PointerParseErrorCode parseErrorCode_; //!< Parsing error code. -}; - -//! GenericPointer for Value (UTF-8, default allocator). -typedef GenericPointer<Value> Pointer; - -//!@name Helper functions for GenericPointer -//@{ - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) { - return pointer.Create(root, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a); -} - -// No allocator parameter - -template <typename DocumentType> -typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) { - return pointer.Create(document); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document); -} - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) { - return pointer.Get(root, unresolvedTokenIndex); -} - -template <typename T> -const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) { - return pointer.Get(root, unresolvedTokenIndex); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { - return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex); -} - -template <typename T, typename CharType, size_t N> -const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { - return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex); -} - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -template <typename T> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename T> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} -#endif - -template <typename T, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&)) -GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) { - return pointer.GetWithDefault(root, defaultValue, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename T, typename CharType, size_t N> -typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a); -} -#endif - -template <typename T, typename CharType, size_t N, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&)) -GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a); -} - -// No allocator parameter - -template <typename DocumentType> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -template <typename DocumentType> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename DocumentType> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} -#endif - -template <typename DocumentType, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&)) -GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) { - return pointer.GetWithDefault(document, defaultValue); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue); -} -#endif - -template <typename DocumentType, typename CharType, size_t N, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&)) -GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue); -} - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template <typename T> -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template <typename T> -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename T> -typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} -#endif - -template <typename T, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&)) -SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) { - return pointer.Set(root, value, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename T, typename CharType, size_t N> -typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a); -} -#endif - -template <typename T, typename CharType, size_t N, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&)) -SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a); -} - -// No allocator parameter - -template <typename DocumentType> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) { - return pointer.Set(document, value); -} - -template <typename DocumentType> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) { - return pointer.Set(document, value); -} - -template <typename DocumentType> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) { - return pointer.Set(document, value); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename DocumentType> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) { - return pointer.Set(document, value); -} -#endif - -template <typename DocumentType, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&)) -SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) { - return pointer.Set(document, value); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value); -} - -#if RAPIDJSON_HAS_STDSTRING -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value); -} -#endif - -template <typename DocumentType, typename CharType, size_t N, typename T2> -RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&)) -SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value); -} - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { - return pointer.Swap(root, value, a); -} - -template <typename T, typename CharType, size_t N> -typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { - return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a); -} - -template <typename DocumentType> -typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) { - return pointer.Swap(document, value); -} - -template <typename DocumentType, typename CharType, size_t N> -typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { - return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value); -} - -////////////////////////////////////////////////////////////////////////////// - -template <typename T> -bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) { - return pointer.Erase(root); -} - -template <typename T, typename CharType, size_t N> -bool EraseValueByPointer(T& root, const CharType(&source)[N]) { - return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root); -} - -//@} - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_POINTER_H_ diff --git a/external/rapidjson/prettywriter.h b/external/rapidjson/prettywriter.h deleted file mode 100644 index c6f0216e9..000000000 --- a/external/rapidjson/prettywriter.h +++ /dev/null @@ -1,261 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_PRETTYWRITER_H_ -#define RAPIDJSON_PRETTYWRITER_H_ - -#include "writer.h" - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Combination of PrettyWriter format flags. -/*! \see PrettyWriter::SetFormatOptions - */ -enum PrettyFormatOptions { - kFormatDefault = 0, //!< Default pretty formatting. - kFormatSingleLineArray = 1 //!< Format arrays on a single line. -}; - -//! Writer with indentation and spacing. -/*! - \tparam OutputStream Type of ouptut os. - \tparam SourceEncoding Encoding of source string. - \tparam TargetEncoding Encoding of output stream. - \tparam StackAllocator Type of allocator for allocating memory of stack. -*/ -template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> -class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> { -public: - typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base; - typedef typename Base::Ch Ch; - - //! Constructor - /*! \param os Output stream. - \param allocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of stack. - */ - explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} - - - explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : - Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} - - //! Set custom indentation. - /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). - \param indentCharCount Number of indent characters for each indentation level. - \note The default indentation is 4 spaces. - */ - PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { - RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); - indentChar_ = indentChar; - indentCharCount_ = indentCharCount; - return *this; - } - - //! Set pretty writer formatting options. - /*! \param options Formatting options. - */ - PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { - formatOptions_ = options; - return *this; - } - - /*! @name Implementation of Handler - \see Handler - */ - //@{ - - bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } - bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } - bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } - bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } - bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } - bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } - bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } - - bool RawNumber(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - PrettyPrefix(kNumberType); - return Base::WriteString(str, length); - } - - bool String(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - PrettyPrefix(kStringType); - return Base::WriteString(str, length); - } - -#if RAPIDJSON_HAS_STDSTRING - bool String(const std::basic_string<Ch>& str) { - return String(str.data(), SizeType(str.size())); - } -#endif - - bool StartObject() { - PrettyPrefix(kObjectType); - new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); - return Base::WriteStartObject(); - } - - bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } - -#if RAPIDJSON_HAS_STDSTRING - bool Key(const std::basic_string<Ch>& str) { - return Key(str.data(), SizeType(str.size())); - } -#endif - - bool EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); - RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); - bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; - - if (!empty) { - Base::os_->Put('\n'); - WriteIndent(); - } - bool ret = Base::WriteEndObject(); - (void)ret; - RAPIDJSON_ASSERT(ret == true); - if (Base::level_stack_.Empty()) // end of json text - Base::os_->Flush(); - return true; - } - - bool StartArray() { - PrettyPrefix(kArrayType); - new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); - return Base::WriteStartArray(); - } - - bool EndArray(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); - RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray); - bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; - - if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { - Base::os_->Put('\n'); - WriteIndent(); - } - bool ret = Base::WriteEndArray(); - (void)ret; - RAPIDJSON_ASSERT(ret == true); - if (Base::level_stack_.Empty()) // end of json text - Base::os_->Flush(); - return true; - } - - //@} - - /*! @name Convenience extensions */ - //@{ - - //! Simpler but slower overload. - bool String(const Ch* str) { return String(str, internal::StrLen(str)); } - bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } - - //@} - - //! Write a raw JSON value. - /*! - For user to write a stringified JSON as a value. - - \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. - \param length Length of the json. - \param type Type of the root of json. - \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. - */ - bool RawValue(const Ch* json, size_t length, Type type) { - RAPIDJSON_ASSERT(json != 0); - PrettyPrefix(type); - return Base::WriteRawValue(json, length); - } - -protected: - void PrettyPrefix(Type type) { - (void)type; - if (Base::level_stack_.GetSize() != 0) { // this value is not at root - typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>(); - - if (level->inArray) { - if (level->valueCount > 0) { - Base::os_->Put(','); // add comma if it is not the first element in array - if (formatOptions_ & kFormatSingleLineArray) - Base::os_->Put(' '); - } - - if (!(formatOptions_ & kFormatSingleLineArray)) { - Base::os_->Put('\n'); - WriteIndent(); - } - } - else { // in object - if (level->valueCount > 0) { - if (level->valueCount % 2 == 0) { - Base::os_->Put(','); - Base::os_->Put('\n'); - } - else { - Base::os_->Put(':'); - Base::os_->Put(' '); - } - } - else - Base::os_->Put('\n'); - - if (level->valueCount % 2 == 0) - WriteIndent(); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else { - RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. - Base::hasRoot_ = true; - } - } - - void WriteIndent() { - size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; - PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count); - } - - Ch indentChar_; - unsigned indentCharCount_; - PrettyFormatOptions formatOptions_; - -private: - // Prohibit copy constructor & assignment operator. - PrettyWriter(const PrettyWriter&); - PrettyWriter& operator=(const PrettyWriter&); -}; - -RAPIDJSON_NAMESPACE_END - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/external/rapidjson/rapidjson.h b/external/rapidjson/rapidjson.h deleted file mode 100644 index 053b2ce43..000000000 --- a/external/rapidjson/rapidjson.h +++ /dev/null @@ -1,615 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_RAPIDJSON_H_ -#define RAPIDJSON_RAPIDJSON_H_ - -/*!\file rapidjson.h - \brief common definitions and configuration - - \see RAPIDJSON_CONFIG - */ - -/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration - \brief Configuration macros for library features - - Some RapidJSON features are configurable to adapt the library to a wide - variety of platforms, environments and usage scenarios. Most of the - features can be configured in terms of overriden or predefined - preprocessor macros at compile-time. - - Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. - - \note These macros should be given on the compiler command-line - (where applicable) to avoid inconsistent values when compiling - different translation units of a single application. - */ - -#include <cstdlib> // malloc(), realloc(), free(), size_t -#include <cstring> // memset(), memcpy(), memmove(), memcmp() - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_VERSION_STRING -// -// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. -// - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -// token stringification -#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) -#define RAPIDJSON_DO_STRINGIFY(x) #x -//!@endcond - -/*! \def RAPIDJSON_MAJOR_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Major version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_MINOR_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Minor version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_PATCH_VERSION - \ingroup RAPIDJSON_CONFIG - \brief Patch version of RapidJSON in integer. -*/ -/*! \def RAPIDJSON_VERSION_STRING - \ingroup RAPIDJSON_CONFIG - \brief Version of RapidJSON in "<major>.<minor>.<patch>" string format. -*/ -#define RAPIDJSON_MAJOR_VERSION 1 -#define RAPIDJSON_MINOR_VERSION 1 -#define RAPIDJSON_PATCH_VERSION 0 -#define RAPIDJSON_VERSION_STRING \ - RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NAMESPACE_(BEGIN|END) -/*! \def RAPIDJSON_NAMESPACE - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace - - In order to avoid symbol clashes and/or "One Definition Rule" errors - between multiple inclusions of (different versions of) RapidJSON in - a single binary, users can customize the name of the main RapidJSON - namespace. - - In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE - to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple - levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref - RAPIDJSON_NAMESPACE_END need to be defined as well: - - \code - // in some .cpp file - #define RAPIDJSON_NAMESPACE my::rapidjson - #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { - #define RAPIDJSON_NAMESPACE_END } } - #include "rapidjson/..." - \endcode - - \see rapidjson - */ -/*! \def RAPIDJSON_NAMESPACE_BEGIN - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace (opening expression) - \see RAPIDJSON_NAMESPACE -*/ -/*! \def RAPIDJSON_NAMESPACE_END - \ingroup RAPIDJSON_CONFIG - \brief provide custom rapidjson namespace (closing expression) - \see RAPIDJSON_NAMESPACE -*/ -#ifndef RAPIDJSON_NAMESPACE -#define RAPIDJSON_NAMESPACE rapidjson -#endif -#ifndef RAPIDJSON_NAMESPACE_BEGIN -#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { -#endif -#ifndef RAPIDJSON_NAMESPACE_END -#define RAPIDJSON_NAMESPACE_END } -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_HAS_STDSTRING - -#ifndef RAPIDJSON_HAS_STDSTRING -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation -#else -#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default -#endif -/*! \def RAPIDJSON_HAS_STDSTRING - \ingroup RAPIDJSON_CONFIG - \brief Enable RapidJSON support for \c std::string - - By defining this preprocessor symbol to \c 1, several convenience functions for using - \ref rapidjson::GenericValue with \c std::string are enabled, especially - for construction and comparison. - - \hideinitializer -*/ -#endif // !defined(RAPIDJSON_HAS_STDSTRING) - -#if RAPIDJSON_HAS_STDSTRING -#include <string> -#endif // RAPIDJSON_HAS_STDSTRING - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NO_INT64DEFINE - -/*! \def RAPIDJSON_NO_INT64DEFINE - \ingroup RAPIDJSON_CONFIG - \brief Use external 64-bit integer types. - - RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types - to be available at global scope. - - If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to - prevent RapidJSON from defining its own types. -*/ -#ifndef RAPIDJSON_NO_INT64DEFINE -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 -#include "msinttypes/stdint.h" -#include "msinttypes/inttypes.h" -#else -// Other compilers should have this. -#include <stdint.h> -#include <inttypes.h> -#endif -//!@endcond -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_NO_INT64DEFINE -#endif -#endif // RAPIDJSON_NO_INT64TYPEDEF - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_FORCEINLINE - -#ifndef RAPIDJSON_FORCEINLINE -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#if defined(_MSC_VER) && defined(NDEBUG) -#define RAPIDJSON_FORCEINLINE __forceinline -#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) -#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) -#else -#define RAPIDJSON_FORCEINLINE -#endif -//!@endcond -#endif // RAPIDJSON_FORCEINLINE - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ENDIAN -#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine -#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine - -//! Endianness of the machine. -/*! - \def RAPIDJSON_ENDIAN - \ingroup RAPIDJSON_CONFIG - - GCC 4.6 provided macro for detecting endianness of the target machine. But other - compilers may not have this. User can define RAPIDJSON_ENDIAN to either - \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. - - Default detection implemented with reference to - \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html - \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp -*/ -#ifndef RAPIDJSON_ENDIAN -// Detect with GCC 4.6's macro -# ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# else -# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. -# endif // __BYTE_ORDER__ -// Detect with GLIBC's endian.h -# elif defined(__GLIBC__) -# include <endian.h> -# if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif (__BYTE_ORDER == __BIG_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# else -# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. -# endif // __GLIBC__ -// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro -# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -// Detect with architecture macros -# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) -# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN -# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(_MSC_VER) && defined(_M_ARM) -# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN -# elif defined(RAPIDJSON_DOXYGEN_RUNNING) -# define RAPIDJSON_ENDIAN -# else -# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. -# endif -#endif // RAPIDJSON_ENDIAN - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_64BIT - -//! Whether using 64-bit architecture -#ifndef RAPIDJSON_64BIT -#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) -#define RAPIDJSON_64BIT 1 -#else -#define RAPIDJSON_64BIT 0 -#endif -#endif // RAPIDJSON_64BIT - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ALIGN - -//! Data alignment of the machine. -/*! \ingroup RAPIDJSON_CONFIG - \param x pointer to align - - Some machines require strict data alignment. Currently the default uses 4 bytes - alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms. - User can customize by defining the RAPIDJSON_ALIGN function macro. -*/ -#ifndef RAPIDJSON_ALIGN -#if RAPIDJSON_64BIT == 1 -#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u)) -#else -#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u) -#endif -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_UINT64_C2 - -//! Construct a 64-bit literal by a pair of 32-bit integer. -/*! - 64-bit literal with or without ULL suffix is prone to compiler warnings. - UINT64_C() is C macro which cause compilation problems. - Use this macro to define 64-bit constants by a pair of 32-bit integer. -*/ -#ifndef RAPIDJSON_UINT64_C2 -#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32)) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_48BITPOINTER_OPTIMIZATION - -//! Use only lower 48-bit address for some pointers. -/*! - \ingroup RAPIDJSON_CONFIG - - This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. - The higher 16-bit can be used for storing other data. - \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. -*/ -#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION -#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) -#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 -#else -#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 -#endif -#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION - -#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 -#if RAPIDJSON_64BIT != 1 -#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 -#endif -#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x)))) -#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) -#else -#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) -#define RAPIDJSON_GETPOINTER(type, p) (p) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD - -/*! \def RAPIDJSON_SIMD - \ingroup RAPIDJSON_CONFIG - \brief Enable SSE2/SSE4.2 optimization. - - RapidJSON supports optimized implementations for some parsing operations - based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible - processors. - - To enable these optimizations, two different symbols can be defined; - \code - // Enable SSE2 optimization. - #define RAPIDJSON_SSE2 - - // Enable SSE4.2 optimization. - #define RAPIDJSON_SSE42 - \endcode - - \c RAPIDJSON_SSE42 takes precedence, if both are defined. - - If any of these symbols is defined, RapidJSON defines the macro - \c RAPIDJSON_SIMD to indicate the availability of the optimized code. -*/ -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ - || defined(RAPIDJSON_DOXYGEN_RUNNING) -#define RAPIDJSON_SIMD -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_NO_SIZETYPEDEFINE - -#ifndef RAPIDJSON_NO_SIZETYPEDEFINE -/*! \def RAPIDJSON_NO_SIZETYPEDEFINE - \ingroup RAPIDJSON_CONFIG - \brief User-provided \c SizeType definition. - - In order to avoid using 32-bit size types for indexing strings and arrays, - define this preprocessor symbol and provide the type rapidjson::SizeType - before including RapidJSON: - \code - #define RAPIDJSON_NO_SIZETYPEDEFINE - namespace rapidjson { typedef ::std::size_t SizeType; } - #include "rapidjson/..." - \endcode - - \see rapidjson::SizeType -*/ -#ifdef RAPIDJSON_DOXYGEN_RUNNING -#define RAPIDJSON_NO_SIZETYPEDEFINE -#endif -RAPIDJSON_NAMESPACE_BEGIN -//! Size type (for string lengths, array sizes, etc.) -/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, - instead of using \c size_t. Users may override the SizeType by defining - \ref RAPIDJSON_NO_SIZETYPEDEFINE. -*/ -typedef unsigned SizeType; -RAPIDJSON_NAMESPACE_END -#endif - -// always import std::size_t to rapidjson namespace -RAPIDJSON_NAMESPACE_BEGIN -using std::size_t; -RAPIDJSON_NAMESPACE_END - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_ASSERT - -//! Assertion. -/*! \ingroup RAPIDJSON_CONFIG - By default, rapidjson uses C \c assert() for internal assertions. - User can override it by defining RAPIDJSON_ASSERT(x) macro. - - \note Parsing errors are handled and can be customized by the - \ref RAPIDJSON_ERRORS APIs. -*/ -#ifndef RAPIDJSON_ASSERT -#include <cassert> -#define RAPIDJSON_ASSERT(x) assert(x) -#endif // RAPIDJSON_ASSERT - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_STATIC_ASSERT - -// Adopt from boost -#ifndef RAPIDJSON_STATIC_ASSERT -#ifndef __clang__ -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#endif -RAPIDJSON_NAMESPACE_BEGIN -template <bool x> struct STATIC_ASSERTION_FAILURE; -template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; -template<int x> struct StaticAssertTest {}; -RAPIDJSON_NAMESPACE_END - -#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) -#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) -#define RAPIDJSON_DO_JOIN2(X, Y) X##Y - -#if defined(__GNUC__) -#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) -#else -#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE -#endif -#ifndef __clang__ -//!@endcond -#endif - -/*! \def RAPIDJSON_STATIC_ASSERT - \brief (Internal) macro to check for conditions at compile-time - \param x compile-time condition - \hideinitializer - */ -#define RAPIDJSON_STATIC_ASSERT(x) \ - typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ - sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \ - RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE -#endif - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY - -//! Compiler branching hint for expression with high probability to be true. -/*! - \ingroup RAPIDJSON_CONFIG - \param x Boolean expression likely to be true. -*/ -#ifndef RAPIDJSON_LIKELY -#if defined(__GNUC__) || defined(__clang__) -#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) -#else -#define RAPIDJSON_LIKELY(x) (x) -#endif -#endif - -//! Compiler branching hint for expression with low probability to be true. -/*! - \ingroup RAPIDJSON_CONFIG - \param x Boolean expression unlikely to be true. -*/ -#ifndef RAPIDJSON_UNLIKELY -#if defined(__GNUC__) || defined(__clang__) -#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define RAPIDJSON_UNLIKELY(x) (x) -#endif -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Helpers - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN - -#define RAPIDJSON_MULTILINEMACRO_BEGIN do { -#define RAPIDJSON_MULTILINEMACRO_END \ -} while((void)0, 0) - -// adopted from Boost -#define RAPIDJSON_VERSION_CODE(x,y,z) \ - (((x)*100000) + ((y)*100) + (z)) - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF - -#if defined(__GNUC__) -#define RAPIDJSON_GNUC \ - RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) -#endif - -#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) - -#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) -#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) -#define RAPIDJSON_DIAG_OFF(x) \ - RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) - -// push/pop support in Clang and GCC>=4.6 -#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) -#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) -#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) -#else // GCC >= 4.2, < 4.6 -#define RAPIDJSON_DIAG_PUSH /* ignored */ -#define RAPIDJSON_DIAG_POP /* ignored */ -#endif - -#elif defined(_MSC_VER) - -// pragma (MSVC specific) -#define RAPIDJSON_PRAGMA(x) __pragma(x) -#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) - -#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) -#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) -#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) - -#else - -#define RAPIDJSON_DIAG_OFF(x) /* ignored */ -#define RAPIDJSON_DIAG_PUSH /* ignored */ -#define RAPIDJSON_DIAG_POP /* ignored */ - -#endif // RAPIDJSON_DIAG_* - -/////////////////////////////////////////////////////////////////////////////// -// C++11 features - -#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS -#if defined(__clang__) -#if __has_feature(cxx_rvalue_references) && \ - (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 -#else -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 -#endif -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) - -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 -#else -#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 -#endif -#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS - -#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT -#if defined(__clang__) -#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) -// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported -#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 -#else -#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 -#endif -#endif -#if RAPIDJSON_HAS_CXX11_NOEXCEPT -#define RAPIDJSON_NOEXCEPT noexcept -#else -#define RAPIDJSON_NOEXCEPT /* noexcept */ -#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT - -// no automatic detection, yet -#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS -#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 -#endif - -#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR -#if defined(__clang__) -#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) -#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) -#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 -#else -#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 -#endif -#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR - -//!@endcond - -/////////////////////////////////////////////////////////////////////////////// -// new/delete - -#ifndef RAPIDJSON_NEW -///! customization point for global \c new -#define RAPIDJSON_NEW(x) new x -#endif -#ifndef RAPIDJSON_DELETE -///! customization point for global \c delete -#define RAPIDJSON_DELETE(x) delete x -#endif - -/////////////////////////////////////////////////////////////////////////////// -// Type - -/*! \namespace rapidjson - \brief main RapidJSON namespace - \see RAPIDJSON_NAMESPACE -*/ -RAPIDJSON_NAMESPACE_BEGIN - -//! Type of JSON value -enum Type { - kNullType = 0, //!< null - kFalseType = 1, //!< false - kTrueType = 2, //!< true - kObjectType = 3, //!< object - kArrayType = 4, //!< array - kStringType = 5, //!< string - kNumberType = 6 //!< number -}; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/external/rapidjson/reader.h b/external/rapidjson/reader.h deleted file mode 100644 index 19f8849b1..000000000 --- a/external/rapidjson/reader.h +++ /dev/null @@ -1,1879 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_READER_H_ -#define RAPIDJSON_READER_H_ - -/*! \file reader.h */ - -#include "allocators.h" -#include "stream.h" -#include "encodedstream.h" -#include "internal/meta.h" -#include "internal/stack.h" -#include "internal/strtod.h" -#include <limits> - -#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) -#include <intrin.h> -#pragma intrinsic(_BitScanForward) -#endif -#ifdef RAPIDJSON_SSE42 -#include <nmmintrin.h> -#elif defined(RAPIDJSON_SSE2) -#include <emmintrin.h> -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -RAPIDJSON_DIAG_OFF(4702) // unreachable code -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(old-style-cast) -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(switch-enum) -#endif - -#ifdef __GNUC__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(effc++) -#endif - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define RAPIDJSON_NOTHING /* deliberately empty */ -#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN -#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ - RAPIDJSON_MULTILINEMACRO_END -#endif -#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) -//!@endcond - -/*! \def RAPIDJSON_PARSE_ERROR_NORETURN - \ingroup RAPIDJSON_ERRORS - \brief Macro to indicate a parse error. - \param parseErrorCode \ref rapidjson::ParseErrorCode of the error - \param offset position of the error in JSON input (\c size_t) - - This macros can be used as a customization point for the internal - error handling mechanism of RapidJSON. - - A common usage model is to throw an exception instead of requiring the - caller to explicitly check the \ref rapidjson::GenericReader::Parse's - return value: - - \code - #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ - throw ParseException(parseErrorCode, #parseErrorCode, offset) - - #include <stdexcept> // std::runtime_error - #include "rapidjson/error/error.h" // rapidjson::ParseResult - - struct ParseException : std::runtime_error, rapidjson::ParseResult { - ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) - : std::runtime_error(msg), ParseResult(code, offset) {} - }; - - #include "rapidjson/reader.h" - \endcode - - \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse - */ -#ifndef RAPIDJSON_PARSE_ERROR_NORETURN -#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ - SetParseError(parseErrorCode, offset); \ - RAPIDJSON_MULTILINEMACRO_END -#endif - -/*! \def RAPIDJSON_PARSE_ERROR - \ingroup RAPIDJSON_ERRORS - \brief (Internal) macro to indicate and handle a parse error. - \param parseErrorCode \ref rapidjson::ParseErrorCode of the error - \param offset position of the error in JSON input (\c size_t) - - Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. - - \see RAPIDJSON_PARSE_ERROR_NORETURN - \hideinitializer - */ -#ifndef RAPIDJSON_PARSE_ERROR -#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ - RAPIDJSON_MULTILINEMACRO_BEGIN \ - RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ - RAPIDJSON_MULTILINEMACRO_END -#endif - -#include "error/error.h" // ParseErrorCode, ParseResult - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// ParseFlag - -/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS - \ingroup RAPIDJSON_CONFIG - \brief User-defined kParseDefaultFlags definition. - - User can define this as any \c ParseFlag combinations. -*/ -#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS -#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags -#endif - -//! Combination of parseFlags -/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream - */ -enum ParseFlag { - kParseNoFlags = 0, //!< No flags are set. - kParseInsituFlag = 1, //!< In-situ(destructive) parsing. - kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. - kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. - kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. - kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). - kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. - kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. - kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. - kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. - kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS -}; - -/////////////////////////////////////////////////////////////////////////////// -// Handler - -/*! \class rapidjson::Handler - \brief Concept for receiving events from GenericReader upon parsing. - The functions return true if no error occurs. If they return false, - the event publisher should terminate the process. -\code -concept Handler { - typename Ch; - - bool Null(); - bool Bool(bool b); - bool Int(int i); - bool Uint(unsigned i); - bool Int64(int64_t i); - bool Uint64(uint64_t i); - bool Double(double d); - /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) - bool RawNumber(const Ch* str, SizeType length, bool copy); - bool String(const Ch* str, SizeType length, bool copy); - bool StartObject(); - bool Key(const Ch* str, SizeType length, bool copy); - bool EndObject(SizeType memberCount); - bool StartArray(); - bool EndArray(SizeType elementCount); -}; -\endcode -*/ -/////////////////////////////////////////////////////////////////////////////// -// BaseReaderHandler - -//! Default implementation of Handler. -/*! This can be used as base class of any reader handler. - \note implements Handler concept -*/ -template<typename Encoding = UTF8<>, typename Derived = void> -struct BaseReaderHandler { - typedef typename Encoding::Ch Ch; - - typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override; - - bool Default() { return true; } - bool Null() { return static_cast<Override&>(*this).Default(); } - bool Bool(bool) { return static_cast<Override&>(*this).Default(); } - bool Int(int) { return static_cast<Override&>(*this).Default(); } - bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); } - bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); } - bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); } - bool Double(double) { return static_cast<Override&>(*this).Default(); } - /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) - bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); } - bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); } - bool StartObject() { return static_cast<Override&>(*this).Default(); } - bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); } - bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); } - bool StartArray() { return static_cast<Override&>(*this).Default(); } - bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); } -}; - -/////////////////////////////////////////////////////////////////////////////// -// StreamLocalCopy - -namespace internal { - -template<typename Stream, int = StreamTraits<Stream>::copyOptimization> -class StreamLocalCopy; - -//! Do copy optimization. -template<typename Stream> -class StreamLocalCopy<Stream, 1> { -public: - StreamLocalCopy(Stream& original) : s(original), original_(original) {} - ~StreamLocalCopy() { original_ = s; } - - Stream s; - -private: - StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; - - Stream& original_; -}; - -//! Keep reference. -template<typename Stream> -class StreamLocalCopy<Stream, 0> { -public: - StreamLocalCopy(Stream& original) : s(original) {} - - Stream& s; - -private: - StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; -}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// SkipWhitespace - -//! Skip the JSON white spaces in a stream. -/*! \param is A input stream for skipping white spaces. - \note This function has SSE2/SSE4.2 specialization. -*/ -template<typename InputStream> -void SkipWhitespace(InputStream& is) { - internal::StreamLocalCopy<InputStream> copy(is); - InputStream& s(copy.s); - - typename InputStream::Ch c; - while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') - s.Take(); -} - -inline const char* SkipWhitespace(const char* p, const char* end) { - while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - return p; -} - -#ifdef RAPIDJSON_SSE42 -//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. -inline const char *SkipWhitespace_SIMD(const char* p) { - // Fast return for single non-whitespace - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // 16-byte align to the next boundary - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - while (p != nextAligned) - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // The rest of string using SIMD - static const char whitespace[16] = " \n\r\t"; - const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); - if (r != 0) { // some of characters is non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } -} - -inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { - // Fast return for single non-whitespace - if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - else - return p; - - // The middle of string using SIMD - static const char whitespace[16] = " \n\r\t"; - const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0])); - - for (; p <= end - 16; p += 16) { - const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p)); - const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); - if (r != 0) { // some of characters is non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } - - return SkipWhitespace(p, end); -} - -#elif defined(RAPIDJSON_SSE2) - -//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. -inline const char *SkipWhitespace_SIMD(const char* p) { - // Fast return for single non-whitespace - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // 16-byte align to the next boundary - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - while (p != nextAligned) - if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') - ++p; - else - return p; - - // The rest of string - #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } - static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; - #undef C16 - - const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0])); - const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0])); - const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0])); - const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - __m128i x = _mm_cmpeq_epi8(s, w0); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); - unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x)); - if (r != 0) { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } -} - -inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { - // Fast return for single non-whitespace - if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) - ++p; - else - return p; - - // The rest of string - #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } - static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; - #undef C16 - - const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0])); - const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0])); - const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0])); - const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0])); - - for (; p <= end - 16; p += 16) { - const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p)); - __m128i x = _mm_cmpeq_epi8(s, w0); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); - x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); - unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x)); - if (r != 0) { // some of characters may be non-whitespace -#ifdef _MSC_VER // Find the index of first non-whitespace - unsigned long offset; - _BitScanForward(&offset, r); - return p + offset; -#else - return p + __builtin_ffs(r) - 1; -#endif - } - } - - return SkipWhitespace(p, end); -} - -#endif // RAPIDJSON_SSE2 - -#ifdef RAPIDJSON_SIMD -//! Template function specialization for InsituStringStream -template<> inline void SkipWhitespace(InsituStringStream& is) { - is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_)); -} - -//! Template function specialization for StringStream -template<> inline void SkipWhitespace(StringStream& is) { - is.src_ = SkipWhitespace_SIMD(is.src_); -} - -template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) { - is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); -} -#endif // RAPIDJSON_SIMD - -/////////////////////////////////////////////////////////////////////////////// -// GenericReader - -//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. -/*! GenericReader parses JSON text from a stream, and send events synchronously to an - object implementing Handler concept. - - It needs to allocate a stack for storing a single decoded string during - non-destructive parsing. - - For in-situ parsing, the decoded string is directly written to the source - text string, no temporary buffer is required. - - A GenericReader object can be reused for parsing multiple JSON text. - - \tparam SourceEncoding Encoding of the input stream. - \tparam TargetEncoding Encoding of the parse output. - \tparam StackAllocator Allocator type for stack. -*/ -template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator> -class GenericReader { -public: - typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type - - //! Constructor. - /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) - \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) - */ - GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} - - //! Parse JSON text. - /*! \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept. - \tparam Handler Type of handler, implementing Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template <unsigned parseFlags, typename InputStream, typename Handler> - ParseResult Parse(InputStream& is, Handler& handler) { - if (parseFlags & kParseIterativeFlag) - return IterativeParse<parseFlags>(is, handler); - - parseResult_.Clear(); - - ClearStackOnExit scope(*this); - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - else { - ParseValue<parseFlags>(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (!(parseFlags & kParseStopWhenDoneFlag)) { - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - - if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - } - } - - return parseResult_; - } - - //! Parse JSON text (with \ref kParseDefaultFlags) - /*! \tparam InputStream Type of input stream, implementing Stream concept - \tparam Handler Type of handler, implementing Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. - */ - template <typename InputStream, typename Handler> - ParseResult Parse(InputStream& is, Handler& handler) { - return Parse<kParseDefaultFlags>(is, handler); - } - - //! Whether a parse error has occured in the last parsing. - bool HasParseError() const { return parseResult_.IsError(); } - - //! Get the \ref ParseErrorCode of last parsing. - ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } - - //! Get the position of last parsing error in input, 0 otherwise. - size_t GetErrorOffset() const { return parseResult_.Offset(); } - -protected: - void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } - -private: - // Prohibit copy constructor & assignment operator. - GenericReader(const GenericReader&); - GenericReader& operator=(const GenericReader&); - - void ClearStack() { stack_.Clear(); } - - // clear stack on any exit from ParseStream, e.g. due to exception - struct ClearStackOnExit { - explicit ClearStackOnExit(GenericReader& r) : r_(r) {} - ~ClearStackOnExit() { r_.ClearStack(); } - private: - GenericReader& r_; - ClearStackOnExit(const ClearStackOnExit&); - ClearStackOnExit& operator=(const ClearStackOnExit&); - }; - - template<unsigned parseFlags, typename InputStream> - void SkipWhitespaceAndComments(InputStream& is) { - SkipWhitespace(is); - - if (parseFlags & kParseCommentsFlag) { - while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { - if (Consume(is, '*')) { - while (true) { - if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) - RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); - else if (Consume(is, '*')) { - if (Consume(is, '/')) - break; - } - else - is.Take(); - } - } - else if (RAPIDJSON_LIKELY(Consume(is, '/'))) - while (is.Peek() != '\0' && is.Take() != '\n'); - else - RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); - - SkipWhitespace(is); - } - } - } - - // Parse object: { string : value, ... } - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseObject(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == '{'); - is.Take(); // Skip '{' - - if (RAPIDJSON_UNLIKELY(!handler.StartObject())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, '}')) { - if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - - for (SizeType memberCount = 0;;) { - if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); - - ParseString<parseFlags>(is, handler, true); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ParseValue<parseFlags>(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ++memberCount; - - switch (is.Peek()) { - case ',': - is.Take(); - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - break; - case '}': - is.Take(); - if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - default: - RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy - } - - if (parseFlags & kParseTrailingCommasFlag) { - if (is.Peek() == '}') { - if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - is.Take(); - return; - } - } - } - } - - // Parse array: [ value, ... ] - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseArray(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == '['); - is.Take(); // Skip '[' - - if (RAPIDJSON_UNLIKELY(!handler.StartArray())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, ']')) { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - - for (SizeType elementCount = 0;;) { - ParseValue<parseFlags>(is, handler); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - ++elementCount; - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - - if (Consume(is, ',')) { - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - } - else if (Consume(is, ']')) { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - return; - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); - - if (parseFlags & kParseTrailingCommasFlag) { - if (is.Peek() == ']') { - if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - is.Take(); - return; - } - } - } - } - - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseNull(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 'n'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { - if (RAPIDJSON_UNLIKELY(!handler.Null())) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseTrue(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 't'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { - if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseFalse(InputStream& is, Handler& handler) { - RAPIDJSON_ASSERT(is.Peek() == 'f'); - is.Take(); - - if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { - if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); - } - - template<typename InputStream> - RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { - if (RAPIDJSON_LIKELY(is.Peek() == expect)) { - is.Take(); - return true; - } - else - return false; - } - - // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). - template<typename InputStream> - unsigned ParseHex4(InputStream& is, size_t escapeOffset) { - unsigned codepoint = 0; - for (int i = 0; i < 4; i++) { - Ch c = is.Peek(); - codepoint <<= 4; - codepoint += static_cast<unsigned>(c); - if (c >= '0' && c <= '9') - codepoint -= '0'; - else if (c >= 'A' && c <= 'F') - codepoint -= 'A' - 10; - else if (c >= 'a' && c <= 'f') - codepoint -= 'a' - 10; - else { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); - } - is.Take(); - } - return codepoint; - } - - template <typename CharType> - class StackStream { - public: - typedef CharType Ch; - - StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {} - RAPIDJSON_FORCEINLINE void Put(Ch c) { - *stack_.template Push<Ch>() = c; - ++length_; - } - - RAPIDJSON_FORCEINLINE void* Push(SizeType count) { - length_ += count; - return stack_.template Push<Ch>(count); - } - - size_t Length() const { return length_; } - - Ch* Pop() { - return stack_.template Pop<Ch>(length_); - } - - private: - StackStream(const StackStream&); - StackStream& operator=(const StackStream&); - - internal::Stack<StackAllocator>& stack_; - SizeType length_; - }; - - // Parse string and generate String event. Different code paths for kParseInsituFlag. - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseString(InputStream& is, Handler& handler, bool isKey = false) { - internal::StreamLocalCopy<InputStream> copy(is); - InputStream& s(copy.s); - - RAPIDJSON_ASSERT(s.Peek() == '\"'); - s.Take(); // Skip '\"' - - bool success = false; - if (parseFlags & kParseInsituFlag) { - typename InputStream::Ch *head = s.PutBegin(); - ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - size_t length = s.PutEnd(head) - 1; - RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head); - success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); - } - else { - StackStream<typename TargetEncoding::Ch> stackStream(stack_); - ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - SizeType length = static_cast<SizeType>(stackStream.Length()) - 1; - const typename TargetEncoding::Ch* const str = stackStream.Pop(); - success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); - } - if (RAPIDJSON_UNLIKELY(!success)) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); - } - - // Parse string to an output is - // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. - template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream> - RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - static const char escape[256] = { - Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', - Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, - 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, - 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 - }; -#undef Z16 -//!@endcond - - for (;;) { - // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. - if (!(parseFlags & kParseValidateEncodingFlag)) - ScanCopyUnescapedString(is, os); - - Ch c = is.Peek(); - if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape - size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset - is.Take(); - Ch e = is.Peek(); - if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) { - is.Take(); - os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)])); - } - else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode - is.Take(); - unsigned codepoint = ParseHex4(is, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) { - // Handle UTF-16 surrogate pair - if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) - RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); - unsigned codepoint2 = ParseHex4(is, escapeOffset); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; - if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) - RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); - codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; - } - TEncoding::Encode(os, codepoint); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); - } - else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote - is.Take(); - os.Put('\0'); // null-terminate the string - return; - } - else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF - if (c == '\0') - RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); - else - RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell()); - } - else { - size_t offset = is.Tell(); - if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? - !Transcoder<SEncoding, TEncoding>::Validate(is, os) : - !Transcoder<SEncoding, TEncoding>::Transcode(is, os)))) - RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); - } - } - } - - template<typename InputStream, typename OutputStream> - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { - // Do nothing for generic version - } - -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) - // StringStream -> StackStream<char> - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) { - const char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { - is.src_ = p; - return; - } - else - os.Put(*p++); - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - SizeType length; - #ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; - #else - length = static_cast<SizeType>(__builtin_ffs(r) - 1); - #endif - char* q = reinterpret_cast<char*>(os.Push(length)); - for (size_t i = 0; i < length; i++) - q[i] = p[i]; - - p += length; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); - } - - is.src_ = p; - } - - // InsituStringStream -> InsituStringStream - static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { - RAPIDJSON_ASSERT(&is == &os); - (void)os; - - if (is.src_ == is.dst_) { - SkipUnescapedString(is); - return; - } - - char* p = is.src_; - char *q = is.dst_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - while (p != nextAligned) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { - is.src_ = p; - is.dst_ = q; - return; - } - else - *q++ = *p++; - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); - - for (;; p += 16, q += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - size_t length; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; -#else - length = static_cast<size_t>(__builtin_ffs(r) - 1); -#endif - for (const char* pend = p + length; p != pend; ) - *q++ = *p++; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); - } - - is.src_ = p; - is.dst_ = q; - } - - // When read/write pointers are the same for insitu stream, just skip unescaped characters - static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { - RAPIDJSON_ASSERT(is.src_ == is.dst_); - char* p = is.src_; - - // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - for (; p != nextAligned; p++) - if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { - is.src_ = is.dst_ = p; - return; - } - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); - - for (;; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - size_t length; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - length = offset; -#else - length = static_cast<size_t>(__builtin_ffs(r) - 1); -#endif - p += length; - break; - } - } - - is.src_ = is.dst_ = p; - } -#endif - - template<typename InputStream, bool backup, bool pushOnTake> - class NumberStream; - - template<typename InputStream> - class NumberStream<InputStream, false, false> { - public: - typedef typename InputStream::Ch Ch; - - NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } - ~NumberStream() {} - - RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } - RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } - RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } - RAPIDJSON_FORCEINLINE void Push(char) {} - - size_t Tell() { return is.Tell(); } - size_t Length() { return 0; } - const char* Pop() { return 0; } - - protected: - NumberStream& operator=(const NumberStream&); - - InputStream& is; - }; - - template<typename InputStream> - class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> { - typedef NumberStream<InputStream, false, false> Base; - public: - NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} - ~NumberStream() {} - - RAPIDJSON_FORCEINLINE Ch TakePush() { - stackStream.Put(static_cast<char>(Base::is.Peek())); - return Base::is.Take(); - } - - RAPIDJSON_FORCEINLINE void Push(char c) { - stackStream.Put(c); - } - - size_t Length() { return stackStream.Length(); } - - const char* Pop() { - stackStream.Put('\0'); - return stackStream.Pop(); - } - - private: - StackStream<char> stackStream; - }; - - template<typename InputStream> - class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> { - typedef NumberStream<InputStream, true, false> Base; - public: - NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} - ~NumberStream() {} - - RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } - }; - - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseNumber(InputStream& is, Handler& handler) { - internal::StreamLocalCopy<InputStream> copy(is); - NumberStream<InputStream, - ((parseFlags & kParseNumbersAsStringsFlag) != 0) ? - ((parseFlags & kParseInsituFlag) == 0) : - ((parseFlags & kParseFullPrecisionFlag) != 0), - (parseFlags & kParseNumbersAsStringsFlag) != 0 && - (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s); - - size_t startOffset = s.Tell(); - double d = 0.0; - bool useNanOrInf = false; - - // Parse minus - bool minus = Consume(s, '-'); - - // Parse int: zero / ( digit1-9 *DIGIT ) - unsigned i = 0; - uint64_t i64 = 0; - bool use64bit = false; - int significandDigit = 0; - if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { - i = 0; - s.TakePush(); - } - else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { - i = static_cast<unsigned>(s.TakePush() - '0'); - - if (minus) - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 - if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { - i64 = i; - use64bit = true; - break; - } - } - i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); - significandDigit++; - } - else - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 - if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { - i64 = i; - use64bit = true; - break; - } - } - i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); - significandDigit++; - } - } - // Parse NaN or Infinity here - else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { - useNanOrInf = true; - if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) { - d = std::numeric_limits<double>::quiet_NaN(); - } - else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { - d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity()); - if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') - && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); - - // Parse 64bit int - bool useDouble = false; - if (use64bit) { - if (minus) - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 - if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { - d = static_cast<double>(i64); - useDouble = true; - break; - } - i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); - significandDigit++; - } - else - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 - if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { - d = static_cast<double>(i64); - useDouble = true; - break; - } - i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); - significandDigit++; - } - } - - // Force double for big integer - if (useDouble) { - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0 - RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); - d = d * 10 + (s.TakePush() - '0'); - } - } - - // Parse frac = decimal-point 1*DIGIT - int expFrac = 0; - size_t decimalPosition; - if (Consume(s, '.')) { - decimalPosition = s.Length(); - - if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) - RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); - - if (!useDouble) { -#if RAPIDJSON_64BIT - // Use i64 to store significand in 64-bit architecture - if (!use64bit) - i64 = i; - - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path - break; - else { - i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); - --expFrac; - if (i64 != 0) - significandDigit++; - } - } - - d = static_cast<double>(i64); -#else - // Use double to store significand in 32-bit architecture - d = static_cast<double>(use64bit ? i64 : i); -#endif - useDouble = true; - } - - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - if (significandDigit < 17) { - d = d * 10.0 + (s.TakePush() - '0'); - --expFrac; - if (RAPIDJSON_LIKELY(d > 0.0)) - significandDigit++; - } - else - s.TakePush(); - } - } - else - decimalPosition = s.Length(); // decimal position at the end of integer. - - // Parse exp = e [ minus / plus ] 1*DIGIT - int exp = 0; - if (Consume(s, 'e') || Consume(s, 'E')) { - if (!useDouble) { - d = static_cast<double>(use64bit ? i64 : i); - useDouble = true; - } - - bool expMinus = false; - if (Consume(s, '+')) - ; - else if (Consume(s, '-')) - expMinus = true; - - if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = static_cast<int>(s.Take() - '0'); - if (expMinus) { - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = exp * 10 + static_cast<int>(s.Take() - '0'); - if (exp >= 214748364) { // Issue #313: prevent overflow exponent - while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent - s.Take(); - } - } - } - else { // positive exp - int maxExp = 308 - expFrac; - while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { - exp = exp * 10 + static_cast<int>(s.Take() - '0'); - if (RAPIDJSON_UNLIKELY(exp > maxExp)) - RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); - } - } - } - else - RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); - - if (expMinus) - exp = -exp; - } - - // Finish parsing, call event according to the type of number. - bool cont = true; - - if (parseFlags & kParseNumbersAsStringsFlag) { - if (parseFlags & kParseInsituFlag) { - s.Pop(); // Pop stack no matter if it will be used or not. - typename InputStream::Ch* head = is.PutBegin(); - const size_t length = s.Tell() - startOffset; - RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - // unable to insert the \0 character here, it will erase the comma after this number - const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head); - cont = handler.RawNumber(str, SizeType(length), false); - } - else { - SizeType numCharsToCopy = static_cast<SizeType>(s.Length()); - StringStream srcStream(s.Pop()); - StackStream<typename TargetEncoding::Ch> dstStream(stack_); - while (numCharsToCopy--) { - Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream); - } - dstStream.Put('\0'); - const typename TargetEncoding::Ch* str = dstStream.Pop(); - const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1; - cont = handler.RawNumber(str, SizeType(length), true); - } - } - else { - size_t length = s.Length(); - const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. - - if (useDouble) { - int p = exp + expFrac; - if (parseFlags & kParseFullPrecisionFlag) - d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); - else - d = internal::StrtodNormalPrecision(d, p); - - cont = handler.Double(minus ? -d : d); - } - else if (useNanOrInf) { - cont = handler.Double(d); - } - else { - if (use64bit) { - if (minus) - cont = handler.Int64(static_cast<int64_t>(~i64 + 1)); - else - cont = handler.Uint64(i64); - } - else { - if (minus) - cont = handler.Int(static_cast<int32_t>(~i + 1)); - else - cont = handler.Uint(i); - } - } - } - if (RAPIDJSON_UNLIKELY(!cont)) - RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); - } - - // Parse any JSON value - template<unsigned parseFlags, typename InputStream, typename Handler> - void ParseValue(InputStream& is, Handler& handler) { - switch (is.Peek()) { - case 'n': ParseNull <parseFlags>(is, handler); break; - case 't': ParseTrue <parseFlags>(is, handler); break; - case 'f': ParseFalse <parseFlags>(is, handler); break; - case '"': ParseString<parseFlags>(is, handler); break; - case '{': ParseObject<parseFlags>(is, handler); break; - case '[': ParseArray <parseFlags>(is, handler); break; - default : - ParseNumber<parseFlags>(is, handler); - break; - - } - } - - // Iterative Parsing - - // States - enum IterativeParsingState { - IterativeParsingStartState = 0, - IterativeParsingFinishState, - IterativeParsingErrorState, - - // Object states - IterativeParsingObjectInitialState, - IterativeParsingMemberKeyState, - IterativeParsingKeyValueDelimiterState, - IterativeParsingMemberValueState, - IterativeParsingMemberDelimiterState, - IterativeParsingObjectFinishState, - - // Array states - IterativeParsingArrayInitialState, - IterativeParsingElementState, - IterativeParsingElementDelimiterState, - IterativeParsingArrayFinishState, - - // Single value state - IterativeParsingValueState - }; - - enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 }; - - // Tokens - enum Token { - LeftBracketToken = 0, - RightBracketToken, - - LeftCurlyBracketToken, - RightCurlyBracketToken, - - CommaToken, - ColonToken, - - StringToken, - FalseToken, - TrueToken, - NullToken, - NumberToken, - - kTokenCount - }; - - RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { - -//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN -#define N NumberToken -#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N - // Maps from ASCII to Token - static const unsigned char tokenMap[256] = { - N16, // 00~0F - N16, // 10~1F - N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F - N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F - N16, // 40~4F - N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F - N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F - N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F - N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF - }; -#undef N -#undef N16 -//!@endcond - - if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) - return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]); - else - return NumberToken; - } - - RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { - // current state x one lookahead token -> new state - static const char G[cIterativeParsingStateCount][kTokenCount] = { - // Start - { - IterativeParsingArrayInitialState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingValueState, // String - IterativeParsingValueState, // False - IterativeParsingValueState, // True - IterativeParsingValueState, // Null - IterativeParsingValueState // Number - }, - // Finish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // Error(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // ObjectInitial - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberKeyState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // MemberKey - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingKeyValueDelimiterState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // KeyValueDelimiter - { - IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) - IterativeParsingErrorState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberValueState, // String - IterativeParsingMemberValueState, // False - IterativeParsingMemberValueState, // True - IterativeParsingMemberValueState, // Null - IterativeParsingMemberValueState // Number - }, - // MemberValue - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingMemberDelimiterState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // MemberDelimiter - { - IterativeParsingErrorState, // Left bracket - IterativeParsingErrorState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingObjectFinishState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingMemberKeyState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // ObjectFinish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // ArrayInitial - { - IterativeParsingArrayInitialState, // Left bracket(push Element state) - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push Element state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingElementState, // String - IterativeParsingElementState, // False - IterativeParsingElementState, // True - IterativeParsingElementState, // Null - IterativeParsingElementState // Number - }, - // Element - { - IterativeParsingErrorState, // Left bracket - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingErrorState, // Left curly bracket - IterativeParsingErrorState, // Right curly bracket - IterativeParsingElementDelimiterState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number - }, - // ElementDelimiter - { - IterativeParsingArrayInitialState, // Left bracket(push Element state) - IterativeParsingArrayFinishState, // Right bracket - IterativeParsingObjectInitialState, // Left curly bracket(push Element state) - IterativeParsingErrorState, // Right curly bracket - IterativeParsingErrorState, // Comma - IterativeParsingErrorState, // Colon - IterativeParsingElementState, // String - IterativeParsingElementState, // False - IterativeParsingElementState, // True - IterativeParsingElementState, // Null - IterativeParsingElementState // Number - }, - // ArrayFinish(sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - }, - // Single Value (sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState - } - }; // End of G - - return static_cast<IterativeParsingState>(G[state][token]); - } - - // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). - // May return a new state on state pop. - template <unsigned parseFlags, typename InputStream, typename Handler> - RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { - (void)token; - - switch (dst) { - case IterativeParsingErrorState: - return dst; - - case IterativeParsingObjectInitialState: - case IterativeParsingArrayInitialState: - { - // Push the state(Element or MemeberValue) if we are nested in another array or value of member. - // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. - IterativeParsingState n = src; - if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) - n = IterativeParsingElementState; - else if (src == IterativeParsingKeyValueDelimiterState) - n = IterativeParsingMemberValueState; - // Push current state. - *stack_.template Push<SizeType>(1) = n; - // Initialize and push the member/element count. - *stack_.template Push<SizeType>(1) = 0; - // Call handler - bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return dst; - } - } - - case IterativeParsingMemberKeyState: - ParseString<parseFlags>(is, handler, true); - if (HasParseError()) - return IterativeParsingErrorState; - else - return dst; - - case IterativeParsingKeyValueDelimiterState: - RAPIDJSON_ASSERT(token == ColonToken); - is.Take(); - return dst; - - case IterativeParsingMemberValueState: - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue<parseFlags>(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return dst; - - case IterativeParsingElementState: - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue<parseFlags>(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return dst; - - case IterativeParsingMemberDelimiterState: - case IterativeParsingElementDelimiterState: - is.Take(); - // Update member/element count. - *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1; - return dst; - - case IterativeParsingObjectFinishState: - { - // Transit from delimiter is only allowed when trailing commas are enabled - if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); - return IterativeParsingErrorState; - } - // Get member count. - SizeType c = *stack_.template Pop<SizeType>(1); - // If the object is not empty, count the last member. - if (src == IterativeParsingMemberValueState) - ++c; - // Restore the state. - IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); - // Transit to Finish state if this is the topmost scope. - if (n == IterativeParsingStartState) - n = IterativeParsingFinishState; - // Call handler - bool hr = handler.EndObject(c); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return n; - } - } - - case IterativeParsingArrayFinishState: - { - // Transit from delimiter is only allowed when trailing commas are enabled - if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); - return IterativeParsingErrorState; - } - // Get element count. - SizeType c = *stack_.template Pop<SizeType>(1); - // If the array is not empty, count the last element. - if (src == IterativeParsingElementState) - ++c; - // Restore the state. - IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); - // Transit to Finish state if this is the topmost scope. - if (n == IterativeParsingStartState) - n = IterativeParsingFinishState; - // Call handler - bool hr = handler.EndArray(c); - // On handler short circuits the parsing. - if (!hr) { - RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); - return IterativeParsingErrorState; - } - else { - is.Take(); - return n; - } - } - - default: - // This branch is for IterativeParsingValueState actually. - // Use `default:` rather than - // `case IterativeParsingValueState:` is for code coverage. - - // The IterativeParsingStartState is not enumerated in this switch-case. - // It is impossible for that case. And it can be caught by following assertion. - - // The IterativeParsingFinishState is not enumerated in this switch-case either. - // It is a "derivative" state which cannot triggered from Predict() directly. - // Therefore it cannot happen here. And it can be caught by following assertion. - RAPIDJSON_ASSERT(dst == IterativeParsingValueState); - - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue<parseFlags>(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return IterativeParsingFinishState; - } - } - - template <typename InputStream> - void HandleError(IterativeParsingState src, InputStream& is) { - if (HasParseError()) { - // Error flag has been set. - return; - } - - switch (src) { - case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; - case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; - case IterativeParsingObjectInitialState: - case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; - case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; - case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; - case IterativeParsingKeyValueDelimiterState: - case IterativeParsingArrayInitialState: - case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; - default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; - } - } - - template <unsigned parseFlags, typename InputStream, typename Handler> - ParseResult IterativeParse(InputStream& is, Handler& handler) { - parseResult_.Clear(); - ClearStackOnExit scope(*this); - IterativeParsingState state = IterativeParsingStartState; - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - while (is.Peek() != '\0') { - Token t = Tokenize(is.Peek()); - IterativeParsingState n = Predict(state, t); - IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler); - - if (d == IterativeParsingErrorState) { - HandleError(state, is); - break; - } - - state = d; - - // Do not further consume streams if a root JSON has been parsed. - if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) - break; - - SkipWhitespaceAndComments<parseFlags>(is); - RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); - } - - // Handle the end of file. - if (state != IterativeParsingFinishState) - HandleError(state, is); - - return parseResult_; - } - - static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. - internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. - ParseResult parseResult_; -}; // class GenericReader - -//! Reader with UTF8 encoding and default allocator. -typedef GenericReader<UTF8<>, UTF8<> > Reader; - -RAPIDJSON_NAMESPACE_END - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - - -#ifdef __GNUC__ -RAPIDJSON_DIAG_POP -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_READER_H_ diff --git a/external/rapidjson/schema.h b/external/rapidjson/schema.h deleted file mode 100644 index 288b93d0f..000000000 --- a/external/rapidjson/schema.h +++ /dev/null @@ -1,2007 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available-> -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License-> You may obtain a copy of the License at -// -// http://opensource->org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied-> See the License for the -// specific language governing permissions and limitations under the License-> - -#ifndef RAPIDJSON_SCHEMA_H_ -#define RAPIDJSON_SCHEMA_H_ - -#include "document.h" -#include "pointer.h" -#include <cmath> // abs, floor - -#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) -#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 -#else -#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 -#endif - -#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) -#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 -#else -#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 -#endif - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX -#include "internal/regex.h" -#elif RAPIDJSON_SCHEMA_USE_STDREGEX -#include <regex> -#endif - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX -#define RAPIDJSON_SCHEMA_HAS_REGEX 1 -#else -#define RAPIDJSON_SCHEMA_HAS_REGEX 0 -#endif - -#ifndef RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_SCHEMA_VERBOSE 0 -#endif - -#if RAPIDJSON_SCHEMA_VERBOSE -#include "stringbuffer.h" -#endif - -RAPIDJSON_DIAG_PUSH - -#if defined(__GNUC__) -RAPIDJSON_DIAG_OFF(effc++) -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_OFF(weak-vtables) -RAPIDJSON_DIAG_OFF(exit-time-destructors) -RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) -RAPIDJSON_DIAG_OFF(variadic-macros) -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Verbose Utilities - -#if RAPIDJSON_SCHEMA_VERBOSE - -namespace internal { - -inline void PrintInvalidKeyword(const char* keyword) { - printf("Fail keyword: %s\n", keyword); -} - -inline void PrintInvalidKeyword(const wchar_t* keyword) { - wprintf(L"Fail keyword: %ls\n", keyword); -} - -inline void PrintInvalidDocument(const char* document) { - printf("Fail document: %s\n\n", document); -} - -inline void PrintInvalidDocument(const wchar_t* document) { - wprintf(L"Fail document: %ls\n\n", document); -} - -inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { - printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); -} - -inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { - wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); -} - -} // namespace internal - -#endif // RAPIDJSON_SCHEMA_VERBOSE - -/////////////////////////////////////////////////////////////////////////////// -// RAPIDJSON_INVALID_KEYWORD_RETURN - -#if RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) -#else -#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) -#endif - -#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ -RAPIDJSON_MULTILINEMACRO_BEGIN\ - context.invalidKeyword = keyword.GetString();\ - RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ - return false;\ -RAPIDJSON_MULTILINEMACRO_END - -/////////////////////////////////////////////////////////////////////////////// -// Forward declarations - -template <typename ValueType, typename Allocator> -class GenericSchemaDocument; - -namespace internal { - -template <typename SchemaDocumentType> -class Schema; - -/////////////////////////////////////////////////////////////////////////////// -// ISchemaValidator - -class ISchemaValidator { -public: - virtual ~ISchemaValidator() {} - virtual bool IsValid() const = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// ISchemaStateFactory - -template <typename SchemaType> -class ISchemaStateFactory { -public: - virtual ~ISchemaStateFactory() {} - virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; - virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; - virtual void* CreateHasher() = 0; - virtual uint64_t GetHashCode(void* hasher) = 0; - virtual void DestroryHasher(void* hasher) = 0; - virtual void* MallocState(size_t size) = 0; - virtual void FreeState(void* p) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Hasher - -// For comparison of compound value -template<typename Encoding, typename Allocator> -class Hasher { -public: - typedef typename Encoding::Ch Ch; - - Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} - - bool Null() { return WriteType(kNullType); } - bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } - bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); } - bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); } - bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); } - bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); } - bool Double(double d) { - Number n; - if (d < 0) n.u.i = static_cast<int64_t>(d); - else n.u.u = static_cast<uint64_t>(d); - n.d = d; - return WriteNumber(n); - } - - bool RawNumber(const Ch* str, SizeType len, bool) { - WriteBuffer(kNumberType, str, len * sizeof(Ch)); - return true; - } - - bool String(const Ch* str, SizeType len, bool) { - WriteBuffer(kStringType, str, len * sizeof(Ch)); - return true; - } - - bool StartObject() { return true; } - bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } - bool EndObject(SizeType memberCount) { - uint64_t h = Hash(0, kObjectType); - uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2); - for (SizeType i = 0; i < memberCount; i++) - h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive - *stack_.template Push<uint64_t>() = h; - return true; - } - - bool StartArray() { return true; } - bool EndArray(SizeType elementCount) { - uint64_t h = Hash(0, kArrayType); - uint64_t* e = stack_.template Pop<uint64_t>(elementCount); - for (SizeType i = 0; i < elementCount; i++) - h = Hash(h, e[i]); // Use hash to achieve element order sensitive - *stack_.template Push<uint64_t>() = h; - return true; - } - - bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } - - uint64_t GetHashCode() const { - RAPIDJSON_ASSERT(IsValid()); - return *stack_.template Top<uint64_t>(); - } - -private: - static const size_t kDefaultSize = 256; - struct Number { - union U { - uint64_t u; - int64_t i; - }u; - double d; - }; - - bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } - - bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } - - bool WriteBuffer(Type type, const void* data, size_t len) { - // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ - uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); - const unsigned char* d = static_cast<const unsigned char*>(data); - for (size_t i = 0; i < len; i++) - h = Hash(h, d[i]); - *stack_.template Push<uint64_t>() = h; - return true; - } - - static uint64_t Hash(uint64_t h, uint64_t d) { - static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); - h ^= d; - h *= kPrime; - return h; - } - - Stack<Allocator> stack_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SchemaValidationContext - -template <typename SchemaDocumentType> -struct SchemaValidationContext { - typedef Schema<SchemaDocumentType> SchemaType; - typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType; - typedef typename SchemaType::ValueType ValueType; - typedef typename ValueType::Ch Ch; - - enum PatternValidatorType { - kPatternValidatorOnly, - kPatternValidatorWithProperty, - kPatternValidatorWithAdditionalProperty - }; - - SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : - factory(f), - schema(s), - valueSchema(), - invalidKeyword(), - hasher(), - arrayElementHashCodes(), - validators(), - validatorCount(), - patternPropertiesValidators(), - patternPropertiesValidatorCount(), - patternPropertiesSchemas(), - patternPropertiesSchemaCount(), - valuePatternValidatorType(kPatternValidatorOnly), - propertyExist(), - inArray(false), - valueUniqueness(false), - arrayUniqueness(false) - { - } - - ~SchemaValidationContext() { - if (hasher) - factory.DestroryHasher(hasher); - if (validators) { - for (SizeType i = 0; i < validatorCount; i++) - factory.DestroySchemaValidator(validators[i]); - factory.FreeState(validators); - } - if (patternPropertiesValidators) { - for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) - factory.DestroySchemaValidator(patternPropertiesValidators[i]); - factory.FreeState(patternPropertiesValidators); - } - if (patternPropertiesSchemas) - factory.FreeState(patternPropertiesSchemas); - if (propertyExist) - factory.FreeState(propertyExist); - } - - SchemaValidatorFactoryType& factory; - const SchemaType* schema; - const SchemaType* valueSchema; - const Ch* invalidKeyword; - void* hasher; // Only validator access - void* arrayElementHashCodes; // Only validator access this - ISchemaValidator** validators; - SizeType validatorCount; - ISchemaValidator** patternPropertiesValidators; - SizeType patternPropertiesValidatorCount; - const SchemaType** patternPropertiesSchemas; - SizeType patternPropertiesSchemaCount; - PatternValidatorType valuePatternValidatorType; - PatternValidatorType objectPatternValidatorType; - SizeType arrayElementIndex; - bool* propertyExist; - bool inArray; - bool valueUniqueness; - bool arrayUniqueness; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Schema - -template <typename SchemaDocumentType> -class Schema { -public: - typedef typename SchemaDocumentType::ValueType ValueType; - typedef typename SchemaDocumentType::AllocatorType AllocatorType; - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename EncodingType::Ch Ch; - typedef SchemaValidationContext<SchemaDocumentType> Context; - typedef Schema<SchemaDocumentType> SchemaType; - typedef GenericValue<EncodingType, AllocatorType> SValue; - friend class GenericSchemaDocument<ValueType, AllocatorType>; - - Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : - allocator_(allocator), - enum_(), - enumCount_(), - not_(), - type_((1 << kTotalSchemaType) - 1), // typeless - validatorCount_(), - properties_(), - additionalPropertiesSchema_(), - patternProperties_(), - patternPropertyCount_(), - propertyCount_(), - minProperties_(), - maxProperties_(SizeType(~0)), - additionalProperties_(true), - hasDependencies_(), - hasRequired_(), - hasSchemaDependencies_(), - additionalItemsSchema_(), - itemsList_(), - itemsTuple_(), - itemsTupleCount_(), - minItems_(), - maxItems_(SizeType(~0)), - additionalItems_(true), - uniqueItems_(false), - pattern_(), - minLength_(0), - maxLength_(~SizeType(0)), - exclusiveMinimum_(false), - exclusiveMaximum_(false) - { - typedef typename SchemaDocumentType::ValueType ValueType; - typedef typename ValueType::ConstValueIterator ConstValueIterator; - typedef typename ValueType::ConstMemberIterator ConstMemberIterator; - - if (!value.IsObject()) - return; - - if (const ValueType* v = GetMember(value, GetTypeString())) { - type_ = 0; - if (v->IsString()) - AddType(*v); - else if (v->IsArray()) - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) - AddType(*itr); - } - - if (const ValueType* v = GetMember(value, GetEnumString())) - if (v->IsArray() && v->Size() > 0) { - enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size())); - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { - typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType; - char buffer[256 + 24]; - MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); - EnumHasherType h(&hasherAllocator, 256); - itr->Accept(h); - enum_[enumCount_++] = h.GetHashCode(); - } - } - - if (schemaDocument) { - AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); - AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); - AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); - } - - if (const ValueType* v = GetMember(value, GetNotString())) { - schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); - notValidatorIndex_ = validatorCount_; - validatorCount_++; - } - - // Object - - const ValueType* properties = GetMember(value, GetPropertiesString()); - const ValueType* required = GetMember(value, GetRequiredString()); - const ValueType* dependencies = GetMember(value, GetDependenciesString()); - { - // Gather properties from properties/required/dependencies - SValue allProperties(kArrayType); - - if (properties && properties->IsObject()) - for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) - AddUniqueElement(allProperties, itr->name); - - if (required && required->IsArray()) - for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) - if (itr->IsString()) - AddUniqueElement(allProperties, *itr); - - if (dependencies && dependencies->IsObject()) - for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { - AddUniqueElement(allProperties, itr->name); - if (itr->value.IsArray()) - for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) - if (i->IsString()) - AddUniqueElement(allProperties, *i); - } - - if (allProperties.Size() > 0) { - propertyCount_ = allProperties.Size(); - properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_)); - for (SizeType i = 0; i < propertyCount_; i++) { - new (&properties_[i]) Property(); - properties_[i].name = allProperties[i]; - properties_[i].schema = GetTypeless(); - } - } - } - - if (properties && properties->IsObject()) { - PointerType q = p.Append(GetPropertiesString(), allocator_); - for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { - SizeType index; - if (FindPropertyIndex(itr->name, &index)) - schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); - } - } - - if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { - PointerType q = p.Append(GetPatternPropertiesString(), allocator_); - patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); - patternPropertyCount_ = 0; - - for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { - new (&patternProperties_[patternPropertyCount_]) PatternProperty(); - patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); - schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); - patternPropertyCount_++; - } - } - - if (required && required->IsArray()) - for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) - if (itr->IsString()) { - SizeType index; - if (FindPropertyIndex(*itr, &index)) { - properties_[index].required = true; - hasRequired_ = true; - } - } - - if (dependencies && dependencies->IsObject()) { - PointerType q = p.Append(GetDependenciesString(), allocator_); - hasDependencies_ = true; - for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { - SizeType sourceIndex; - if (FindPropertyIndex(itr->name, &sourceIndex)) { - if (itr->value.IsArray()) { - properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_)); - std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); - for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { - SizeType targetIndex; - if (FindPropertyIndex(*targetItr, &targetIndex)) - properties_[sourceIndex].dependencies[targetIndex] = true; - } - } - else if (itr->value.IsObject()) { - hasSchemaDependencies_ = true; - schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); - properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; - validatorCount_++; - } - } - } - } - - if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { - if (v->IsBool()) - additionalProperties_ = v->GetBool(); - else if (v->IsObject()) - schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); - } - - AssignIfExist(minProperties_, value, GetMinPropertiesString()); - AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); - - // Array - if (const ValueType* v = GetMember(value, GetItemsString())) { - PointerType q = p.Append(GetItemsString(), allocator_); - if (v->IsObject()) // List validation - schemaDocument->CreateSchema(&itemsList_, q, *v, document); - else if (v->IsArray()) { // Tuple validation - itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size())); - SizeType index = 0; - for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) - schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); - } - } - - AssignIfExist(minItems_, value, GetMinItemsString()); - AssignIfExist(maxItems_, value, GetMaxItemsString()); - - if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { - if (v->IsBool()) - additionalItems_ = v->GetBool(); - else if (v->IsObject()) - schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); - } - - AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); - - // String - AssignIfExist(minLength_, value, GetMinLengthString()); - AssignIfExist(maxLength_, value, GetMaxLengthString()); - - if (const ValueType* v = GetMember(value, GetPatternString())) - pattern_ = CreatePattern(*v); - - // Number - if (const ValueType* v = GetMember(value, GetMinimumString())) - if (v->IsNumber()) - minimum_.CopyFrom(*v, *allocator_); - - if (const ValueType* v = GetMember(value, GetMaximumString())) - if (v->IsNumber()) - maximum_.CopyFrom(*v, *allocator_); - - AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); - AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); - - if (const ValueType* v = GetMember(value, GetMultipleOfString())) - if (v->IsNumber() && v->GetDouble() > 0.0) - multipleOf_.CopyFrom(*v, *allocator_); - } - - ~Schema() { - if (allocator_) { - allocator_->Free(enum_); - } - if (properties_) { - for (SizeType i = 0; i < propertyCount_; i++) - properties_[i].~Property(); - AllocatorType::Free(properties_); - } - if (patternProperties_) { - for (SizeType i = 0; i < patternPropertyCount_; i++) - patternProperties_[i].~PatternProperty(); - AllocatorType::Free(patternProperties_); - } - AllocatorType::Free(itemsTuple_); -#if RAPIDJSON_SCHEMA_HAS_REGEX - if (pattern_) { - pattern_->~RegexType(); - allocator_->Free(pattern_); - } -#endif - } - - bool BeginValue(Context& context) const { - if (context.inArray) { - if (uniqueItems_) - context.valueUniqueness = true; - - if (itemsList_) - context.valueSchema = itemsList_; - else if (itemsTuple_) { - if (context.arrayElementIndex < itemsTupleCount_) - context.valueSchema = itemsTuple_[context.arrayElementIndex]; - else if (additionalItemsSchema_) - context.valueSchema = additionalItemsSchema_; - else if (additionalItems_) - context.valueSchema = GetTypeless(); - else - RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); - } - else - context.valueSchema = GetTypeless(); - - context.arrayElementIndex++; - } - return true; - } - - RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { - if (context.patternPropertiesValidatorCount > 0) { - bool otherValid = false; - SizeType count = context.patternPropertiesValidatorCount; - if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) - otherValid = context.patternPropertiesValidators[--count]->IsValid(); - - bool patternValid = true; - for (SizeType i = 0; i < count; i++) - if (!context.patternPropertiesValidators[i]->IsValid()) { - patternValid = false; - break; - } - - if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { - if (!patternValid) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { - if (!patternValid || !otherValid) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); - } - - if (enum_) { - const uint64_t h = context.factory.GetHashCode(context.hasher); - for (SizeType i = 0; i < enumCount_; i++) - if (enum_[i] == h) - goto foundEnum; - RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); - foundEnum:; - } - - if (allOf_.schemas) - for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) - if (!context.validators[i]->IsValid()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); - - if (anyOf_.schemas) { - for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) - if (context.validators[i]->IsValid()) - goto foundAny; - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); - foundAny:; - } - - if (oneOf_.schemas) { - bool oneValid = false; - for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) - if (context.validators[i]->IsValid()) { - if (oneValid) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); - else - oneValid = true; - } - if (!oneValid) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); - } - - if (not_ && context.validators[notValidatorIndex_]->IsValid()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); - - return true; - } - - bool Null(Context& context) const { - if (!(type_ & (1 << kNullSchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - return CreateParallelValidator(context); - } - - bool Bool(Context& context, bool) const { - if (!(type_ & (1 << kBooleanSchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - return CreateParallelValidator(context); - } - - bool Int(Context& context, int i) const { - if (!CheckInt(context, i)) - return false; - return CreateParallelValidator(context); - } - - bool Uint(Context& context, unsigned u) const { - if (!CheckUint(context, u)) - return false; - return CreateParallelValidator(context); - } - - bool Int64(Context& context, int64_t i) const { - if (!CheckInt(context, i)) - return false; - return CreateParallelValidator(context); - } - - bool Uint64(Context& context, uint64_t u) const { - if (!CheckUint(context, u)) - return false; - return CreateParallelValidator(context); - } - - bool Double(Context& context, double d) const { - if (!(type_ & (1 << kNumberSchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) - return false; - - if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) - return false; - - if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) - return false; - - return CreateParallelValidator(context); - } - - bool String(Context& context, const Ch* str, SizeType length, bool) const { - if (!(type_ & (1 << kStringSchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - if (minLength_ != 0 || maxLength_ != SizeType(~0)) { - SizeType count; - if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) { - if (count < minLength_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); - if (count > maxLength_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); - } - } - - if (pattern_ && !IsPatternMatch(pattern_, str, length)) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); - - return CreateParallelValidator(context); - } - - bool StartObject(Context& context) const { - if (!(type_ & (1 << kObjectSchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - if (hasDependencies_ || hasRequired_) { - context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_)); - std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); - } - - if (patternProperties_) { // pre-allocate schema array - SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType - context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count)); - context.patternPropertiesSchemaCount = 0; - std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); - } - - return CreateParallelValidator(context); - } - - bool Key(Context& context, const Ch* str, SizeType len, bool) const { - if (patternProperties_) { - context.patternPropertiesSchemaCount = 0; - for (SizeType i = 0; i < patternPropertyCount_; i++) - if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; - } - - SizeType index; - if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { - if (context.patternPropertiesSchemaCount > 0) { - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; - context.valueSchema = GetTypeless(); - context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; - } - else - context.valueSchema = properties_[index].schema; - - if (context.propertyExist) - context.propertyExist[index] = true; - - return true; - } - - if (additionalPropertiesSchema_) { - if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { - context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; - context.valueSchema = GetTypeless(); - context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; - } - else - context.valueSchema = additionalPropertiesSchema_; - return true; - } - else if (additionalProperties_) { - context.valueSchema = GetTypeless(); - return true; - } - - if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties - RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); - - return true; - } - - bool EndObject(Context& context, SizeType memberCount) const { - if (hasRequired_) - for (SizeType index = 0; index < propertyCount_; index++) - if (properties_[index].required) - if (!context.propertyExist[index]) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); - - if (memberCount < minProperties_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); - - if (memberCount > maxProperties_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); - - if (hasDependencies_) { - for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) - if (context.propertyExist[sourceIndex]) { - if (properties_[sourceIndex].dependencies) { - for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) - if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex]) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); - } - else if (properties_[sourceIndex].dependenciesSchema) - if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); - } - } - - return true; - } - - bool StartArray(Context& context) const { - if (!(type_ & (1 << kArraySchemaType))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - context.arrayElementIndex = 0; - context.inArray = true; - - return CreateParallelValidator(context); - } - - bool EndArray(Context& context, SizeType elementCount) const { - context.inArray = false; - - if (elementCount < minItems_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); - - if (elementCount > maxItems_) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); - - return true; - } - - // Generate functions for string literal according to Ch -#define RAPIDJSON_STRING_(name, ...) \ - static const ValueType& Get##name##String() {\ - static const Ch s[] = { __VA_ARGS__, '\0' };\ - static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\ - return v;\ - } - - RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') - RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') - RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') - RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') - RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') - RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') - RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') - RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') - RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') - RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') - RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') - RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') - RAPIDJSON_STRING_(Not, 'n', 'o', 't') - RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') - RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') - RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') - RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') - RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') - RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') - RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') - RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') - RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') - -#undef RAPIDJSON_STRING_ - -private: - enum SchemaValueType { - kNullSchemaType, - kBooleanSchemaType, - kObjectSchemaType, - kArraySchemaType, - kStringSchemaType, - kNumberSchemaType, - kIntegerSchemaType, - kTotalSchemaType - }; - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX - typedef internal::GenericRegex<EncodingType> RegexType; -#elif RAPIDJSON_SCHEMA_USE_STDREGEX - typedef std::basic_regex<Ch> RegexType; -#else - typedef char RegexType; -#endif - - struct SchemaArray { - SchemaArray() : schemas(), count() {} - ~SchemaArray() { AllocatorType::Free(schemas); } - const SchemaType** schemas; - SizeType begin; // begin index of context.validators - SizeType count; - }; - - static const SchemaType* GetTypeless() { - static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0); - return &typeless; - } - - template <typename V1, typename V2> - void AddUniqueElement(V1& a, const V2& v) { - for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) - if (*itr == v) - return; - V1 c(v, *allocator_); - a.PushBack(c, *allocator_); - } - - static const ValueType* GetMember(const ValueType& value, const ValueType& name) { - typename ValueType::ConstMemberIterator itr = value.FindMember(name); - return itr != value.MemberEnd() ? &(itr->value) : 0; - } - - static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { - if (const ValueType* v = GetMember(value, name)) - if (v->IsBool()) - out = v->GetBool(); - } - - static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { - if (const ValueType* v = GetMember(value, name)) - if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) - out = static_cast<SizeType>(v->GetUint64()); - } - - void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { - if (const ValueType* v = GetMember(value, name)) { - if (v->IsArray() && v->Size() > 0) { - PointerType q = p.Append(name, allocator_); - out.count = v->Size(); - out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*))); - memset(out.schemas, 0, sizeof(Schema*)* out.count); - for (SizeType i = 0; i < out.count; i++) - schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); - out.begin = validatorCount_; - validatorCount_ += out.count; - } - } - } - -#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX - template <typename ValueType> - RegexType* CreatePattern(const ValueType& value) { - if (value.IsString()) { - RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString()); - if (!r->IsValid()) { - r->~RegexType(); - AllocatorType::Free(r); - r = 0; - } - return r; - } - return 0; - } - - static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { - GenericRegexSearch<RegexType> rs(*pattern); - return rs.Search(str); - } -#elif RAPIDJSON_SCHEMA_USE_STDREGEX - template <typename ValueType> - RegexType* CreatePattern(const ValueType& value) { - if (value.IsString()) - try { - return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); - } - catch (const std::regex_error&) { - } - return 0; - } - - static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { - std::match_results<const Ch*> r; - return std::regex_search(str, str + length, r, *pattern); - } -#else - template <typename ValueType> - RegexType* CreatePattern(const ValueType&) { return 0; } - - static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } -#endif // RAPIDJSON_SCHEMA_USE_STDREGEX - - void AddType(const ValueType& type) { - if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; - else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; - else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; - else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; - else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; - else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; - else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); - } - - bool CreateParallelValidator(Context& context) const { - if (enum_ || context.arrayUniqueness) - context.hasher = context.factory.CreateHasher(); - - if (validatorCount_) { - RAPIDJSON_ASSERT(context.validators == 0); - context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); - context.validatorCount = validatorCount_; - - if (allOf_.schemas) - CreateSchemaValidators(context, allOf_); - - if (anyOf_.schemas) - CreateSchemaValidators(context, anyOf_); - - if (oneOf_.schemas) - CreateSchemaValidators(context, oneOf_); - - if (not_) - context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); - - if (hasSchemaDependencies_) { - for (SizeType i = 0; i < propertyCount_; i++) - if (properties_[i].dependenciesSchema) - context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); - } - } - - return true; - } - - void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { - for (SizeType i = 0; i < schemas.count; i++) - context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); - } - - // O(n) - bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { - SizeType len = name.GetStringLength(); - const Ch* str = name.GetString(); - for (SizeType index = 0; index < propertyCount_; index++) - if (properties_[index].name.GetStringLength() == len && - (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) - { - *outIndex = index; - return true; - } - return false; - } - - bool CheckInt(Context& context, int64_t i) const { - if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - if (!minimum_.IsNull()) { - if (minimum_.IsInt64()) { - if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - } - else if (minimum_.IsUint64()) { - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() - } - else if (!CheckDoubleMinimum(context, static_cast<double>(i))) - return false; - } - - if (!maximum_.IsNull()) { - if (maximum_.IsInt64()) { - if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - } - else if (maximum_.IsUint64()) - /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() - else if (!CheckDoubleMaximum(context, static_cast<double>(i))) - return false; - } - - if (!multipleOf_.IsNull()) { - if (multipleOf_.IsUint64()) { - if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - } - else if (!CheckDoubleMultipleOf(context, static_cast<double>(i))) - return false; - } - - return true; - } - - bool CheckUint(Context& context, uint64_t i) const { - if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); - - if (!minimum_.IsNull()) { - if (minimum_.IsUint64()) { - if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - } - else if (minimum_.IsInt64()) - /* do nothing */; // i >= 0 > minimum.Getint64() - else if (!CheckDoubleMinimum(context, static_cast<double>(i))) - return false; - } - - if (!maximum_.IsNull()) { - if (maximum_.IsUint64()) { - if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - } - else if (maximum_.IsInt64()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ - else if (!CheckDoubleMaximum(context, static_cast<double>(i))) - return false; - } - - if (!multipleOf_.IsNull()) { - if (multipleOf_.IsUint64()) { - if (i % multipleOf_.GetUint64() != 0) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - } - else if (!CheckDoubleMultipleOf(context, static_cast<double>(i))) - return false; - } - - return true; - } - - bool CheckDoubleMinimum(Context& context, double d) const { - if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); - return true; - } - - bool CheckDoubleMaximum(Context& context, double d) const { - if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); - return true; - } - - bool CheckDoubleMultipleOf(Context& context, double d) const { - double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); - double q = std::floor(a / b); - double r = a - q * b; - if (r > 0.0) - RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); - return true; - } - - struct Property { - Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} - ~Property() { AllocatorType::Free(dependencies); } - SValue name; - const SchemaType* schema; - const SchemaType* dependenciesSchema; - SizeType dependenciesValidatorIndex; - bool* dependencies; - bool required; - }; - - struct PatternProperty { - PatternProperty() : schema(), pattern() {} - ~PatternProperty() { - if (pattern) { - pattern->~RegexType(); - AllocatorType::Free(pattern); - } - } - const SchemaType* schema; - RegexType* pattern; - }; - - AllocatorType* allocator_; - uint64_t* enum_; - SizeType enumCount_; - SchemaArray allOf_; - SchemaArray anyOf_; - SchemaArray oneOf_; - const SchemaType* not_; - unsigned type_; // bitmask of kSchemaType - SizeType validatorCount_; - SizeType notValidatorIndex_; - - Property* properties_; - const SchemaType* additionalPropertiesSchema_; - PatternProperty* patternProperties_; - SizeType patternPropertyCount_; - SizeType propertyCount_; - SizeType minProperties_; - SizeType maxProperties_; - bool additionalProperties_; - bool hasDependencies_; - bool hasRequired_; - bool hasSchemaDependencies_; - - const SchemaType* additionalItemsSchema_; - const SchemaType* itemsList_; - const SchemaType** itemsTuple_; - SizeType itemsTupleCount_; - SizeType minItems_; - SizeType maxItems_; - bool additionalItems_; - bool uniqueItems_; - - RegexType* pattern_; - SizeType minLength_; - SizeType maxLength_; - - SValue minimum_; - SValue maximum_; - SValue multipleOf_; - bool exclusiveMinimum_; - bool exclusiveMaximum_; -}; - -template<typename Stack, typename Ch> -struct TokenHelper { - RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { - *documentStack.template Push<Ch>() = '/'; - char buffer[21]; - size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); - for (size_t i = 0; i < length; i++) - *documentStack.template Push<Ch>() = buffer[i]; - } -}; - -// Partial specialized version for char to prevent buffer copying. -template <typename Stack> -struct TokenHelper<Stack, char> { - RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { - if (sizeof(SizeType) == 4) { - char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint - *buffer++ = '/'; - const char* end = internal::u32toa(index, buffer); - documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer))); - } - else { - char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64 - *buffer++ = '/'; - const char* end = internal::u64toa(index, buffer); - documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer))); - } - } -}; - -} // namespace internal - -/////////////////////////////////////////////////////////////////////////////// -// IGenericRemoteSchemaDocumentProvider - -template <typename SchemaDocumentType> -class IGenericRemoteSchemaDocumentProvider { -public: - typedef typename SchemaDocumentType::Ch Ch; - - virtual ~IGenericRemoteSchemaDocumentProvider() {} - virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; -}; - -/////////////////////////////////////////////////////////////////////////////// -// GenericSchemaDocument - -//! JSON schema document. -/*! - A JSON schema document is a compiled version of a JSON schema. - It is basically a tree of internal::Schema. - - \note This is an immutable class (i.e. its instance cannot be modified after construction). - \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. - \tparam Allocator Allocator type for allocating memory of this document. -*/ -template <typename ValueT, typename Allocator = CrtAllocator> -class GenericSchemaDocument { -public: - typedef ValueT ValueType; - typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRemoteSchemaDocumentProviderType; - typedef Allocator AllocatorType; - typedef typename ValueType::EncodingType EncodingType; - typedef typename EncodingType::Ch Ch; - typedef internal::Schema<GenericSchemaDocument> SchemaType; - typedef GenericPointer<ValueType, Allocator> PointerType; - friend class internal::Schema<GenericSchemaDocument>; - template <typename, typename, typename> - friend class GenericSchemaValidator; - - //! Constructor. - /*! - Compile a JSON document into schema document. - - \param document A JSON document as source. - \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. - \param allocator An optional allocator instance for allocating memory. Can be null. - */ - explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : - remoteProvider_(remoteProvider), - allocator_(allocator), - ownAllocator_(), - root_(), - schemaMap_(allocator, kInitialSchemaMapSize), - schemaRef_(allocator, kInitialSchemaRefSize) - { - if (!allocator_) - ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); - - // Generate root schema, it will call CreateSchema() to create sub-schemas, - // And call AddRefSchema() if there are $ref. - CreateSchemaRecursive(&root_, PointerType(), document, document); - - // Resolve $ref - while (!schemaRef_.Empty()) { - SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1); - if (const SchemaType* s = GetSchema(refEntry->target)) { - if (refEntry->schema) - *refEntry->schema = s; - - // Create entry in map if not exist - if (!GetSchema(refEntry->source)) { - new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_); - } - } - refEntry->~SchemaRefEntry(); - } - - RAPIDJSON_ASSERT(root_ != 0); - - schemaRef_.ShrinkToFit(); // Deallocate all memory for ref - } - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - //! Move constructor in C++11 - GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : - remoteProvider_(rhs.remoteProvider_), - allocator_(rhs.allocator_), - ownAllocator_(rhs.ownAllocator_), - root_(rhs.root_), - schemaMap_(std::move(rhs.schemaMap_)), - schemaRef_(std::move(rhs.schemaRef_)) - { - rhs.remoteProvider_ = 0; - rhs.allocator_ = 0; - rhs.ownAllocator_ = 0; - } -#endif - - //! Destructor - ~GenericSchemaDocument() { - while (!schemaMap_.Empty()) - schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry(); - - RAPIDJSON_DELETE(ownAllocator_); - } - - //! Get the root schema. - const SchemaType& GetRoot() const { return *root_; } - -private: - //! Prohibit copying - GenericSchemaDocument(const GenericSchemaDocument&); - //! Prohibit assignment - GenericSchemaDocument& operator=(const GenericSchemaDocument&); - - struct SchemaRefEntry { - SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} - PointerType source; - PointerType target; - const SchemaType** schema; - }; - - struct SchemaEntry { - SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} - ~SchemaEntry() { - if (owned) { - schema->~SchemaType(); - Allocator::Free(schema); - } - } - PointerType pointer; - SchemaType* schema; - bool owned; - }; - - void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { - if (schema) - *schema = SchemaType::GetTypeless(); - - if (v.GetType() == kObjectType) { - const SchemaType* s = GetSchema(pointer); - if (!s) - CreateSchema(schema, pointer, v, document); - - for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) - CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); - } - else if (v.GetType() == kArrayType) - for (SizeType i = 0; i < v.Size(); i++) - CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); - } - - void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { - RAPIDJSON_ASSERT(pointer.IsValid()); - if (v.IsObject()) { - if (!HandleRefSchema(pointer, schema, v, document)) { - SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); - new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_); - if (schema) - *schema = s; - } - } - } - - bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { - static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; - static const ValueType kRefValue(kRefString, 4); - - typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); - if (itr == v.MemberEnd()) - return false; - - if (itr->value.IsString()) { - SizeType len = itr->value.GetStringLength(); - if (len > 0) { - const Ch* s = itr->value.GetString(); - SizeType i = 0; - while (i < len && s[i] != '#') // Find the first # - i++; - - if (i > 0) { // Remote reference, resolve immediately - if (remoteProvider_) { - if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) { - PointerType pointer(&s[i], len - i, allocator_); - if (pointer.IsValid()) { - if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { - if (schema) - *schema = sc; - return true; - } - } - } - } - } - else if (s[i] == '#') { // Local reference, defer resolution - PointerType pointer(&s[i], len - i, allocator_); - if (pointer.IsValid()) { - if (const ValueType* nv = pointer.Get(document)) - if (HandleRefSchema(source, schema, *nv, document)) - return true; - - new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_); - return true; - } - } - } - } - return false; - } - - const SchemaType* GetSchema(const PointerType& pointer) const { - for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target) - if (pointer == target->pointer) - return target->schema; - return 0; - } - - PointerType GetPointer(const SchemaType* schema) const { - for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target) - if (schema == target->schema) - return target->pointer; - return PointerType(); - } - - static const size_t kInitialSchemaMapSize = 64; - static const size_t kInitialSchemaRefSize = 64; - - IRemoteSchemaDocumentProviderType* remoteProvider_; - Allocator *allocator_; - Allocator *ownAllocator_; - const SchemaType* root_; //!< Root schema. - internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas - internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref -}; - -//! GenericSchemaDocument using Value type. -typedef GenericSchemaDocument<Value> SchemaDocument; -//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. -typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider; - -/////////////////////////////////////////////////////////////////////////////// -// GenericSchemaValidator - -//! JSON Schema Validator. -/*! - A SAX style JSON schema validator. - It uses a \c GenericSchemaDocument to validate SAX events. - It delegates the incoming SAX events to an output handler. - The default output handler does nothing. - It can be reused multiple times by calling \c Reset(). - - \tparam SchemaDocumentType Type of schema document. - \tparam OutputHandler Type of output handler. Default handler does nothing. - \tparam StateAllocator Allocator for storing the internal validation states. -*/ -template < - typename SchemaDocumentType, - typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>, - typename StateAllocator = CrtAllocator> -class GenericSchemaValidator : - public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>, - public internal::ISchemaValidator -{ -public: - typedef typename SchemaDocumentType::SchemaType SchemaType; - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename SchemaType::EncodingType EncodingType; - typedef typename EncodingType::Ch Ch; - - //! Constructor without output handler. - /*! - \param schemaDocument The schema document to conform to. - \param allocator Optional allocator for storing internal validation states. - \param schemaStackCapacity Optional initial capacity of schema path stack. - \param documentStackCapacity Optional initial capacity of document path stack. - */ - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(schemaDocument.GetRoot()), - outputHandler_(GetNullHandler()), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(0) -#endif - { - } - - //! Constructor with output handler. - /*! - \param schemaDocument The schema document to conform to. - \param allocator Optional allocator for storing internal validation states. - \param schemaStackCapacity Optional initial capacity of schema path stack. - \param documentStackCapacity Optional initial capacity of document path stack. - */ - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - OutputHandler& outputHandler, - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(schemaDocument.GetRoot()), - outputHandler_(outputHandler), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(0) -#endif - { - } - - //! Destructor. - ~GenericSchemaValidator() { - Reset(); - RAPIDJSON_DELETE(ownStateAllocator_); - } - - //! Reset the internal states. - void Reset() { - while (!schemaStack_.Empty()) - PopSchema(); - documentStack_.Clear(); - valid_ = true; - } - - //! Checks whether the current state is valid. - // Implementation of ISchemaValidator - virtual bool IsValid() const { return valid_; } - - //! Gets the JSON pointer pointed to the invalid schema. - PointerType GetInvalidSchemaPointer() const { - return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema()); - } - - //! Gets the keyword of invalid schema. - const Ch* GetInvalidSchemaKeyword() const { - return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; - } - - //! Gets the JSON pointer pointed to the invalid value. - PointerType GetInvalidDocumentPointer() const { - return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch)); - } - -#if RAPIDJSON_SCHEMA_VERBOSE -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ -RAPIDJSON_MULTILINEMACRO_BEGIN\ - *documentStack_.template Push<Ch>() = '\0';\ - documentStack_.template Pop<Ch>(1);\ - internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\ -RAPIDJSON_MULTILINEMACRO_END -#else -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() -#endif - -#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ - if (!valid_) return false; \ - if (!BeginValue() || !CurrentSchema().method arg1) {\ - RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ - return valid_ = false;\ - } - -#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ - for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\ - if (context->hasher)\ - static_cast<HasherType*>(context->hasher)->method arg2;\ - if (context->validators)\ - for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ - static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\ - if (context->patternPropertiesValidators)\ - for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ - static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\ - } - -#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ - return valid_ = EndValue() && outputHandler_.method arg2 - -#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ - RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ - RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) - - bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); } - bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } - bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } - bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } - bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } - bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } - bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } - bool RawNumber(const Ch* str, SizeType length, bool copy) - { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } - bool String(const Ch* str, SizeType length, bool copy) - { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } - - bool StartObject() { - RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); - return valid_ = outputHandler_.StartObject(); - } - - bool Key(const Ch* str, SizeType len, bool copy) { - if (!valid_) return false; - AppendToken(str, len); - if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); - return valid_ = outputHandler_.Key(str, len, copy); - } - - bool EndObject(SizeType memberCount) { - if (!valid_) return false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); - if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); - } - - bool StartArray() { - RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); - return valid_ = outputHandler_.StartArray(); - } - - bool EndArray(SizeType elementCount) { - if (!valid_) return false; - RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); - if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; - RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); - } - -#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ -#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ -#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ -#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ - - // Implementation of ISchemaStateFactory<SchemaType> - virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { - return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, -#if RAPIDJSON_SCHEMA_VERBOSE - depth_ + 1, -#endif - &GetStateAllocator()); - } - - virtual void DestroySchemaValidator(ISchemaValidator* validator) { - GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator); - v->~GenericSchemaValidator(); - StateAllocator::Free(v); - } - - virtual void* CreateHasher() { - return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); - } - - virtual uint64_t GetHashCode(void* hasher) { - return static_cast<HasherType*>(hasher)->GetHashCode(); - } - - virtual void DestroryHasher(void* hasher) { - HasherType* h = static_cast<HasherType*>(hasher); - h->~HasherType(); - StateAllocator::Free(h); - } - - virtual void* MallocState(size_t size) { - return GetStateAllocator().Malloc(size); - } - - virtual void FreeState(void* p) { - return StateAllocator::Free(p); - } - -private: - typedef typename SchemaType::Context Context; - typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray; - typedef internal::Hasher<EncodingType, StateAllocator> HasherType; - - GenericSchemaValidator( - const SchemaDocumentType& schemaDocument, - const SchemaType& root, -#if RAPIDJSON_SCHEMA_VERBOSE - unsigned depth, -#endif - StateAllocator* allocator = 0, - size_t schemaStackCapacity = kDefaultSchemaStackCapacity, - size_t documentStackCapacity = kDefaultDocumentStackCapacity) - : - schemaDocument_(&schemaDocument), - root_(root), - outputHandler_(GetNullHandler()), - stateAllocator_(allocator), - ownStateAllocator_(0), - schemaStack_(allocator, schemaStackCapacity), - documentStack_(allocator, documentStackCapacity), - valid_(true) -#if RAPIDJSON_SCHEMA_VERBOSE - , depth_(depth) -#endif - { - } - - StateAllocator& GetStateAllocator() { - if (!stateAllocator_) - stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator()); - return *stateAllocator_; - } - - bool BeginValue() { - if (schemaStack_.Empty()) - PushSchema(root_); - else { - if (CurrentContext().inArray) - internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); - - if (!CurrentSchema().BeginValue(CurrentContext())) - return false; - - SizeType count = CurrentContext().patternPropertiesSchemaCount; - const SchemaType** sa = CurrentContext().patternPropertiesSchemas; - typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; - bool valueUniqueness = CurrentContext().valueUniqueness; - if (CurrentContext().valueSchema) - PushSchema(*CurrentContext().valueSchema); - - if (count > 0) { - CurrentContext().objectPatternValidatorType = patternValidatorType; - ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; - SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; - va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count)); - for (SizeType i = 0; i < count; i++) - va[validatorCount++] = CreateSchemaValidator(*sa[i]); - } - - CurrentContext().arrayUniqueness = valueUniqueness; - } - return true; - } - - bool EndValue() { - if (!CurrentSchema().EndValue(CurrentContext())) - return false; - -#if RAPIDJSON_SCHEMA_VERBOSE - GenericStringBuffer<EncodingType> sb; - schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); - - *documentStack_.template Push<Ch>() = '\0'; - documentStack_.template Pop<Ch>(1); - internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>()); -#endif - - uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0; - - PopSchema(); - - if (!schemaStack_.Empty()) { - Context& context = CurrentContext(); - if (context.valueUniqueness) { - HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes); - if (!a) - CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); - for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) - if (itr->GetUint64() == h) - RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); - a->PushBack(h, GetStateAllocator()); - } - } - - // Remove the last token of document pointer - while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/') - ; - - return true; - } - - void AppendToken(const Ch* str, SizeType len) { - documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters - *documentStack_.template PushUnsafe<Ch>() = '/'; - for (SizeType i = 0; i < len; i++) { - if (str[i] == '~') { - *documentStack_.template PushUnsafe<Ch>() = '~'; - *documentStack_.template PushUnsafe<Ch>() = '0'; - } - else if (str[i] == '/') { - *documentStack_.template PushUnsafe<Ch>() = '~'; - *documentStack_.template PushUnsafe<Ch>() = '1'; - } - else - *documentStack_.template PushUnsafe<Ch>() = str[i]; - } - } - - RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); } - - RAPIDJSON_FORCEINLINE void PopSchema() { - Context* c = schemaStack_.template Pop<Context>(1); - if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) { - a->~HashCodeArray(); - StateAllocator::Free(a); - } - c->~Context(); - } - - const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; } - Context& CurrentContext() { return *schemaStack_.template Top<Context>(); } - const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); } - - static OutputHandler& GetNullHandler() { - static OutputHandler nullHandler; - return nullHandler; - } - - static const size_t kDefaultSchemaStackCapacity = 1024; - static const size_t kDefaultDocumentStackCapacity = 256; - const SchemaDocumentType* schemaDocument_; - const SchemaType& root_; - OutputHandler& outputHandler_; - StateAllocator* stateAllocator_; - StateAllocator* ownStateAllocator_; - internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) - internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch) - bool valid_; -#if RAPIDJSON_SCHEMA_VERBOSE - unsigned depth_; -#endif -}; - -typedef GenericSchemaValidator<SchemaDocument> SchemaValidator; - -/////////////////////////////////////////////////////////////////////////////// -// SchemaValidatingReader - -//! A helper class for parsing with validation. -/*! - This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). - - \tparam parseFlags Combination of \ref ParseFlag. - \tparam InputStream Type of input stream, implementing Stream concept. - \tparam SourceEncoding Encoding of the input stream. - \tparam SchemaDocumentType Type of schema document. - \tparam StackAllocator Allocator type for stack. -*/ -template < - unsigned parseFlags, - typename InputStream, - typename SourceEncoding, - typename SchemaDocumentType = SchemaDocument, - typename StackAllocator = CrtAllocator> -class SchemaValidatingReader { -public: - typedef typename SchemaDocumentType::PointerType PointerType; - typedef typename InputStream::Ch Ch; - - //! Constructor - /*! - \param is Input stream. - \param sd Schema document. - */ - SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {} - - template <typename Handler> - bool operator()(Handler& handler) { - GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader; - GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler); - parseResult_ = reader.template Parse<parseFlags>(is_, validator); - - isValid_ = validator.IsValid(); - if (isValid_) { - invalidSchemaPointer_ = PointerType(); - invalidSchemaKeyword_ = 0; - invalidDocumentPointer_ = PointerType(); - } - else { - invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); - invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); - invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); - } - - return parseResult_; - } - - const ParseResult& GetParseResult() const { return parseResult_; } - bool IsValid() const { return isValid_; } - const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } - const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } - const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } - -private: - InputStream& is_; - const SchemaDocumentType& sd_; - - ParseResult parseResult_; - PointerType invalidSchemaPointer_; - const Ch* invalidSchemaKeyword_; - PointerType invalidDocumentPointer_; - bool isValid_; -}; - -RAPIDJSON_NAMESPACE_END -RAPIDJSON_DIAG_POP - -#endif // RAPIDJSON_SCHEMA_H_ diff --git a/external/rapidjson/stream.h b/external/rapidjson/stream.h deleted file mode 100644 index fef82c252..000000000 --- a/external/rapidjson/stream.h +++ /dev/null @@ -1,179 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#include "rapidjson.h" - -#ifndef RAPIDJSON_STREAM_H_ -#define RAPIDJSON_STREAM_H_ - -#include "encodings.h" - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Stream - -/*! \class rapidjson::Stream - \brief Concept for reading and writing characters. - - For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). - - For write-only stream, only need to implement Put() and Flush(). - -\code -concept Stream { - typename Ch; //!< Character type of the stream. - - //! Read the current character from stream without moving the read cursor. - Ch Peek() const; - - //! Read the current character from stream and moving the read cursor to next character. - Ch Take(); - - //! Get the current read cursor. - //! \return Number of characters read from start. - size_t Tell(); - - //! Begin writing operation at the current read pointer. - //! \return The begin writer pointer. - Ch* PutBegin(); - - //! Write a character. - void Put(Ch c); - - //! Flush the buffer. - void Flush(); - - //! End the writing operation. - //! \param begin The begin write pointer returned by PutBegin(). - //! \return Number of characters written. - size_t PutEnd(Ch* begin); -} -\endcode -*/ - -//! Provides additional information for stream. -/*! - By using traits pattern, this type provides a default configuration for stream. - For custom stream, this type can be specialized for other configuration. - See TEST(Reader, CustomStringStream) in readertest.cpp for example. -*/ -template<typename Stream> -struct StreamTraits { - //! Whether to make local copy of stream for optimization during parsing. - /*! - By default, for safety, streams do not use local copy optimization. - Stream that can be copied fast should specialize this, like StreamTraits<StringStream>. - */ - enum { copyOptimization = 0 }; -}; - -//! Reserve n characters for writing to a stream. -template<typename Stream> -inline void PutReserve(Stream& stream, size_t count) { - (void)stream; - (void)count; -} - -//! Write character to a stream, presuming buffer is reserved. -template<typename Stream> -inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { - stream.Put(c); -} - -//! Put N copies of a character to a stream. -template<typename Stream, typename Ch> -inline void PutN(Stream& stream, Ch c, size_t n) { - PutReserve(stream, n); - for (size_t i = 0; i < n; i++) - PutUnsafe(stream, c); -} - -/////////////////////////////////////////////////////////////////////////////// -// StringStream - -//! Read-only string stream. -/*! \note implements Stream concept -*/ -template <typename Encoding> -struct GenericStringStream { - typedef typename Encoding::Ch Ch; - - GenericStringStream(const Ch *src) : src_(src), head_(src) {} - - Ch Peek() const { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() const { return static_cast<size_t>(src_ - head_); } - - Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } - void Put(Ch) { RAPIDJSON_ASSERT(false); } - void Flush() { RAPIDJSON_ASSERT(false); } - size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } - - const Ch* src_; //!< Current read position. - const Ch* head_; //!< Original head of the string. -}; - -template <typename Encoding> -struct StreamTraits<GenericStringStream<Encoding> > { - enum { copyOptimization = 1 }; -}; - -//! String stream with UTF8 encoding. -typedef GenericStringStream<UTF8<> > StringStream; - -/////////////////////////////////////////////////////////////////////////////// -// InsituStringStream - -//! A read-write string stream. -/*! This string stream is particularly designed for in-situ parsing. - \note implements Stream concept -*/ -template <typename Encoding> -struct GenericInsituStringStream { - typedef typename Encoding::Ch Ch; - - GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} - - // Read - Ch Peek() { return *src_; } - Ch Take() { return *src_++; } - size_t Tell() { return static_cast<size_t>(src_ - head_); } - - // Write - void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } - - Ch* PutBegin() { return dst_ = src_; } - size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); } - void Flush() {} - - Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } - void Pop(size_t count) { dst_ -= count; } - - Ch* src_; - Ch* dst_; - Ch* head_; -}; - -template <typename Encoding> -struct StreamTraits<GenericInsituStringStream<Encoding> > { - enum { copyOptimization = 1 }; -}; - -//! Insitu string stream with UTF8 encoding. -typedef GenericInsituStringStream<UTF8<> > InsituStringStream; - -RAPIDJSON_NAMESPACE_END - -#endif // RAPIDJSON_STREAM_H_ diff --git a/external/rapidjson/stringbuffer.h b/external/rapidjson/stringbuffer.h deleted file mode 100644 index 78f34d209..000000000 --- a/external/rapidjson/stringbuffer.h +++ /dev/null @@ -1,117 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_STRINGBUFFER_H_ -#define RAPIDJSON_STRINGBUFFER_H_ - -#include "stream.h" -#include "internal/stack.h" - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS -#include <utility> // std::move -#endif - -#include "internal/stack.h" - -#if defined(__clang__) -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(c++98-compat) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -//! Represents an in-memory output stream. -/*! - \tparam Encoding Encoding of the stream. - \tparam Allocator type for allocating memory buffer. - \note implements Stream concept -*/ -template <typename Encoding, typename Allocator = CrtAllocator> -class GenericStringBuffer { -public: - typedef typename Encoding::Ch Ch; - - GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} - -#if RAPIDJSON_HAS_CXX11_RVALUE_REFS - GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} - GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { - if (&rhs != this) - stack_ = std::move(rhs.stack_); - return *this; - } -#endif - - void Put(Ch c) { *stack_.template Push<Ch>() = c; } - void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; } - void Flush() {} - - void Clear() { stack_.Clear(); } - void ShrinkToFit() { - // Push and pop a null terminator. This is safe. - *stack_.template Push<Ch>() = '\0'; - stack_.ShrinkToFit(); - stack_.template Pop<Ch>(1); - } - - void Reserve(size_t count) { stack_.template Reserve<Ch>(count); } - Ch* Push(size_t count) { return stack_.template Push<Ch>(count); } - Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); } - void Pop(size_t count) { stack_.template Pop<Ch>(count); } - - const Ch* GetString() const { - // Push and pop a null terminator. This is safe. - *stack_.template Push<Ch>() = '\0'; - stack_.template Pop<Ch>(1); - - return stack_.template Bottom<Ch>(); - } - - size_t GetSize() const { return stack_.GetSize(); } - - static const size_t kDefaultCapacity = 256; - mutable internal::Stack<Allocator> stack_; - -private: - // Prohibit copy constructor & assignment operator. - GenericStringBuffer(const GenericStringBuffer&); - GenericStringBuffer& operator=(const GenericStringBuffer&); -}; - -//! String buffer with UTF8 encoding -typedef GenericStringBuffer<UTF8<> > StringBuffer; - -template<typename Encoding, typename Allocator> -inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) { - stream.Reserve(count); -} - -template<typename Encoding, typename Allocator> -inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) { - stream.PutUnsafe(c); -} - -//! Implement specialized version of PutN() with memset() for better performance. -template<> -inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) { - std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c)); -} - -RAPIDJSON_NAMESPACE_END - -#if defined(__clang__) -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/external/rapidjson/writer.h b/external/rapidjson/writer.h deleted file mode 100644 index c5a3b98a9..000000000 --- a/external/rapidjson/writer.h +++ /dev/null @@ -1,616 +0,0 @@ -// Tencent is pleased to support the open source community by making RapidJSON available. -// -// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. -// -// Licensed under the MIT License (the "License"); you may not use this file except -// in compliance with the License. You may obtain a copy of the License at -// -// http://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software distributed -// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, either express or implied. See the License for the -// specific language governing permissions and limitations under the License. - -#ifndef RAPIDJSON_WRITER_H_ -#define RAPIDJSON_WRITER_H_ - -#include "stream.h" -#include "internal/stack.h" -#include "internal/strfunc.h" -#include "internal/dtoa.h" -#include "internal/itoa.h" -#include "stringbuffer.h" -#include <new> // placement new - -#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) -#include <intrin.h> -#pragma intrinsic(_BitScanForward) -#endif -#ifdef RAPIDJSON_SSE42 -#include <nmmintrin.h> -#elif defined(RAPIDJSON_SSE2) -#include <emmintrin.h> -#endif - -#ifdef _MSC_VER -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_PUSH -RAPIDJSON_DIAG_OFF(padded) -RAPIDJSON_DIAG_OFF(unreachable-code) -#endif - -RAPIDJSON_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// WriteFlag - -/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS - \ingroup RAPIDJSON_CONFIG - \brief User-defined kWriteDefaultFlags definition. - - User can define this as any \c WriteFlag combinations. -*/ -#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS -#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags -#endif - -//! Combination of writeFlags -enum WriteFlag { - kWriteNoFlags = 0, //!< No flags are set. - kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. - kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. - kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS -}; - -//! JSON writer -/*! Writer implements the concept Handler. - It generates JSON text by events to an output os. - - User may programmatically calls the functions of a writer to generate JSON text. - - On the other side, a writer can also be passed to objects that generates events, - - for example Reader::Parse() and Document::Accept(). - - \tparam OutputStream Type of output stream. - \tparam SourceEncoding Encoding of source string. - \tparam TargetEncoding Encoding of output stream. - \tparam StackAllocator Type of allocator for allocating memory of stack. - \note implements Handler concept -*/ -template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> -class Writer { -public: - typedef typename SourceEncoding::Ch Ch; - - static const int kDefaultMaxDecimalPlaces = 324; - - //! Constructor - /*! \param os Output stream. - \param stackAllocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of stack. - */ - explicit - Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - - explicit - Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : - os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} - - //! Reset the writer with a new stream. - /*! - This function reset the writer with a new stream and default settings, - in order to make a Writer object reusable for output multiple JSONs. - - \param os New output stream. - \code - Writer<OutputStream> writer(os1); - writer.StartObject(); - // ... - writer.EndObject(); - - writer.Reset(os2); - writer.StartObject(); - // ... - writer.EndObject(); - \endcode - */ - void Reset(OutputStream& os) { - os_ = &os; - hasRoot_ = false; - level_stack_.Clear(); - } - - //! Checks whether the output is a complete JSON. - /*! - A complete JSON has a complete root object or array. - */ - bool IsComplete() const { - return hasRoot_ && level_stack_.Empty(); - } - - int GetMaxDecimalPlaces() const { - return maxDecimalPlaces_; - } - - //! Sets the maximum number of decimal places for double output. - /*! - This setting truncates the output with specified number of decimal places. - - For example, - - \code - writer.SetMaxDecimalPlaces(3); - writer.StartArray(); - writer.Double(0.12345); // "0.123" - writer.Double(0.0001); // "0.0" - writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) - writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) - writer.EndArray(); - \endcode - - The default setting does not truncate any decimal places. You can restore to this setting by calling - \code - writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); - \endcode - */ - void SetMaxDecimalPlaces(int maxDecimalPlaces) { - maxDecimalPlaces_ = maxDecimalPlaces; - } - - /*!@name Implementation of Handler - \see Handler - */ - //@{ - - bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } - bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } - bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } - bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } - bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } - bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } - - //! Writes the given \c double value to the stream - /*! - \param d The value to be written. - \return Whether it is succeed. - */ - bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } - - bool RawNumber(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kNumberType); - return EndValue(WriteString(str, length)); - } - - bool String(const Ch* str, SizeType length, bool copy = false) { - RAPIDJSON_ASSERT(str != 0); - (void)copy; - Prefix(kStringType); - return EndValue(WriteString(str, length)); - } - -#if RAPIDJSON_HAS_STDSTRING - bool String(const std::basic_string<Ch>& str) { - return String(str.data(), SizeType(str.size())); - } -#endif - - bool StartObject() { - Prefix(kObjectType); - new (level_stack_.template Push<Level>()) Level(false); - return WriteStartObject(); - } - - bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } - - bool EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); - level_stack_.template Pop<Level>(1); - return EndValue(WriteEndObject()); - } - - bool StartArray() { - Prefix(kArrayType); - new (level_stack_.template Push<Level>()) Level(true); - return WriteStartArray(); - } - - bool EndArray(SizeType elementCount = 0) { - (void)elementCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray); - level_stack_.template Pop<Level>(1); - return EndValue(WriteEndArray()); - } - //@} - - /*! @name Convenience extensions */ - //@{ - - //! Simpler but slower overload. - bool String(const Ch* str) { return String(str, internal::StrLen(str)); } - bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } - - //@} - - //! Write a raw JSON value. - /*! - For user to write a stringified JSON as a value. - - \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. - \param length Length of the json. - \param type Type of the root of json. - */ - bool RawValue(const Ch* json, size_t length, Type type) { - RAPIDJSON_ASSERT(json != 0); - Prefix(type); - return EndValue(WriteRawValue(json, length)); - } - -protected: - //! Information for each nested level - struct Level { - Level(bool inArray_) : valueCount(0), inArray(inArray_) {} - size_t valueCount; //!< number of values in this level - bool inArray; //!< true if in array, otherwise in object - }; - - static const size_t kDefaultLevelDepth = 32; - - bool WriteNull() { - PutReserve(*os_, 4); - PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; - } - - bool WriteBool(bool b) { - if (b) { - PutReserve(*os_, 4); - PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); - } - else { - PutReserve(*os_, 5); - PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); - } - return true; - } - - bool WriteInt(int i) { - char buffer[11]; - const char* end = internal::i32toa(i, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); - return true; - } - - bool WriteUint(unsigned u) { - char buffer[10]; - const char* end = internal::u32toa(u, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); - return true; - } - - bool WriteInt64(int64_t i64) { - char buffer[21]; - const char* end = internal::i64toa(i64, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (const char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); - return true; - } - - bool WriteUint64(uint64_t u64) { - char buffer[20]; - char* end = internal::u64toa(u64, buffer); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); - return true; - } - - bool WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - if (!(writeFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char buffer[25]; - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - PutReserve(*os_, static_cast<size_t>(end - buffer)); - for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); - return true; - } - - bool WriteString(const Ch* str, SizeType length) { - static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - static const char escape[256] = { -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 - 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - Z16, Z16, // 30~4F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF -#undef Z16 - }; - - if (TargetEncoding::supportUnicode) - PutReserve(*os_, 2 + length * 6); // "\uxxxx..." - else - PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." - - PutUnsafe(*os_, '\"'); - GenericStringStream<SourceEncoding> is(str); - while (ScanWriteUnescapedString(is, length)) { - const Ch c = is.Peek(); - if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) { - // Unicode escaping - unsigned codepoint; - if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) - return false; - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { - PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); - } - else { - RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); - // Surrogate pair - unsigned s = codepoint - 0x010000; - unsigned lead = (s >> 10) + 0xD800; - unsigned trail = (s & 0x3FF) + 0xDC00; - PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(lead ) & 15]); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, 'u'); - PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); - PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); - PutUnsafe(*os_, hexDigits[(trail ) & 15]); - } - } - else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) { - is.Take(); - PutUnsafe(*os_, '\\'); - PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)])); - if (escape[static_cast<unsigned char>(c)] == 'u') { - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, '0'); - PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]); - PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]); - } - } - else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? - Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) : - Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_)))) - return false; - } - PutUnsafe(*os_, '\"'); - return true; - } - - bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) { - return RAPIDJSON_LIKELY(is.Tell() < length); - } - - bool WriteStartObject() { os_->Put('{'); return true; } - bool WriteEndObject() { os_->Put('}'); return true; } - bool WriteStartArray() { os_->Put('['); return true; } - bool WriteEndArray() { os_->Put(']'); return true; } - - bool WriteRawValue(const Ch* json, size_t length) { - PutReserve(*os_, length); - for (size_t i = 0; i < length; i++) { - RAPIDJSON_ASSERT(json[i] != '\0'); - PutUnsafe(*os_, json[i]); - } - return true; - } - - void Prefix(Type type) { - (void)type; - if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root - Level* level = level_stack_.template Top<Level>(); - if (level->valueCount > 0) { - if (level->inArray) - os_->Put(','); // add comma if it is not the first element in array - else // in object - os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else { - RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. - hasRoot_ = true; - } - } - - // Flush the value if it is the top level one. - bool EndValue(bool ret) { - if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text - os_->Flush(); - return ret; - } - - OutputStream* os_; - internal::Stack<StackAllocator> level_stack_; - int maxDecimalPlaces_; - bool hasRoot_; - -private: - // Prohibit copy constructor & assignment operator. - Writer(const Writer&); - Writer& operator=(const Writer&); -}; - -// Full specialization for StringStream to prevent memory copying - -template<> -inline bool Writer<StringBuffer>::WriteInt(int i) { - char *buffer = os_->Push(11); - const char* end = internal::i32toa(i, buffer); - os_->Pop(static_cast<size_t>(11 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteUint(unsigned u) { - char *buffer = os_->Push(10); - const char* end = internal::u32toa(u, buffer); - os_->Pop(static_cast<size_t>(10 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) { - char *buffer = os_->Push(21); - const char* end = internal::i64toa(i64, buffer); - os_->Pop(static_cast<size_t>(21 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) { - char *buffer = os_->Push(20); - const char* end = internal::u64toa(u, buffer); - os_->Pop(static_cast<size_t>(20 - (end - buffer))); - return true; -} - -template<> -inline bool Writer<StringBuffer>::WriteDouble(double d) { - if (internal::Double(d).IsNanOrInf()) { - // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). - if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) - return false; - if (internal::Double(d).IsNan()) { - PutReserve(*os_, 3); - PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); - return true; - } - if (internal::Double(d).Sign()) { - PutReserve(*os_, 9); - PutUnsafe(*os_, '-'); - } - else - PutReserve(*os_, 8); - PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); - PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); - return true; - } - - char *buffer = os_->Push(25); - char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); - os_->Pop(static_cast<size_t>(25 - (end - buffer))); - return true; -} - -#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) -template<> -inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) { - if (length < 16) - return RAPIDJSON_LIKELY(is.Tell() < length); - - if (!RAPIDJSON_LIKELY(is.Tell() < length)) - return false; - - const char* p = is.src_; - const char* end = is.head_ + length; - const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); - const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15)); - if (nextAligned > end) - return true; - - while (p != nextAligned) - if (*p < 0x20 || *p == '\"' || *p == '\\') { - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); - } - else - os_->PutUnsafe(*p++); - - // The rest of string using SIMD - static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; - static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; - static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; - const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); - const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); - const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); - - for (; p != endAligned; p += 16) { - const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); - const __m128i t1 = _mm_cmpeq_epi8(s, dq); - const __m128i t2 = _mm_cmpeq_epi8(s, bs); - const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 - const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); - unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); - if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped - SizeType len; -#ifdef _MSC_VER // Find the index of first escaped - unsigned long offset; - _BitScanForward(&offset, r); - len = offset; -#else - len = static_cast<SizeType>(__builtin_ffs(r) - 1); -#endif - char* q = reinterpret_cast<char*>(os_->PushUnsafe(len)); - for (size_t i = 0; i < len; i++) - q[i] = p[i]; - - p += len; - break; - } - _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); - } - - is.src_ = p; - return RAPIDJSON_LIKELY(is.Tell() < length); -} -#endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) - -RAPIDJSON_NAMESPACE_END - -#ifdef _MSC_VER -RAPIDJSON_DIAG_POP -#endif - -#ifdef __clang__ -RAPIDJSON_DIAG_POP -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ |