mirror of
https://github.com/monero-project/monero.git
synced 2025-01-28 18:56:31 +02:00
Merge with upstream
This commit is contained in:
commit
18cbb876d0
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +1,2 @@
|
||||
.git* export-ignore
|
||||
/CMakeLists.txt export-subst
|
||||
version.cmake export-subst
|
||||
|
117
CMakeLists.txt
117
CMakeLists.txt
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2014, The Monero Project
|
||||
# Copyright (c) 2014-2015, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
@ -28,33 +28,41 @@
|
||||
#
|
||||
# Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.6)
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
|
||||
if(NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
set(ColourReset "${Esc}[m")
|
||||
set(BoldRed "${Esc}[1;31m")
|
||||
endif()
|
||||
project(bitmonero)
|
||||
|
||||
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
function (die msg)
|
||||
if (NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
set(ColourReset "${Esc}[m")
|
||||
set(BoldRed "${Esc}[1;31m")
|
||||
else ()
|
||||
set(ColourReset "")
|
||||
set(BoldRed "")
|
||||
endif ()
|
||||
|
||||
message(FATAL_ERROR "${BoldRed}${msg}${ColourReset}")
|
||||
endfunction ()
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0
|
||||
"${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
if (NOT DEFINED ENV{DEVELOPER_LOCAL_TOOLS})
|
||||
message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF)
|
||||
elseif ("$ENV{DEVELOPER_LOCAL_TOOLS}" EQUAL 1)
|
||||
message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 1")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT ON)
|
||||
option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" ON)
|
||||
message(STATUS "Could not find DEVELOPER_LOCAL_TOOLS in env (not required)")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF)
|
||||
elseif (ENV{DEVELOPER_LOCAL_TOOLS} EQUAL 1)
|
||||
message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 1")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT ON)
|
||||
else()
|
||||
message(STATUS "found: env DEVELOPER_LOCAL_TOOLS = 0")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF)
|
||||
message(STATUS "Found: env DEVELOPER_LOCAL_TOOLS = 0")
|
||||
set(BOOST_IGNORE_SYSTEM_PATHS_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
message(STATUS "BOOST_IGNORE_SYSTEM_PATHS defaults to ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT}")
|
||||
option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost ins tallation" $BOOST_IGNORE_SYSTEM_PATHS_DEFAULT)
|
||||
option(BOOST_IGNORE_SYSTEM_PATHS "Ignore boost system paths for local boost installation" ${BOOST_IGNORE_SYSTEM_PATHS_DEFAULT})
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
|
||||
enable_testing()
|
||||
|
||||
# Check if we're on FreeBSD so we can exclude the local miniupnpc (it should be installed from ports instead)
|
||||
@ -86,15 +94,28 @@ if(MSVC OR MINGW)
|
||||
else()
|
||||
set(DEFAULT_STATIC false)
|
||||
endif()
|
||||
set(STATIC ${DEFAULT_STATIC} CACHE BOOL "Link libraries statically")
|
||||
option(STATIC "Link libraries statically" ${DEFAULT_STATIC})
|
||||
|
||||
IF(STATIC)
|
||||
IF(MSVC)
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
ELSE()
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
if(MINGW)
|
||||
get_filename_component(msys2_install_path "[HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS2 64bit;InstallLocation]" ABSOLUTE)
|
||||
set(CMAKE_INCLUDE_PATH "${msys2_install_path}/mingw64/include")
|
||||
# This is necessary because otherwise CMake will make Boost libraries -lfoo
|
||||
# rather than a full path. Unfortunately, this makes the shared libraries get
|
||||
# linked due to a bug in CMake which misses putting -static flags around the
|
||||
# -lfoo arguments.
|
||||
list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_DIRECTORIES
|
||||
"${msys2_install_path}/mingw64/lib")
|
||||
list(REMOVE_ITEM CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES
|
||||
"${msys2_install_path}/mingw64/lib")
|
||||
endif()
|
||||
|
||||
if(STATIC)
|
||||
if(MSVC)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll.a .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else()
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
# Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail
|
||||
@ -113,6 +134,10 @@ endif()
|
||||
|
||||
# Final setup for libunbound
|
||||
include_directories(${UNBOUND_INCLUDE})
|
||||
link_directories(${UNBOUND_LIBRARY_DIRS})
|
||||
|
||||
# Final setup for rapidjson
|
||||
include_directories(external/rapidjson)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
|
||||
@ -126,12 +151,15 @@ if(MSVC)
|
||||
include_directories(SYSTEM src/platform/msc)
|
||||
else()
|
||||
set(ARCH native CACHE STRING "CPU to build for: -march value or default")
|
||||
if("${ARCH}" STREQUAL "default")
|
||||
if(ARCH STREQUAL "default")
|
||||
set(ARCH_FLAG "")
|
||||
else()
|
||||
set(ARCH_FLAG "-march=${ARCH}")
|
||||
endif()
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Werror -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
if(NOT MINGW)
|
||||
set(WARNINGS "${WARNINGS} -Werror")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration")
|
||||
else()
|
||||
@ -142,6 +170,8 @@ else()
|
||||
set(MINGW_FLAG "${MINGW_FLAG} -DWIN32_LEAN_AND_MEAN")
|
||||
set(Boost_THREADAPI win32)
|
||||
include_directories(SYSTEM src/platform/mingw)
|
||||
# mingw doesn't support LTO (multiple definition errors at link time)
|
||||
set(USE_LTO_DEFAULT false)
|
||||
endif()
|
||||
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes")
|
||||
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")
|
||||
@ -171,7 +201,7 @@ else()
|
||||
|
||||
# There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
set(USE_LTO false)
|
||||
set(USE_LTO false)
|
||||
endif()
|
||||
if(USE_LTO)
|
||||
set(RELEASE_FLAGS "${RELEASE_FLAGS} -flto")
|
||||
@ -195,7 +225,7 @@ else()
|
||||
endif()
|
||||
|
||||
if (BOOST_IGNORE_SYSTEM_PATHS)
|
||||
set(Boost_NO_SYSTEM_PATHS TRUE)
|
||||
set(Boost_NO_SYSTEM_PATHS TRUE)
|
||||
endif()
|
||||
|
||||
if(STATIC)
|
||||
@ -205,36 +235,27 @@ endif()
|
||||
find_package(Boost 1.53 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options)
|
||||
|
||||
if(NOT Boost_FOUND)
|
||||
MESSAGE(FATAL_ERROR "${BoldRed}Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.53 or 1.55+) or the equivalent${ColourReset}")
|
||||
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.53 or 1.55+) or the equivalent")
|
||||
endif()
|
||||
|
||||
if((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 54))
|
||||
message(FATAL_ERROR "${BoldRed}Boost version 1.54 is unsupported due to a bug (see: http://goo.gl/RrCFmA), please install Boost 1.53 or 1.55 and above${ColourReset}")
|
||||
if((Boost_MAJOR_VERSION EQUAL 1) AND (Boost_MINOR_VERSION EQUAL 54))
|
||||
die("Boost version 1.54 is unsupported due to a bug (see: http://goo.gl/RrCFmA), please install Boost 1.53 or 1.55 and above")
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
if(MINGW)
|
||||
set(EXTRA_LIBRARIES pthread;mswsock;ws2_32)
|
||||
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi)
|
||||
elseif(APPLE OR FREEBSD)
|
||||
set(EXTRA_LIBRARIES "")
|
||||
elseif(NOT MSVC)
|
||||
find_library(RT rt)
|
||||
find_library(PTHREAD pthread)
|
||||
find_library(DL dl)
|
||||
set(EXTRA_LIBRARIES ${RT} ${PTHREAD} ${DL})
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/version")
|
||||
find_package(Git QUIET)
|
||||
if(Git_FOUND OR GIT_FOUND)
|
||||
message(STATUS "Found Git: ${GIT_EXECUTABLE}")
|
||||
add_custom_target(version ALL "${CMAKE_COMMAND}" "-D" "GIT=${GIT_EXECUTABLE}" "-D" "TO=${CMAKE_BINARY_DIR}/version/version.h" "-P" "src/version.cmake" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
else()
|
||||
message(STATUS "WARNING: Git was not found!")
|
||||
set(VERSIONTAG "unknown")
|
||||
configure_file("src/version.h.in" "version/version.h")
|
||||
add_custom_target(version ALL)
|
||||
endif()
|
||||
include(version.cmake)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
16
Makefile
16
Makefile
@ -8,9 +8,12 @@ build-debug: cmake-debug
|
||||
cd build/debug && $(MAKE)
|
||||
|
||||
test-debug: build-debug
|
||||
cd build/debug && $(MAKE) test
|
||||
mkdir -p build/debug
|
||||
cd build/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE) test
|
||||
|
||||
all-debug: build-debug
|
||||
all-debug:
|
||||
mkdir -p build/debug
|
||||
cd build/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug ../.. && $(MAKE)
|
||||
|
||||
cmake-release:
|
||||
mkdir -p build/release
|
||||
@ -20,13 +23,16 @@ build-release: cmake-release
|
||||
cd build/release && $(MAKE)
|
||||
|
||||
test-release: build-release
|
||||
cd build/release && $(MAKE) test
|
||||
mkdir -p build/release
|
||||
cd build/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE) test
|
||||
|
||||
all-release: build-release
|
||||
all-release:
|
||||
mkdir -p build/release
|
||||
cd build/release && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE)
|
||||
|
||||
release-static:
|
||||
mkdir -p build/release
|
||||
cd build/release && cmake -D STATIC=ON -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=Release ../.. && $(MAKE)
|
||||
cd build/release && cmake -D STATIC=ON -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=release ../.. && $(MAKE)
|
||||
|
||||
clean:
|
||||
@echo "WARNING: Back-up your wallet if it exists within ./build!" ; \
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Monero
|
||||
|
||||
Copyright (c) 2014, The Monero Project
|
||||
Copyright (c) 2014-2015, The Monero Project
|
||||
|
||||
## Development Resources
|
||||
|
||||
@ -30,7 +30,7 @@ Anyone is able to contribute to Monero. If you have a fix or code change, feel f
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014, The Monero Project
|
||||
Copyright (c) 2014-2015, The Monero Project
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@ -50,7 +50,7 @@ Parts of the project are originally copyright (c) 2012-2013 The Cryptonote devel
|
||||
|
||||
### On Unix and Linux:
|
||||
|
||||
Dependencies: GCC 4.7.3 or later, CMake 2.8.6 or later, libunbound 1.4.16 or later (note: Unbound is not a dependency, libunbound is), and Boost 1.53 or later (except 1.54, [more details here](http://goo.gl/RrCFmA)).
|
||||
Dependencies: GCC 4.7.3 or later, CMake 2.8.6 or later, libunbound 1.4.16 or later (note: Unbound is not a dependency, libunbound is), libevent 2.0 or later, libgtest 1.5 or later, and Boost 1.53 or later (except 1.54, [more details here](http://goo.gl/RrCFmA)).
|
||||
Static Build Additional Dependencies: ldns 1.6.17 or later, expat 1.1 or later, bison or yacc
|
||||
|
||||
**Basic Process:**
|
||||
|
@ -1,47 +0,0 @@
|
||||
Monero
|
||||
|
||||
Release notes 0.8.8
|
||||
|
||||
- JSON RPC v2.0 compatibility
|
||||
- JSON RPC over TCP added- Further optimizations
|
||||
- Fixed a bug with checkpoints behavior
|
||||
- UI improvements for daemon
|
||||
- Fixed COIN value (10^12)
|
||||
- Raised minimum fee to 5 * (10^9)
|
||||
- Temporary fix for block reward DoS attack
|
||||
|
||||
Release notes 0.8.7
|
||||
|
||||
- Slow hash optimizations
|
||||
|
||||
Release notes 0.8.6
|
||||
|
||||
- Simplwallet can set extra for transfers
|
||||
- Improvements in JSON RPC for wallet
|
||||
- UX improvements in simplewallet
|
||||
- Win32 compilation
|
||||
- Mac OSX compilation
|
||||
|
||||
Release notes 0.8.5
|
||||
|
||||
- Port mapping for daemon using UPnP
|
||||
- Improvements for daemon JSON RPC API
|
||||
|
||||
Release notes 0.8.4
|
||||
|
||||
- Formalization of high level API
|
||||
- Improvements for wallet JSON RPC API
|
||||
|
||||
Release notes 0.8.3
|
||||
|
||||
- JSON RPC for wallet
|
||||
- Fixed bug with blockchain storing
|
||||
- Fixed bug with correct display of transfer's change
|
||||
- Bug fix in simple wallet
|
||||
|
||||
Release notes 0.8.2
|
||||
|
||||
- Now wallet is still working when daemon stores blockchain and can't serve clients
|
||||
- No-console option for a daemon
|
||||
- Fixed problem with network synchronization
|
||||
- Major bug fix in simple wallet
|
@ -32,7 +32,7 @@
|
||||
if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
set(MINIUPNP_FIND_QUIETLY TRUE)
|
||||
endif (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY)
|
||||
endif ()
|
||||
|
||||
find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h
|
||||
PATH_SUFFIXES miniupnpc)
|
||||
@ -47,7 +47,7 @@ if (MINIUPNP_FOUND)
|
||||
if (NOT MINIUPNP_FIND_QUIETLY)
|
||||
message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}")
|
||||
message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}")
|
||||
endif (NOT MINIUPNP_FIND_QUIETLY)
|
||||
endif ()
|
||||
|
||||
message(STATUS "Detecting version of miniupnpc in path: ${MINIUPNP_INCLUDE_DIR}")
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2014, The Monero Project
|
||||
# Copyright (c) 2014-2015, The Monero Project
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
119
external/CMakeLists.txt
vendored
119
external/CMakeLists.txt
vendored
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2014, The Monero Project
|
||||
# Copyright (c) 2014-2015, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
@ -38,14 +38,14 @@
|
||||
find_package(MiniUpnpc QUIET)
|
||||
|
||||
# FreeBSD doesn't play well with the local copy, so default to using shared
|
||||
SET(USE_SHARED_MINIUPNPC false)
|
||||
set(USE_SHARED_MINIUPNPC false)
|
||||
|
||||
# If we have the correct shared version and we're not building static, use it
|
||||
IF(STATIC)
|
||||
SET(USE_SHARED_MINIUPNPC false)
|
||||
ELSEIF(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
SET(USE_SHARED_MINIUPNPC true)
|
||||
ENDIF()
|
||||
if(STATIC)
|
||||
set(USE_SHARED_MINIUPNPC false)
|
||||
elseif(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(USE_SHARED_MINIUPNPC true)
|
||||
endif()
|
||||
|
||||
if(USE_SHARED_MINIUPNPC)
|
||||
message(STATUS "Using shared miniupnpc found at ${MINIUPNP_INCLUDE_DIR}")
|
||||
@ -78,103 +78,26 @@ endif()
|
||||
|
||||
find_package(Unbound)
|
||||
|
||||
IF(!UNBOUND_INCLUDE_DIR OR STATIC)
|
||||
if(STATIC)
|
||||
message(STATUS "Using libunbound from local source tree for static build")
|
||||
else()
|
||||
message(STATUS "Using libunbound from local source tree (/external/unbound)")
|
||||
endif()
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
|
||||
FIND_PACKAGE(OpenSSL QUIET)
|
||||
IF(!OPENSSL_LIBRARIES)
|
||||
MESSAGE(FATAL_ERROR "${BoldRed}Could not find the openssl library. Please make sure you have installed openssl or libssl-dev or the equivalent${ColourReset}")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Found openssl libraries")
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(Expat QUIET)
|
||||
IF(!EXPAT_LIBRARIES)
|
||||
MESSAGE(FATAL_ERROR "${BoldRed}Could not find the expat library. Please make sure you have installed libexpat or libexpat-dev or the equivalent${ColourReset}")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Found expat libraries")
|
||||
ENDIF()
|
||||
|
||||
IF(MINGW)
|
||||
set(ENV{USE_WINSOCK} 1)
|
||||
set(ENV{CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(ENV{GCC_PREFIX} ${GCC_PREFIX})
|
||||
set(ENV{CMAKE_FIND_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH})
|
||||
EXTERNALPROJECT_ADD(
|
||||
libunbound
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/monero-config.sh
|
||||
BUILD_COMMAND $(MAKE)
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_UPDATE 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
LOG_TEST 1
|
||||
LOG_INSTALL 1
|
||||
)
|
||||
ELSEIF(APPLE)
|
||||
execute_process(COMMAND brew --prefix OUTPUT_VARIABLE BREW_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
EXTERNALPROJECT_ADD(
|
||||
libunbound
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/configure --prefix=${BREW_PREFIX} --enable-shared --enable-static --disable-gost --disable-rpath --with-libevent=no --without-pyunbound --without-pythonmodule --without-pthreads --with-libunbound-only
|
||||
BUILD_COMMAND $(MAKE)
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_UPDATE 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
LOG_TEST 1
|
||||
LOG_INSTALL 1
|
||||
)
|
||||
ELSE()
|
||||
EXTERNALPROJECT_ADD(
|
||||
libunbound
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/unbound
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/unbound/
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/unbound/configure --disable-shared --enable-static --disable-gost --disable-rpath --with-libevent=no --without-pyunbound --without-pythonmodule --without-pthreads --with-libunbound-only
|
||||
BUILD_COMMAND $(MAKE)
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND ""
|
||||
INSTALL_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libtool --mode=install cp ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.la ${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_UPDATE 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
LOG_TEST 1
|
||||
LOG_INSTALL 1
|
||||
)
|
||||
ENDIF()
|
||||
if(NOT UNBOUND_INCLUDE_DIR OR STATIC)
|
||||
add_subdirectory(unbound)
|
||||
|
||||
set(UNBOUND_STATIC true PARENT_SCOPE)
|
||||
set(UNBOUND_INCLUDE "${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build" PARENT_SCOPE)
|
||||
set(UNBOUND_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/unbound/src/libunbound-build/libunbound.a;${OPENSSL_LIBRARIES}" PARENT_SCOPE)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}")
|
||||
IF(UNBOUND_LIBRARIES)
|
||||
MESSAGE(STATUS "Found libunbound shared library")
|
||||
set(UNBOUND_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/unbound/libunbound" PARENT_SCOPE)
|
||||
set(UNBOUND_LIBRARY "unbound" PARENT_SCOPE)
|
||||
set(UNBOUND_LIBRARY_DIRS "${LIBEVENT2_LIBDIR}" PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}")
|
||||
if(UNBOUND_LIBRARIES)
|
||||
message(STATUS "Found libunbound shared library")
|
||||
set(UNBOUND_STATIC false PARENT_SCOPE)
|
||||
set(UNBOUND_INCLUDE ${UNBOUND_INCLUDE_DIR} PARENT_SCOPE)
|
||||
set(UNBOUND_LIBRARY ${UNBOUND_LIBRARIES} PARENT_SCOPE)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "${BoldRed}Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent${ColourReset}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
set(UNBOUND_LIBRARY_DIRS "" PARENT_SCOPE)
|
||||
else()
|
||||
die("Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(NET_SKELETON_SRCS net_skeleton/net_skeleton.c)
|
||||
add_library(net_skeleton ${NET_SKELETON_SRCS})
|
||||
set(NET_SKELETON_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libnet_skeleton.a" PARENT_SCOPE)
|
||||
|
||||
|
101
external/miniupnpc/CMakeLists.txt
vendored
101
external/miniupnpc/CMakeLists.txt
vendored
@ -4,64 +4,27 @@ project (miniupnpc C)
|
||||
set (MINIUPNPC_VERSION 1.9)
|
||||
set (MINIUPNPC_API_VERSION 10)
|
||||
|
||||
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()
|
||||
|
||||
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
||||
option (UPNPC_BUILD_SHARED "Build shared library" TRUE)
|
||||
if (NOT WIN32)
|
||||
option (UPNPC_BUILD_TESTS "Build test executables" TRUE)
|
||||
endif (NOT WIN32)
|
||||
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
||||
|
||||
mark_as_advanced (NO_GETADDRINFO)
|
||||
|
||||
if (NO_GETADDRINFO)
|
||||
add_definitions (-DNO_GETADDRINFO)
|
||||
endif (NO_GETADDRINFO)
|
||||
endif ()
|
||||
|
||||
if (NOT WIN32)
|
||||
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
|
||||
add_definitions (-D_BSD_SOURCE -D_POSIX_C_SOURCE=1)
|
||||
else (NOT WIN32)
|
||||
add_definitions (-D_BSD_SOURCE -D_POSIX_C_SOURCE=201112)
|
||||
else ()
|
||||
add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
|
||||
endif (NOT WIN32)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
add_definitions (-D_DARWIN_C_SOURCE)
|
||||
endif ()
|
||||
|
||||
# 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 ()
|
||||
|
||||
configure_file (miniupnpcstrings.h.cmake ${CMAKE_BINARY_DIR}/miniupnpcstrings.h)
|
||||
include_directories (${CMAKE_BINARY_DIR})
|
||||
|
||||
@ -80,16 +43,16 @@ set (MINIUPNPC_SOURCES
|
||||
receivedata.c
|
||||
)
|
||||
|
||||
if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||
if (NOT WIN32)
|
||||
set (MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c)
|
||||
endif (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
set_source_files_properties (${MINIUPNPC_SOURCES} PROPERTIES
|
||||
COMPILE_DEFINITIONS MINIUPNP_STATICLIB
|
||||
COMPILE_DEFINITIONS MINIUPNP_EXPORTS
|
||||
)
|
||||
endif (WIN32)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
# find_library (WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32)
|
||||
@ -97,63 +60,31 @@ if (WIN32)
|
||||
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)
|
||||
endif ()
|
||||
|
||||
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)
|
||||
message (FATAL "Both shared and static libraries are disabled!")
|
||||
endif ()
|
||||
|
||||
if (UPNPC_BUILD_STATIC)
|
||||
add_library (upnpc-static STATIC ${MINIUPNPC_SOURCES})
|
||||
set_target_properties (upnpc-static PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
set_target_properties (upnpc-static PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||
target_link_libraries (upnpc-static ${LDLIBS})
|
||||
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-static)
|
||||
set (UPNPC_LIBRARY_TARGET upnpc-static)
|
||||
endif (UPNPC_BUILD_STATIC)
|
||||
endif ()
|
||||
|
||||
if (UPNPC_BUILD_SHARED)
|
||||
add_library (upnpc-shared SHARED ${MINIUPNPC_SOURCES})
|
||||
set_target_properties (upnpc-shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
set_target_properties (upnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||
set_target_properties (upnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION})
|
||||
set_target_properties (upnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION})
|
||||
target_link_libraries (upnpc-shared ${LDLIBS})
|
||||
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-shared)
|
||||
set (UPNPC_LIBRARY_TARGET upnpc-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)
|
||||
|
||||
endif ()
|
||||
|
||||
install (TARGETS ${UPNPC_INSTALL_TARGETS}
|
||||
RUNTIME DESTINATION bin
|
||||
@ -161,7 +92,7 @@ install (TARGETS ${UPNPC_INSTALL_TARGETS}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX}
|
||||
)
|
||||
install (FILES
|
||||
miniupnpc.h
|
||||
miniupnpc.h
|
||||
miniwget.h
|
||||
upnpcommands.h
|
||||
igd_desc_parse.h
|
||||
@ -173,6 +104,4 @@ install (FILES
|
||||
DESTINATION include/miniupnpc
|
||||
)
|
||||
|
||||
set (CONFIGURED YES CACHE INTERNAL "")
|
||||
|
||||
# vim: ts=2:sw=2
|
||||
|
246
external/rapidjson/allocators.h
vendored
Normal file
246
external/rapidjson/allocators.h
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_ALLOCATORS_H_
|
||||
#define RAPIDJSON_ALLOCATORS_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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) { return std::malloc(size); }
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; 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)
|
||||
{
|
||||
if (!baseAllocator_)
|
||||
ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
|
||||
AddChunk(chunk_capacity_);
|
||||
}
|
||||
|
||||
//! 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();
|
||||
delete ownBaseAllocator_;
|
||||
}
|
||||
|
||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
void Clear() {
|
||||
while(chunkHead_ != 0 && chunkHead_ != userBuffer_) {
|
||||
ChunkHeader* next = chunkHead_->next;
|
||||
baseAllocator_->Free(chunkHead_);
|
||||
chunkHead_ = next;
|
||||
}
|
||||
}
|
||||
|
||||
//! 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) {
|
||||
size = RAPIDJSON_ALIGN(size);
|
||||
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
||||
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
|
||||
|
||||
void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + 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);
|
||||
|
||||
// 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 == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
|
||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||
increment = RAPIDJSON_ALIGN(increment);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
chunkHead_->size += increment;
|
||||
return originalPtr;
|
||||
}
|
||||
}
|
||||
|
||||
// Realloc process: allocate and copy memory, do not free original buffer.
|
||||
void* newBuffer = Malloc(newSize);
|
||||
RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
|
||||
return std::memcpy(newBuffer, originalPtr, originalSize);
|
||||
}
|
||||
|
||||
//! 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.
|
||||
*/
|
||||
void AddChunk(size_t capacity) {
|
||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
|
||||
chunk->capacity = capacity;
|
||||
chunk->size = 0;
|
||||
chunk->next = chunkHead_;
|
||||
chunkHead_ = chunk;
|
||||
}
|
||||
|
||||
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.
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ENCODINGS_H_
|
1863
external/rapidjson/document.h
vendored
Normal file
1863
external/rapidjson/document.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
290
external/rapidjson/encodedstream.h
vendored
Normal file
290
external/rapidjson/encodedstream.h
vendored
Normal file
@ -0,0 +1,290 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
|
||||
#define RAPIDJSON_ENCODEDSTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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_;
|
||||
};
|
||||
|
||||
//! Output byte stream wrapper with 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, 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); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
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) {
|
||||
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 = (const unsigned char *)is_->Peek4();
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
unsigned bom = 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.
|
||||
switch (type_) {
|
||||
case kUTF8:
|
||||
// Do nothing
|
||||
break;
|
||||
case kUTF16LE:
|
||||
case kUTF16BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||
break;
|
||||
case kUTF32LE:
|
||||
case kUTF32BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||
break;
|
||||
default:
|
||||
RAPIDJSON_ASSERT(false); // Invalid type
|
||||
}
|
||||
}
|
||||
|
||||
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 InputByteStream 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) {
|
||||
// RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
|
||||
switch (type_) {
|
||||
case kUTF16LE:
|
||||
case kUTF16BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||
break;
|
||||
case kUTF32LE:
|
||||
case kUTF32BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||
break;
|
||||
case kUTF8:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
RAPIDJSON_ASSERT(false); // Invalid UTFType
|
||||
}
|
||||
|
||||
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); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
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
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
630
external/rapidjson/encodings.h
vendored
Normal file
630
external/rapidjson/encodings.h
vendored
Normal file
@ -0,0 +1,630 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef 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++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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 InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
|
||||
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c = is.Take();
|
||||
if (!(c & 0x80)) {
|
||||
*codepoint = (unsigned char)c;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char type = GetRange((unsigned char)c);
|
||||
*codepoint = (0xFF >> type) & (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((unsigned char)c) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c;
|
||||
COPY();
|
||||
if (!(c & 0x80))
|
||||
return true;
|
||||
|
||||
bool result = true;
|
||||
switch (GetRange((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);
|
||||
Ch c = Take(is);
|
||||
if ((unsigned char)c != 0xEFu) return c;
|
||||
c = is.Take();
|
||||
if ((unsigned char)c != 0xBBu) return c;
|
||||
c = is.Take();
|
||||
if ((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 is.Take();
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xEFu); os.Put(0xBBu); os.Put(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 InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
||||
Ch c = is.Take();
|
||||
if (c < 0xD800 || c > 0xDFFF) {
|
||||
*codepoint = c;
|
||||
return true;
|
||||
}
|
||||
else if (c <= 0xDBFF) {
|
||||
*codepoint = (c & 0x3FF) << 10;
|
||||
c = is.Take();
|
||||
*codepoint |= (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);
|
||||
Ch c;
|
||||
os.Put(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 (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((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 (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFEu); os.Put(0xFFu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(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 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 (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 24;
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((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 (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 24;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 24) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(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 InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
unsigned char c = static_cast<unsigned char>(is.Take());
|
||||
*codepoint = c;
|
||||
return c <= 0X7F;
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
unsigned char c = is.Take();
|
||||
os.Put(c);
|
||||
return c <= 0x7F;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
Ch c = Take(is);
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
return 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 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;
|
||||
}
|
||||
|
||||
//! 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.
|
||||
}
|
||||
};
|
||||
|
||||
//! 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 Validate(InputStream& is, OutputStream& os) {
|
||||
return Encoding::Validate(is, os); // source/target encoding are the same
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#if defined(__GNUC__) || defined(_MSV_VER)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ENCODINGS_H_
|
71
external/rapidjson/error/en.h
vendored
Normal file
71
external/rapidjson/error/en.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_ERROR_EN_H__
|
||||
#define RAPIDJSON_ERROR_EN_H__
|
||||
|
||||
#include "error.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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 follow 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.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ERROR_EN_H__
|
150
external/rapidjson/error/error.h
vendored
Normal file
150
external/rapidjson/error/error.h
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H__
|
||||
#define RAPIDJSON_ERROR_ERROR_H__
|
||||
|
||||
/*! \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
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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 {
|
||||
|
||||
//! 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);
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H__
|
94
external/rapidjson/filereadstream.h
vendored
Normal file
94
external/rapidjson/filereadstream.h
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_FILEREADSTREAM_H_
|
||||
#define RAPIDJSON_FILEREADSTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE* fp_;
|
||||
Ch *buffer_;
|
||||
size_t bufferSize_;
|
||||
Ch *bufferLast_;
|
||||
Ch *current_;
|
||||
size_t readCount_;
|
||||
size_t count_; //!< Number of characters read
|
||||
bool eof_;
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
73
external/rapidjson/filestream.h
vendored
Normal file
73
external/rapidjson/filestream.h
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_FILESTREAM_H_
|
||||
#define RAPIDJSON_FILESTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! (Depreciated) Wrapper of C file stream for input or output.
|
||||
/*!
|
||||
This simple wrapper does not check the validity of the stream.
|
||||
\note implements Stream concept
|
||||
\note deprecated: This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead.
|
||||
*/
|
||||
class FileStream {
|
||||
public:
|
||||
typedef char Ch; //!< Character type. Only support char.
|
||||
|
||||
FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); }
|
||||
char Peek() const { return current_; }
|
||||
char Take() { char c = current_; Read(); return c; }
|
||||
size_t Tell() const { return count_; }
|
||||
void Put(char c) { fputc(c, fp_); }
|
||||
void Flush() { fflush(fp_); }
|
||||
|
||||
// Not implemented
|
||||
char* PutBegin() { return 0; }
|
||||
size_t PutEnd(char*) { return 0; }
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
FileStream(const FileStream&);
|
||||
FileStream& operator=(const FileStream&);
|
||||
|
||||
void Read() {
|
||||
RAPIDJSON_ASSERT(fp_ != 0);
|
||||
int c = fgetc(fp_);
|
||||
if (c != EOF) {
|
||||
current_ = (char)c;
|
||||
count_++;
|
||||
}
|
||||
else if (current_ != '\0')
|
||||
current_ = '\0';
|
||||
}
|
||||
|
||||
FILE* fp_;
|
||||
char current_;
|
||||
size_t count_;
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
97
external/rapidjson/filewritestream.h
vendored
Normal file
97
external/rapidjson/filewritestream.h
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
|
||||
#define RAPIDJSON_FILEWRITESTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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(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_) {
|
||||
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
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&);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
418
external/rapidjson/internal/dtoa.h
vendored
Normal file
418
external/rapidjson/internal/dtoa.h
vendored
Normal file
@ -0,0 +1,418 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// This is 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_
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#if defined(_M_AMD64)
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "itoa.h" // GetDigitsLut()
|
||||
|
||||
namespace rapidjson {
|
||||
namespace internal {
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
struct DiyFp {
|
||||
DiyFp() {}
|
||||
|
||||
DiyFp(uint64_t f, int e) : f(f), e(e) {}
|
||||
|
||||
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__)
|
||||
unsigned __int128 p = static_cast<unsigned __int128>(f) * static_cast<unsigned __int128>(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__)
|
||||
int s = __builtin_clzll(f);
|
||||
return DiyFp(f << s, e - s);
|
||||
#else
|
||||
DiyFp res = *this;
|
||||
while (!(res.f & kDpHiddenBit)) {
|
||||
res.f <<= 1;
|
||||
res.e--;
|
||||
}
|
||||
res.f <<= (kDiySignificandSize - kDpSignificandSize - 1);
|
||||
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
DiyFp NormalizeBoundary() const {
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, f);
|
||||
return DiyFp (f << (63 - index), e - (63 - index));
|
||||
#else
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const int kDiySignificandSize = 64;
|
||||
static const int kDpSignificandSize = 52;
|
||||
static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
|
||||
static const int kDpMinExponent = -kDpExponentBias;
|
||||
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 GetCachedPower(int e, int* K) {
|
||||
// 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
|
||||
};
|
||||
|
||||
//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 (k != dk)
|
||||
k++;
|
||||
|
||||
unsigned index = static_cast<unsigned>((k >> 3) + 1);
|
||||
*K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
|
||||
|
||||
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
||||
}
|
||||
|
||||
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;
|
||||
if (n < 1000000000) return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
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);
|
||||
int kappa = CountDecimalDigit32(p1);
|
||||
*len = 0;
|
||||
|
||||
while (kappa > 0) {
|
||||
uint32_t d;
|
||||
switch (kappa) {
|
||||
case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
|
||||
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 defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
__builtin_unreachable();
|
||||
#else
|
||||
d = 0;
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
|
||||
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) {
|
||||
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
||||
|
||||
if (length <= kk && 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], length - kk);
|
||||
buffer[kk] = '.';
|
||||
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], length);
|
||||
buffer[0] = '0';
|
||||
buffer[1] = '.';
|
||||
for (int i = 2; i < offset; i++)
|
||||
buffer[i] = '0';
|
||||
return &buffer[length + offset];
|
||||
}
|
||||
else if (length == 1) {
|
||||
// 1e30
|
||||
buffer[1] = 'e';
|
||||
return WriteExponent(kk - 1, &buffer[2]);
|
||||
}
|
||||
else {
|
||||
// 1234e30 -> 1.234e33
|
||||
std::memmove(&buffer[2], &buffer[1], length - 1);
|
||||
buffer[1] = '.';
|
||||
buffer[length + 1] = 'e';
|
||||
return WriteExponent(kk - 1, &buffer[0 + length + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
inline char* dtoa(double value, char* buffer) {
|
||||
if (value == 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_DTOA_
|
306
external/rapidjson/internal/itoa.h
vendored
Normal file
306
external/rapidjson/internal/itoa.h
vendored
Normal file
@ -0,0 +1,306 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_ITOA_
|
||||
#define RAPIDJSON_ITOA_
|
||||
|
||||
namespace rapidjson {
|
||||
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) {
|
||||
if (value < 0) {
|
||||
*buffer++ = '-';
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return u32toa(static_cast<uint32_t>(value), 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) {
|
||||
if (value < 0) {
|
||||
*buffer++ = '-';
|
||||
value = -value;
|
||||
}
|
||||
|
||||
return u64toa(static_cast<uint64_t>(value), buffer);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ITOA_
|
189
external/rapidjson/internal/meta.h
vendored
Normal file
189
external/rapidjson/internal/meta.h
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_INTERNAL_META_H_
|
||||
#define RAPIDJSON_INTERNAL_META_H_
|
||||
|
||||
#ifndef RAPIDJSON_RAPIDJSON_H_
|
||||
#error <rapidjson.h> not yet included. Do not include this file directly.
|
||||
#endif
|
||||
|
||||
#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
|
||||
namespace rapidjson {
|
||||
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::internal::RemoveSfinaeTag \
|
||||
< ::rapidjson::internal::SfinaeTag&(*) type>::Type
|
||||
|
||||
#define RAPIDJSON_ENABLEIF(cond) \
|
||||
typename ::rapidjson::internal::EnableIf \
|
||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||
|
||||
#define RAPIDJSON_DISABLEIF(cond) \
|
||||
typename ::rapidjson::internal::DisableIf \
|
||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||
|
||||
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
||||
typename ::rapidjson::internal::EnableIf \
|
||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||
|
||||
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
||||
typename ::rapidjson::internal::DisableIf \
|
||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
//@endcond
|
||||
|
||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_META_H_
|
59
external/rapidjson/internal/pow10.h
vendored
Normal file
59
external/rapidjson/internal/pow10.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_POW10_
|
||||
#define RAPIDJSON_POW10_
|
||||
|
||||
namespace rapidjson {
|
||||
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
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_POW10_
|
137
external/rapidjson/internal/stack.h
vendored
Normal file
137
external/rapidjson/internal/stack.h
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_INTERNAL_STACK_H_
|
||||
#define RAPIDJSON_INTERNAL_STACK_H_
|
||||
|
||||
namespace rapidjson {
|
||||
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) {
|
||||
RAPIDJSON_ASSERT(stackCapacity > 0);
|
||||
if (!allocator_)
|
||||
ownAllocator = allocator_ = new Allocator();
|
||||
}
|
||||
|
||||
~Stack() {
|
||||
Allocator::Free(stack_);
|
||||
delete ownAllocator; // Only delete if it is owned by the stack
|
||||
}
|
||||
|
||||
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 T* Push(size_t count = 1) {
|
||||
// Expand the stack if needed
|
||||
if (stackTop_ + sizeof(T) * count >= stackEnd_)
|
||||
Expand<T>(count);
|
||||
|
||||
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>
|
||||
T* Bottom() { return (T*)stack_; }
|
||||
|
||||
Allocator& GetAllocator() { 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)
|
||||
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_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity);
|
||||
stackTop_ = stack_ + size;
|
||||
stackEnd_ = stack_ + newCapacity;
|
||||
}
|
||||
|
||||
// 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
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_STACK_H_
|
43
external/rapidjson/internal/strfunc.h
vendored
Normal file
43
external/rapidjson/internal/strfunc.h
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
|
||||
namespace rapidjson {
|
||||
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) {
|
||||
const Ch* p = s;
|
||||
while (*p) ++p;
|
||||
return SizeType(p - s);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
|
76
external/rapidjson/memorybuffer.h
vendored
Normal file
76
external/rapidjson/memorybuffer.h
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_MEMORYBUFFER_H_
|
||||
#define RAPIDJSON_MEMORYBUFFER_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/stack.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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));
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_MEMORYBUFFER_H_
|
67
external/rapidjson/memorystream.h
vendored
Normal file
67
external/rapidjson/memorystream.h
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_MEMORYSTREAM_H_
|
||||
#define RAPIDJSON_MEMORYSTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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 *src_; }
|
||||
Ch Take() { return (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.
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_MEMORYBUFFER_H_
|
306
external/rapidjson/msinttypes/inttypes.h
vendored
Normal file
306
external/rapidjson/msinttypes/inttypes.h
vendored
Normal file
@ -0,0 +1,306 @@
|
||||
// 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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"
|
||||
|
||||
// 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_INTTYPES_H_ ]
|
296
external/rapidjson/msinttypes/stdint.h
vendored
Normal file
296
external/rapidjson/msinttypes/stdint.h
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
// 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// 7.18.1 Integer types
|
||||
|
||||
// 7.18.1.1 Exact-width integer types
|
||||
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
// 7.18.1.2 Minimum-width integer types
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
// 7.18.1.3 Fastest minimum-width integer types
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
// 7.18.1.4 Integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else // _WIN64 ][
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.1.5 Greatest-width integer types
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
|
||||
// 7.18.2 Limits of specified-width integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||
|
||||
// 7.18.2.1 Limits of exact-width integer types
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
// 7.18.2.2 Limits of minimum-width integer types
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.2.5 Limits of greatest-width integer types
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
// 7.18.3 Limits of other integer types
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX // [
|
||||
# ifdef _WIN64 // [
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else // _WIN64 ][
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif // _WIN64 ]
|
||||
#endif // SIZE_MAX ]
|
||||
|
||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||
#ifndef WCHAR_MIN // [
|
||||
# define WCHAR_MIN 0
|
||||
#endif // WCHAR_MIN ]
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif // WCHAR_MAX ]
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif // __STDC_LIMIT_MACROS ]
|
||||
|
||||
|
||||
// 7.18.4 Limits of other integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||
|
||||
// 7.18.4.1 Macros for minimum-width integer constants
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
// 7.18.4.2 Macros for greatest-width integer constants
|
||||
// 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_ ]
|
205
external/rapidjson/prettywriter.h
vendored
Normal file
205
external/rapidjson/prettywriter.h
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_PRETTYWRITER_H_
|
||||
#define RAPIDJSON_PRETTYWRITER_H_
|
||||
|
||||
#include "writer.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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>
|
||||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> {
|
||||
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.
|
||||
*/
|
||||
PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||
Base(os, 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;
|
||||
}
|
||||
|
||||
/*! @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 String(const Ch* str, SizeType length, bool copy = false) {
|
||||
(void)copy;
|
||||
PrettyPrefix(kStringType);
|
||||
return Base::WriteString(str, length);
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
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();
|
||||
}
|
||||
if (!Base::WriteEndObject())
|
||||
return false;
|
||||
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) {
|
||||
Base::os_->Put('\n');
|
||||
WriteIndent();
|
||||
}
|
||||
if (!Base::WriteEndArray())
|
||||
return false;
|
||||
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)); }
|
||||
|
||||
//@}
|
||||
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
|
||||
Base::os_->Put('\n');
|
||||
}
|
||||
else
|
||||
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_, indentChar_, count);
|
||||
}
|
||||
|
||||
Ch indentChar_;
|
||||
unsigned indentCharCount_;
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
PrettyWriter(const PrettyWriter&);
|
||||
PrettyWriter& operator=(const PrettyWriter&);
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
567
external/rapidjson/rapidjson.h
vendored
Normal file
567
external/rapidjson/rapidjson.h
vendored
Normal file
@ -0,0 +1,567 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_RAPIDJSON_H_
|
||||
#define RAPIDJSON_RAPIDJSON_H_
|
||||
|
||||
// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
|
||||
// Version 0.1
|
||||
|
||||
/*!\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_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
|
||||
#ifdef _MSC_VER
|
||||
#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
|
||||
#ifdef _MSC_VER
|
||||
#define RAPIDJSON_FORCEINLINE __forceinline
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#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(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(_WIN64)
|
||||
#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. User can customize by defining the RAPIDJSON_ALIGN function macro.,
|
||||
*/
|
||||
#ifndef RAPIDJSON_ALIGN
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
|
||||
#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_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
|
||||
namespace rapidjson {
|
||||
//! 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;
|
||||
} // namespace rapidjson
|
||||
#endif
|
||||
|
||||
// always import std::size_t to rapidjson namespace
|
||||
namespace rapidjson {
|
||||
using std::size_t;
|
||||
} // namespace rapidjson
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
namespace rapidjson {
|
||||
|
||||
template <bool x> struct STATIC_ASSERTION_FAILURE;
|
||||
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
||||
template<int x> struct StaticAssertTest {};
|
||||
} // namespace rapidjson
|
||||
|
||||
#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
|
||||
//!@endcond
|
||||
|
||||
/*! \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::StaticAssertTest<\
|
||||
sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
|
||||
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||
#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))
|
||||
|
||||
// token stringification
|
||||
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
|
||||
#define RAPIDJSON_DO_STRINGIFY(x) #x
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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__)
|
||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references)
|
||||
#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
|
||||
|
||||
//!@endcond
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allocators and Encodings
|
||||
|
||||
#include "allocators.h"
|
||||
#include "encodings.h"
|
||||
|
||||
//! main RapidJSON namespace
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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 };
|
||||
};
|
||||
|
||||
//! Put N copies of a character to a stream.
|
||||
template<typename Stream, typename Ch>
|
||||
inline void PutN(Stream& stream, Ch c, size_t n) {
|
||||
for (size_t i = 0; i < n; i++)
|
||||
stream.Put(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;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Type
|
||||
|
||||
//! 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
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
1369
external/rapidjson/reader.h
vendored
Normal file
1369
external/rapidjson/reader.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
79
external/rapidjson/stringbuffer.h
vendored
Normal file
79
external/rapidjson/stringbuffer.h
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_STRINGBUFFER_H_
|
||||
#define RAPIDJSON_STRINGBUFFER_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/stack.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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>
|
||||
struct GenericStringBuffer {
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
GenericStringBuffer(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() {
|
||||
// Push and pop a null terminator. This is safe.
|
||||
*stack_.template Push<Ch>() = '\0';
|
||||
stack_.ShrinkToFit();
|
||||
stack_.template Pop<Ch>(1);
|
||||
}
|
||||
Ch* Push(size_t count) { return stack_.template Push<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_;
|
||||
};
|
||||
|
||||
//! String buffer with UTF8 encoding
|
||||
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
||||
|
||||
//! 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));
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_STRINGBUFFER_H_
|
389
external/rapidjson/writer.h
vendored
Normal file
389
external/rapidjson/writer.h
vendored
Normal file
@ -0,0 +1,389 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_WRITER_H_
|
||||
#define RAPIDJSON_WRITER_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/stack.h"
|
||||
#include "internal/strfunc.h"
|
||||
#include "internal/dtoa.h"
|
||||
#include "internal/itoa.h"
|
||||
#include "stringbuffer.h"
|
||||
#include <new> // placement new
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! 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>
|
||||
class Writer {
|
||||
public:
|
||||
typedef typename SourceEncoding::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.
|
||||
*/
|
||||
Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {}
|
||||
|
||||
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), 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();
|
||||
}
|
||||
|
||||
/*!@name Implementation of Handler
|
||||
\see Handler
|
||||
*/
|
||||
//@{
|
||||
|
||||
bool Null() { Prefix(kNullType); return WriteNull(); }
|
||||
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); }
|
||||
bool Int(int i) { Prefix(kNumberType); return WriteInt(i); }
|
||||
bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); }
|
||||
bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); }
|
||||
bool Uint64(uint64_t u64) { Prefix(kNumberType); return 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 WriteDouble(d); }
|
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||
(void)copy;
|
||||
Prefix(kStringType);
|
||||
return WriteString(str, length);
|
||||
}
|
||||
|
||||
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);
|
||||
bool ret = WriteEndObject();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
bool ret = WriteEndArray();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
//@}
|
||||
|
||||
/*! @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)); }
|
||||
|
||||
//@}
|
||||
|
||||
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() {
|
||||
os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true;
|
||||
}
|
||||
|
||||
bool WriteBool(bool b) {
|
||||
if (b) {
|
||||
os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e');
|
||||
}
|
||||
else {
|
||||
os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteInt(int i) {
|
||||
char buffer[11];
|
||||
const char* end = internal::i32toa(i, buffer);
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteUint(unsigned u) {
|
||||
char buffer[10];
|
||||
const char* end = internal::u32toa(u, buffer);
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteInt64(int64_t i64) {
|
||||
char buffer[21];
|
||||
const char* end = internal::i64toa(i64, buffer);
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteUint64(uint64_t u64) {
|
||||
char buffer[20];
|
||||
char* end = internal::u64toa(u64, buffer);
|
||||
for (char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteDouble(double d) {
|
||||
char buffer[25];
|
||||
char* end = internal::dtoa(d, buffer);
|
||||
for (char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteString(const Ch* str, SizeType length) {
|
||||
static const char 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
|
||||
};
|
||||
|
||||
os_->Put('\"');
|
||||
GenericStringStream<SourceEncoding> is(str);
|
||||
while (is.Tell() < length) {
|
||||
const Ch c = is.Peek();
|
||||
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) {
|
||||
// Unicode escaping
|
||||
unsigned codepoint;
|
||||
if (!SourceEncoding::Decode(is, &codepoint))
|
||||
return false;
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
|
||||
os_->Put(hexDigits[(codepoint >> 12) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 8) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 4) & 15]);
|
||||
os_->Put(hexDigits[(codepoint ) & 15]);
|
||||
}
|
||||
else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) {
|
||||
// Surrogate pair
|
||||
unsigned s = codepoint - 0x010000;
|
||||
unsigned lead = (s >> 10) + 0xD800;
|
||||
unsigned trail = (s & 0x3FF) + 0xDC00;
|
||||
os_->Put(hexDigits[(lead >> 12) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 8) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 4) & 15]);
|
||||
os_->Put(hexDigits[(lead ) & 15]);
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
os_->Put(hexDigits[(trail >> 12) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 8) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 4) & 15]);
|
||||
os_->Put(hexDigits[(trail ) & 15]);
|
||||
}
|
||||
else
|
||||
return false; // invalid code point
|
||||
}
|
||||
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
|
||||
is.Take();
|
||||
os_->Put('\\');
|
||||
os_->Put(escape[(unsigned char)c]);
|
||||
if (escape[(unsigned char)c] == 'u') {
|
||||
os_->Put('0');
|
||||
os_->Put('0');
|
||||
os_->Put(hexDigits[(unsigned char)c >> 4]);
|
||||
os_->Put(hexDigits[(unsigned char)c & 0xF]);
|
||||
}
|
||||
}
|
||||
else
|
||||
Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_);
|
||||
}
|
||||
os_->Put('\"');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteStartObject() { os_->Put('{'); return true; }
|
||||
bool WriteEndObject() { os_->Put('}'); return true; }
|
||||
bool WriteStartArray() { os_->Put('['); return true; }
|
||||
bool WriteEndArray() { os_->Put(']'); return true; }
|
||||
|
||||
void Prefix(Type type) {
|
||||
(void)type;
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream* os_;
|
||||
internal::Stack<StackAllocator> level_stack_;
|
||||
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(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(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(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(20 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
||||
char *buffer = os_->Push(25);
|
||||
char* end = internal::dtoa(d, buffer);
|
||||
os_->Pop(25 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
201
external/unbound/CMakeLists.txt
vendored
Normal file
201
external/unbound/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
|
||||
project(unbound C)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Threads)
|
||||
|
||||
include(configure_checks.cmake)
|
||||
|
||||
if (WIN32)
|
||||
set(USE_MINI_EVENT 1)
|
||||
set(USE_WINSOCK 1)
|
||||
else ()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBEVENT2 REQUIRED libevent)
|
||||
endif ()
|
||||
|
||||
set(RETSIGTYPE void)
|
||||
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
option(USE_ECDSA "Use ECDSA algorithms" ON)
|
||||
option(USE_SHA2 "Enable SHA2 support" ON)
|
||||
set(ENABLE_DNSTAP 0)
|
||||
set(HAVE_SSL 1)
|
||||
if (CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_USE_WIN32_THREADS_INIT)
|
||||
set(HAVE_PTHREAD 1)
|
||||
else ()
|
||||
set(HAVE_PTHREAD 0)
|
||||
endif ()
|
||||
if (CMAKE_USE_WIN32_THREADS_INIT)
|
||||
set(HAVE_WINDOWS_THREADS 1)
|
||||
else ()
|
||||
set(HAVE_WINDOWS_THREADS 0)
|
||||
endif ()
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/config.h")
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/dnstap/dnstap_config.h.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/dnstap/dnstap_config.h")
|
||||
|
||||
set(common_src
|
||||
services/cache/dns.c
|
||||
services/cache/infra.c
|
||||
services/cache/rrset.c
|
||||
util/data/dname.c
|
||||
util/data/msgencode.c
|
||||
util/data/msgparse.c
|
||||
util/data/msgreply.c
|
||||
util/data/packed_rrset.c
|
||||
iterator/iterator.c
|
||||
iterator/iter_delegpt.c
|
||||
iterator/iter_donotq.c
|
||||
iterator/iter_fwd.c
|
||||
iterator/iter_hints.c
|
||||
iterator/iter_priv.c
|
||||
iterator/iter_resptype.c
|
||||
iterator/iter_scrub.c
|
||||
iterator/iter_utils.c
|
||||
services/listen_dnsport.c
|
||||
services/localzone.c
|
||||
services/mesh.c
|
||||
services/modstack.c
|
||||
services/outbound_list.c
|
||||
services/outside_network.c
|
||||
util/alloc.c
|
||||
util/config_file.c
|
||||
util/configlexer.c
|
||||
util/configparser.c
|
||||
util/fptr_wlist.c
|
||||
util/locks.c
|
||||
util/log.c
|
||||
util/mini_event.c
|
||||
util/module.c
|
||||
util/netevent.c
|
||||
util/net_help.c
|
||||
util/random.c
|
||||
util/rbtree.c
|
||||
util/regional.c
|
||||
util/rtt.c
|
||||
util/storage/dnstree.c
|
||||
util/storage/lookup3.c
|
||||
util/storage/lruhash.c
|
||||
util/storage/slabhash.c
|
||||
util/timehist.c
|
||||
util/tube.c
|
||||
util/winsock_event.c
|
||||
validator/autotrust.c
|
||||
validator/val_anchor.c
|
||||
validator/validator.c
|
||||
validator/val_kcache.c
|
||||
validator/val_kentry.c
|
||||
validator/val_neg.c
|
||||
validator/val_nsec3.c
|
||||
validator/val_nsec.c
|
||||
validator/val_secalgo.c
|
||||
validator/val_sigcrypt.c
|
||||
validator/val_utils.c
|
||||
dns64/dns64.c
|
||||
|
||||
#$(CHECKLOCK_SRC)
|
||||
testcode/checklocks.c)
|
||||
|
||||
set(compat_src)
|
||||
|
||||
foreach (symbol IN ITEMS ctime_r gmtime_r inet_aton inet_ntop inet_pton malloc memcmp memmove snprintf strlcat strlcpy strptime explicit_bzero arc4random arc4random_uniform sha512)
|
||||
string(TOUPPER "${symbol}" upper_sym)
|
||||
if (NOT HAVE_${upper_sym})
|
||||
list(APPEND compat_src
|
||||
compat/${symbol}.c)
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if (NOT HAVE_ARC4RANDOM)
|
||||
list(APPEND compat_src
|
||||
compat/arc4_lock.c)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
list(APPEND compat_src
|
||||
compat/getentropy_linux.c)
|
||||
elseif (APPLE)
|
||||
list(APPEND compat_src
|
||||
compat/getentropy_osx.c)
|
||||
#elseif (SunOS)
|
||||
# list(APPEND compat_src
|
||||
# compat/getentropy_solaris.c)
|
||||
elseif (WIN32)
|
||||
list(APPEND compat_src
|
||||
compat/getentropy_win.c)
|
||||
endif ()
|
||||
|
||||
if (NOT HAVE_GETADDRINFO)
|
||||
list(APPEND compat_src
|
||||
compat/fake-rfc2553.c)
|
||||
endif ()
|
||||
|
||||
set(sldns_src
|
||||
ldns/keyraw.c
|
||||
ldns/sbuffer.c
|
||||
ldns/wire2str.c
|
||||
ldns/parse.c
|
||||
ldns/parseutil.c
|
||||
ldns/rrdef.c
|
||||
ldns/str2wire.c)
|
||||
|
||||
set(libunbound_src
|
||||
libunbound/context.c
|
||||
libunbound/libunbound.c
|
||||
libunbound/libworker.c)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR})
|
||||
if (LIBEVENT2_FOUND)
|
||||
include_directories(SYSTEM ${LIBEVENT2_INCLUDE_DIRS})
|
||||
link_directories(${LIBEVENT2_LIBRARY_DIRS})
|
||||
endif ()
|
||||
add_library(unbound
|
||||
${common_src}
|
||||
${sldns_src}
|
||||
${compat_src}
|
||||
${libunbound_src})
|
||||
target_link_libraries(unbound
|
||||
LINK_PRIVATE
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
if (LIBEVENT2_FOUND)
|
||||
target_link_libraries(unbound
|
||||
LINK_PRIVATE
|
||||
${LIBEVENT2_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(unbound
|
||||
LINK_PRIVATE
|
||||
iphlpapi
|
||||
ws2_32)
|
||||
endif ()
|
||||
|
||||
# XXX: Hack for static builds.
|
||||
set(LIBEVENT2_LIBDIR
|
||||
"${LIBEVENT2_LIBDIR}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
if (MINGW)
|
||||
# There is no variable for this (probably due to the fact that the pthread
|
||||
# library is implicit with a link in msys).
|
||||
find_library(win32pthread
|
||||
NAMES libwinpthread-1.dll)
|
||||
foreach (input IN LISTS win32pthread OPENSSL_LIBRARIES)
|
||||
# Copy shared libraries into the build tree so that no PATH manipulation is
|
||||
# necessary.
|
||||
get_filename_component(name "${input}" NAME)
|
||||
configure_file(
|
||||
"${input}"
|
||||
"${CMAKE_BINARY_DIR}/bin/${name}"
|
||||
COPYONLY)
|
||||
endforeach ()
|
||||
endif ()
|
4
external/unbound/Makefile.in
vendored
4
external/unbound/Makefile.in
vendored
@ -80,7 +80,7 @@ LINTFLAGS+="-Dsigset_t=long"
|
||||
# FreeBSD
|
||||
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list"
|
||||
|
||||
INSTALL=$(srcdir)/install-sh
|
||||
INSTALL=$(SHELL) $(srcdir)/install-sh
|
||||
|
||||
#pythonmod.c is not here, it is mentioned by itself in its own rules,
|
||||
#makedepend fails on missing interface.h otherwise.
|
||||
@ -397,7 +397,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i un
|
||||
|
||||
# Pyunbound python unbound wrapper
|
||||
_unbound.la: libunbound_wrap.lo libunbound.la
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound
|
||||
|
||||
util/config_file.c: util/configparser.h
|
||||
util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
|
||||
|
4
external/unbound/compat/arc4_lock.c
vendored
4
external/unbound/compat/arc4_lock.c
vendored
@ -53,8 +53,10 @@ static int arc4lockinit = 0;
|
||||
|
||||
void _ARC4_LOCK(void)
|
||||
{
|
||||
if(!arc4lockinit)
|
||||
if(!arc4lockinit) {
|
||||
arc4lockinit = 1;
|
||||
lock_quick_init(&arc4lock);
|
||||
}
|
||||
lock_quick_lock(&arc4lock);
|
||||
}
|
||||
|
||||
|
11
external/unbound/compat/getentropy_linux.c
vendored
11
external/unbound/compat/getentropy_linux.c
vendored
@ -48,6 +48,7 @@
|
||||
#include <time.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sysctl.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
@ -77,7 +78,7 @@ extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
#ifdef CTL_MAXNAME
|
||||
#ifdef SYS__sysctl
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
@ -102,7 +103,7 @@ getentropy(void *buf, size_t len)
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
|
||||
#ifdef CTL_MAXNAME
|
||||
#ifdef SYS__sysctl
|
||||
/*
|
||||
* Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
|
||||
* sysctl is a failsafe API, so it guarantees a result. This
|
||||
@ -124,7 +125,7 @@ getentropy(void *buf, size_t len)
|
||||
ret = getentropy_sysctl(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
#endif /* CTL_MAXNAME */
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
/*
|
||||
* Entropy collection via /dev/urandom and sysctl have failed.
|
||||
@ -235,7 +236,7 @@ nodevrandom:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CTL_MAXNAME
|
||||
#ifdef SYS__sysctl
|
||||
static int
|
||||
getentropy_sysctl(void *buf, size_t len)
|
||||
{
|
||||
@ -265,7 +266,7 @@ sysctlfailed:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
#endif /* CTL_MAXNAME */
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
static int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
|
4
external/unbound/compat/getentropy_win.c
vendored
4
external/unbound/compat/getentropy_win.c
vendored
@ -41,9 +41,9 @@ getentropy(void *buf, size_t len)
|
||||
}
|
||||
|
||||
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT) != 0)
|
||||
CRYPT_VERIFYCONTEXT) == 0)
|
||||
goto fail;
|
||||
if (CryptGenRandom(provider, len, buf) != 0) {
|
||||
if (CryptGenRandom(provider, len, buf) == 0) {
|
||||
CryptReleaseContext(provider, 0);
|
||||
goto fail;
|
||||
}
|
||||
|
10
external/unbound/compat/inet_aton.c
vendored
10
external/unbound/compat/inet_aton.c
vendored
@ -103,7 +103,7 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if (!isdigit(c))
|
||||
if (!isdigit((unsigned char)c))
|
||||
return (0);
|
||||
val = 0; base = 10;
|
||||
if (c == '0') {
|
||||
@ -114,12 +114,12 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
base = 8;
|
||||
}
|
||||
for (;;) {
|
||||
if (isascii(c) && isdigit(c)) {
|
||||
if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
c = *++cp;
|
||||
} else if (base == 16 && isascii(c) && isxdigit(c)) {
|
||||
} else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
|
||||
val = (val << 4) |
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
@ -141,7 +141,7 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && (!isascii(c) || !isspace(c)))
|
||||
if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
|
2
external/unbound/compat/memmove.c
vendored
2
external/unbound/compat/memmove.c
vendored
@ -28,7 +28,7 @@ void *memmove(void *dest, const void *src, size_t n)
|
||||
to[i] = from[i];
|
||||
return dest;
|
||||
}
|
||||
if (from > to && from-to < (int)n) {
|
||||
if (from > to && from-to < (int)n) {
|
||||
/* to overlaps with from */
|
||||
/* <from......> */
|
||||
/* <to........> */
|
||||
|
8
external/unbound/compat/strptime.c
vendored
8
external/unbound/compat/strptime.c
vendored
@ -89,7 +89,7 @@ str2int(const char **buf, int max)
|
||||
{
|
||||
int ret=0, count=0;
|
||||
|
||||
while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
|
||||
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
|
||||
ret = ret*10 + (*buf[0] - '0');
|
||||
(*buf)++;
|
||||
count++;
|
||||
@ -111,11 +111,11 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
/* whitespace, literal or format */
|
||||
if (isspace(c)) { /* whitespace */
|
||||
if (isspace((unsigned char)c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
* input string.
|
||||
**/
|
||||
while (isspace(*s))
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
else if (c == '%') { /* format */
|
||||
@ -221,7 +221,7 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
break;
|
||||
case 'n': /* arbitrary whitespace */
|
||||
case 't':
|
||||
while (isspace(*s))
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
break;
|
||||
case 'p': /* am pm */
|
||||
|
1034
external/unbound/config.h.cmake.in
vendored
Normal file
1034
external/unbound/config.h.cmake.in
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
external/unbound/config.h.in
vendored
3
external/unbound/config.h.in
vendored
@ -1,8 +1,5 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* define if a library can reference the 'main' symbol */
|
||||
#undef CAN_REFERENCE_MAIN
|
||||
|
||||
/* Directory to chroot to */
|
||||
#undef CHROOT_DIR
|
||||
|
||||
|
1476
external/unbound/configure
vendored
1476
external/unbound/configure
vendored
File diff suppressed because it is too large
Load Diff
49
external/unbound/configure.ac
vendored
49
external/unbound/configure.ac
vendored
@ -9,16 +9,16 @@ sinclude(dnstap/dnstap.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[4])
|
||||
m4_define([VERSION_MICRO],[23])
|
||||
m4_define([VERSION_MINOR],[5])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=4
|
||||
LIBUNBOUND_CURRENT=5
|
||||
LIBUNBOUND_REVISION=3
|
||||
LIBUNBOUND_AGE=2
|
||||
LIBUNBOUND_AGE=3
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@ -56,7 +56,8 @@ LIBUNBOUND_AGE=2
|
||||
# 1.4.20 had 4:0:2 # adds libunbound.ttl # but shipped 3:5:1
|
||||
# 1.4.21 had 4:1:2
|
||||
# 1.4.22 had 4:1:2
|
||||
# 1.4.23 had 4:3:2
|
||||
# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr
|
||||
# 1.5.1 had 5:4:3
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -1022,39 +1023,6 @@ if test "$USE_NSS" = "no"; then
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
;;
|
||||
esac
|
||||
# generate libtool to test if linking main
|
||||
# from a dynamic library works.
|
||||
LT_OUTPUT
|
||||
AC_MSG_CHECKING([if dynamic lib can refer to main])
|
||||
cat >tmp.$$.def <<EOF
|
||||
myfunc
|
||||
EOF
|
||||
cat >tmp.$$.c <<EOF
|
||||
int myfunc(void);
|
||||
extern int main(int, char *argv[]);
|
||||
int myfunc(void)
|
||||
{
|
||||
return ((int)main) + 1;
|
||||
}
|
||||
EOF
|
||||
mylibtool=./libtool
|
||||
mylibdir=/usr/local/lib
|
||||
myok=yes
|
||||
$mylibtool --quiet --tag=CC --mode=compile $CC $CFLAGS -o tmp.$$.lo -c tmp.$$.c >/dev/null 2>&1
|
||||
if test $? = 0; then myok=yes; else myok=no; fi
|
||||
if test "$myok" = "yes"; then
|
||||
$mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1
|
||||
if test $? = 0; then myok=yes; else myok=no; fi
|
||||
fi
|
||||
if test "$myok" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(CAN_REFERENCE_MAIN, [1], [define if a library can reference the 'main' symbol])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
$mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo
|
||||
rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o
|
||||
|
||||
fi
|
||||
])
|
||||
fi
|
||||
@ -1365,6 +1333,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
])
|
||||
|
||||
dnl if we build from source tree, the man pages need @date@ and @version@
|
||||
dnl if this is a distro tarball, that was already done by makedist.sh
|
||||
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
|
||||
AC_SUBST(date, [`date +'%b %e, %Y'`])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
218
external/unbound/configure_checks.cmake
vendored
Normal file
218
external/unbound/configure_checks.cmake
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
# Need expat.
|
||||
|
||||
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
check_include_file(endian.h HAVE_ENDIAN_H)
|
||||
check_include_file(dlfcn.h HAVE_DLFCN_H)
|
||||
check_include_file(event.h HAVE_EVENT_H)
|
||||
check_include_file(getopt.h HAVE_GETOPT_H)
|
||||
check_include_file(glob.h HAVE_GLOB_H)
|
||||
check_include_file(grp.h HAVE_GRP_H)
|
||||
check_include_file(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_file(iphlpapi.h HAVE_IPHLPAPI_H)
|
||||
check_include_file(login_cap.h HAVE_LOGIN_CAP_H)
|
||||
check_include_file(memory.h HAVE_MEMORY_H)
|
||||
check_include_file(netdb.h HAVE_NETDB_H)
|
||||
check_include_file(netinet/in.h HAVE_NETINET_IN_H)
|
||||
check_include_file(pwd.h HAVE_PWD_H)
|
||||
check_include_file(stdarg.h HAVE_STDARG_H)
|
||||
check_include_file(stdbool.h HAVE_STDBOOL_H)
|
||||
check_include_file(stdint.h HAVE_STDINT_H)
|
||||
check_include_file(stdlib.h HAVE_STDLIB_H)
|
||||
check_include_file(strings.h HAVE_STRINGS_H)
|
||||
check_include_file(string.h HAVE_STRING_H)
|
||||
check_include_file(sys/param.h HAVE_SYS_PARAM_H)
|
||||
check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H)
|
||||
check_include_file(sys/sha2.h HAVE_SYS_SHA2_H)
|
||||
check_include_file(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_file(sys/stat.h HAVE_SYS_STAT_H)
|
||||
check_include_file(sys/sysctl.h HAVE_SYS_SYSCTL_H)
|
||||
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||
check_include_file(sys/uio.h HAVE_SYS_UIO_H)
|
||||
check_include_file(sys/wait.h HAVE_SYS_WAIT_H)
|
||||
check_include_file(syslog.h HAVE_SYSLOG_H)
|
||||
check_include_file(time.h HAVE_TIME_H)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
check_include_file(vfork.h HAVE_VFORK_H)
|
||||
check_include_file(windows.h HAVE_WINDOWS_H)
|
||||
check_include_file(winsock2.h HAVE_WINSOCK2_H)
|
||||
check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H)
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_REQUIRED_LIBRARIES
|
||||
iphlpapi
|
||||
ws2_32)
|
||||
endif ()
|
||||
|
||||
check_function_exists(arc4random HAVE_ARC4RANDOM)
|
||||
check_function_exists(arc4random_uniform HAVE_ARC4RANDOM_UNIFORM)
|
||||
check_function_exists(chown HAVE_CHOWN)
|
||||
check_function_exists(chroot HAVE_CHROOT)
|
||||
check_function_exists(ctime_r HAVE_CTIME_R)
|
||||
check_function_exists(daemon HAVE_DAEMON)
|
||||
check_function_exists(endprotoent HAVE_ENDPROTOENT)
|
||||
check_function_exists(endservent HAVE_ENDSERVENT)
|
||||
check_function_exists(fnctl HAVE_FNCTL)
|
||||
check_function_exists(fork HAVE_FORK)
|
||||
check_function_exists(fseeko HAVE_FSEEKO)
|
||||
check_function_exists(getentropy HAVE_GETENTROPY)
|
||||
check_function_exists(getpwnam HAVE_GETPWNAM)
|
||||
check_function_exists(getrlimit HAVE_GETRLIMIT)
|
||||
check_function_exists(glob HAVE_GLOB)
|
||||
check_function_exists(gmtime_r HAVE_GMTIME_R)
|
||||
check_function_exists(inet_aton HAVE_INET_ATON)
|
||||
check_function_exists(inet_ntop HAVE_INET_NTOP)
|
||||
check_function_exists(inet_pton HAVE_INET_PTON)
|
||||
check_function_exists(initgroups HAVE_INITGROUPS)
|
||||
check_function_exists(ioctlsocket HAVE_IOCTLSOCKET)
|
||||
check_function_exists(kill HAVE_KILL)
|
||||
check_function_exists(localtime_r HAVE_LOCALTIME_R)
|
||||
check_function_exists(malloc HAVE_MALLOC)
|
||||
check_function_exists(memmove HAVE_MEMMOVE)
|
||||
check_function_exists(random HAVE_RANDOM)
|
||||
check_function_exists(recvmsg HAVE_RECVMSG)
|
||||
check_function_exists(sbrk HAVE_SBRK)
|
||||
check_function_exists(sendmsg HAVE_SENDMSG)
|
||||
check_function_exists(setregid HAVE_SETREGID)
|
||||
check_function_exists(setresgid HAVE_SETRESGID)
|
||||
check_function_exists(setresuid HAVE_SETRESUID)
|
||||
check_function_exists(setreuid HAVE_SETREUID)
|
||||
check_function_exists(setrlimit HAVE_SETRLIMIT)
|
||||
check_function_exists(setsid HAVE_SETSID)
|
||||
check_function_exists(setusercontent HAVE_SETUSERCONTENT)
|
||||
check_function_exists(sigprocmask HAVE_SIGPROCMASK)
|
||||
check_function_exists(sleep HAVE_SLEEP)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
check_function_exists(socketpair HAVE_SOCKETPAIR)
|
||||
check_function_exists(srandom HAVE_SRANDOM)
|
||||
check_function_exists(strftime HAVE_STRFTIME)
|
||||
check_function_exists(strlcat HAVE_STRLCAT)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
check_function_exists(strptime HAVE_STRPTIME)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
check_function_exists(tzset HAVE_TZSET)
|
||||
check_function_exists(usleep HAVE_USLEEP)
|
||||
check_function_exists(writev HAVE_WRITEV)
|
||||
check_function_exists(_beginthreadex HAVE__BEGINTHREADEX)
|
||||
|
||||
set(getaddrinfo_headers)
|
||||
if (HAVE_NETDB_H)
|
||||
list(APPEND getaddrinfo_headers "netdb.h")
|
||||
endif ()
|
||||
if (HAVE_WS2TCPIP_H)
|
||||
list(APPEND getaddrinfo_headers "ws2tcpip.h")
|
||||
endif ()
|
||||
check_symbol_exists(getaddrinfo "${getaddrinfo_headers}" HAVE_GETADDRINFO)
|
||||
|
||||
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
|
||||
|
||||
function (check_type_exists type variable header default)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "${header}")
|
||||
check_type_size("${type}" "${variable}")
|
||||
|
||||
if (NOT HAVE_${type})
|
||||
set("${variable}" "${default}" PARENT_SCOPE)
|
||||
else ()
|
||||
set("${variable}" "FALSE" PARENT_SCOPE)
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "time.h")
|
||||
check_type_size(time_t SIZEOF_TIME_T)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
|
||||
check_type_exists(gid_t gid_t "sys/types.h" int)
|
||||
check_type_exists(in_addr_t in_addr_t "netinet/in.h" uint32_t)
|
||||
check_type_exists(in_port_t in_port_t "netinet/in.h" uint16_t)
|
||||
check_type_exists(int16_t int16_t "sys/types.h" short)
|
||||
check_type_exists(int32_t int32_t "sys/types.h" int)
|
||||
check_type_exists(int64_t int64_t "sys/types.h" __int64)
|
||||
check_type_exists(int8_t int8_t "sys/types.h" char)
|
||||
check_type_exists(pid_t pid_t "sys/types.h" int)
|
||||
check_type_exists(rlim_t rlim_t "sys/resource.h" "unsigned long")
|
||||
check_type_exists(ssize_t ssize_t "sys/types.h" int)
|
||||
check_type_exists(uid_t uid_t "sys/types.h" int)
|
||||
check_type_exists(uint16_t uint16_t "sys/types.h" "unsigned short")
|
||||
check_type_exists(uint32_t uint32_t "sys/types.h" "unsigned int")
|
||||
check_type_exists(uint64_t uint64_t "sys/types.h" "unsigned long long")
|
||||
check_type_exists(uint8_t uint8_t "sys/types.h" "unsigned char")
|
||||
|
||||
if (WIN32)
|
||||
set(UB_ON_WINDOWS 1)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
set(inline __inline)
|
||||
set(__func__ __FUNCTION__)
|
||||
endif ()
|
||||
|
||||
if (NOT HAVE_VFORK)
|
||||
set(vfork fork)
|
||||
endif ()
|
||||
|
||||
# XXX: Check for broken malloc()?
|
||||
# XXX: Check for broken memcmp()?
|
||||
# XXX: Check for broken vfork()?
|
||||
# XXX: Check for one-arg mkdir?
|
||||
|
||||
check_symbol_exists(PTHREAD_PRIO_INHERIT "pthread.h" HAVE_PTHREAD_PRIO_INHERIT)
|
||||
check_symbol_exists(pthread_rwlock_t "pthread.h" HAVE_PTHREAD_RWLOCK_T)
|
||||
check_symbol_exists(pthread_spinlock_t "pthread.h" HAVE_PTHREAD_SPINLOCK_T)
|
||||
|
||||
# openssl
|
||||
set(CMAKE_REQUIRED_INCLUDES
|
||||
${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
check_include_file(openssl/conf.h HAVE_OPENSSL_CONF_H)
|
||||
check_include_file(openssl/engine.h HAVE_OPENSSL_ENGINE_H)
|
||||
check_include_file(openssl/err.h HAVE_OPENSSL_ERR_H)
|
||||
check_include_file(openssl/rand.h HAVE_OPENSSL_RAND_H)
|
||||
check_include_file(openssl/ssl.h HAVE_OPENSSL_SSL_H)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
|
||||
check_symbol_exists(NID_secp384r1 "openssl/evp.h" HAVE_DECL_NID_SECP384R1)
|
||||
check_symbol_exists(NID_X9_62_prime256v1 "openssl/evp.h" HAVE_DECL_NID_X9_62_PRIME256V1)
|
||||
check_symbol_exists(sk_SSL_COMP_pop_free "openssl/ssl.h" HAVE_DECL_SK_SSL_COMP_POP_FREE)
|
||||
check_symbol_exists(SSL_COMP_get_compression_methods "openssl/ssl.h" HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES
|
||||
${OPENSSL_LIBRARIES})
|
||||
|
||||
check_function_exists(EVP_sha1 HAVE_EVP_SHA1)
|
||||
check_function_exists(EVP_sha256 HAVE_EVP_SHA256)
|
||||
check_function_exists(EVP_sha512 HAVE_EVP_SHA512)
|
||||
check_function_exists(FIPS_mode HAVE_FIPS_MODE)
|
||||
check_function_exists(HMAC_CTX_init HAVE_HMAC_CTX_INIT)
|
||||
check_function_exists(OPENSSL_config HAVE_OPENSSL_CONFIG)
|
||||
check_function_exists(SHA512_Update HAVE_SHA512_UPDATE)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
set(UNBOUND_CONFIGFILE "${CMAKE_INSTALL_PREFIX}/etc/unbound/unbound.conf"
|
||||
CACHE STRING "default configuration file")
|
||||
set(UNBOUND_USERNAME "unbound"
|
||||
CACHE STRING "default user that unbound changes to")
|
||||
set(UNBOUND_CHROOT_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound"
|
||||
CACHE STRING "default directory to chroot to")
|
||||
set(UNBOUND_RUN_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound"
|
||||
CACHE STRING "default directory to chroot to")
|
||||
set(UNBOUND_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/etc/unbound"
|
||||
CACHE STRING "default directory with shared data")
|
||||
set(UNBOUND_PIDFILE "${CMAKE_INSTALL_PREFIX}/etc/unbound/unbound.pid"
|
||||
CACHE STRING "default pathname to the pidfile")
|
||||
|
||||
# Copied from configure.ac.
|
||||
set(WINVER 0x0502)
|
||||
set(PACKAGE_VERSION "1.4.23")
|
||||
set(PACKAGE_NAME "${PROJECT_NAME}")
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(MAXSYSLOGMSGLEN 10240)
|
||||
|
||||
# Make assumptions.
|
||||
set(HAVE_WORKING_FORK ${HAVE_FORK})
|
||||
set(HAVE_WORKING_VFORK ${HAVE_VFORK})
|
4
external/unbound/contrib/README
vendored
4
external/unbound/contrib/README
vendored
@ -25,4 +25,8 @@ distribution but may be helpful.
|
||||
* unbound_cache.cmd: windows script to save and load the cache.
|
||||
* warmup.sh: shell script to warm up DNS cache by your own MRU domains.
|
||||
* warmup.cmd: windows script to warm up DNS cache by your own MRU domains.
|
||||
* aaaa-filter-iterator.patch: adds config option aaaa-filter: yes that
|
||||
works like the BIND feature (removes AAAA records unless AAAA-only domain).
|
||||
Useful for certain 'broken IPv6 default route' scenarios.
|
||||
Patch from Stephane Lapie for ASAHI Net.
|
||||
|
||||
|
394
external/unbound/contrib/aaaa-filter-iterator.patch
vendored
Normal file
394
external/unbound/contrib/aaaa-filter-iterator.patch
vendored
Normal file
@ -0,0 +1,394 @@
|
||||
--- unbound-1.4.17.orig/doc/unbound.conf.5.in
|
||||
+++ unbound-1.4.17/doc/unbound.conf.5.in
|
||||
@@ -519,6 +519,13 @@ authority servers and checks if the repl
|
||||
Disabled by default.
|
||||
This feature is an experimental implementation of draft dns\-0x20.
|
||||
.TP
|
||||
+.B aaaa\-filter: \fI<yes or no>
|
||||
+Activate behavior similar to BIND's AAAA-filter.
|
||||
+This forces the dropping of all AAAA records, unless in the case of
|
||||
+explicit AAAA queries, when no A records have been confirmed.
|
||||
+This also causes an additional A query to be sent for each AAAA query.
|
||||
+This breaks DNSSEC!
|
||||
+.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for public
|
||||
--- unbound-1.4.17.orig/util/config_file.c
|
||||
+++ unbound-1.4.17/util/config_file.c
|
||||
@@ -160,6 +160,7 @@ config_create(void)
|
||||
cfg->harden_below_nxdomain = 0;
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->use_caps_bits_for_id = 0;
|
||||
+ cfg->aaaa_filter = 0; /* ASN: default is disabled */
|
||||
cfg->private_address = NULL;
|
||||
cfg->private_domain = NULL;
|
||||
cfg->unwanted_threshold = 0;
|
||||
--- unbound-1.4.17.orig/iterator/iter_scrub.c
|
||||
+++ unbound-1.4.17/iterator/iter_scrub.c
|
||||
@@ -580,6 +580,32 @@ static int sanitize_nsec_is_overreach(st
|
||||
}
|
||||
|
||||
/**
|
||||
+ * ASN: Lookup A records from rrset cache.
|
||||
+ * @param qinfo: the question originally asked.
|
||||
+ * @param env: module environment with config and cache.
|
||||
+ * @param ie: iterator environment with private address data.
|
||||
+ * @return 0 if no A record found, 1 if A record found.
|
||||
+ */
|
||||
+static int
|
||||
+asn_lookup_a_record_from_cache(struct query_info* qinfo,
|
||||
+ struct module_env* env, struct iter_env* ie)
|
||||
+{
|
||||
+ struct ub_packed_rrset_key* akey;
|
||||
+
|
||||
+ /* get cached A records for queried name */
|
||||
+ akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
|
||||
+ qinfo->qname_len, LDNS_RR_TYPE_A, qinfo->qclass,
|
||||
+ 0, *env->now, 0);
|
||||
+ if(akey) { /* we had some. */
|
||||
+ log_rrset_key(VERB_ALGO, "ASN-AAAA-filter: found A record",
|
||||
+ akey);
|
||||
+ lock_rw_unlock(&akey->entry.lock);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* Given a response event, remove suspect RRsets from the response.
|
||||
* "Suspect" rrsets are potentially poison. Note that this routine expects
|
||||
* the response to be in a "normalized" state -- that is, all "irrelevant"
|
||||
@@ -598,6 +625,7 @@ scrub_sanitize(ldns_buffer* pkt, struct
|
||||
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
|
||||
struct iter_env* ie)
|
||||
{
|
||||
+ int found_a_record = 0; /* ASN: do we have a A record? */
|
||||
int del_addi = 0; /* if additional-holding rrsets are deleted, we
|
||||
do not trust the normalized additional-A-AAAA any more */
|
||||
struct rrset_parse* rrset, *prev;
|
||||
@@ -633,6 +661,13 @@ scrub_sanitize(ldns_buffer* pkt, struct
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
||||
+ /* ASN: Locate any A record we can find */
|
||||
+ if((ie->aaaa_filter) && (qinfo->qtype == LDNS_RR_TYPE_AAAA)) {
|
||||
+ found_a_record = asn_lookup_a_record_from_cache(qinfo,
|
||||
+ env, ie);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
+
|
||||
/* At this point, we brutally remove ALL rrsets that aren't
|
||||
* children of the originating zone. The idea here is that,
|
||||
* as far as we know, the server that we contacted is ONLY
|
||||
@@ -644,6 +679,24 @@ scrub_sanitize(ldns_buffer* pkt, struct
|
||||
rrset = msg->rrset_first;
|
||||
while(rrset) {
|
||||
|
||||
+ /* ASN: For AAAA records only... */
|
||||
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
+ /* ASN: If this is not a AAAA query, then remove AAAA
|
||||
+ * records, no questions asked. If this IS a AAAA query
|
||||
+ * then remove AAAA records if we have an A record.
|
||||
+ * Otherwise, leave things be. */
|
||||
+ if((qinfo->qtype != LDNS_RR_TYPE_AAAA) ||
|
||||
+ (found_a_record)) {
|
||||
+ remove_rrset("ASN-AAAA-filter: removing AAAA "
|
||||
+ "for record", pkt, msg, prev, &rrset);
|
||||
+ continue;
|
||||
+ }
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
|
||||
+ "keep AAAA for", zonename,
|
||||
+ LDNS_RR_TYPE_AAAA, qinfo->qclass);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
+
|
||||
/* remove private addresses */
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA) &&
|
||||
--- unbound-1.4.17.orig/iterator/iterator.c
|
||||
+++ unbound-1.4.17/iterator/iterator.c
|
||||
@@ -1579,6 +1579,53 @@ processDSNSFind(struct module_qstate* qs
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * ASN: This event state was added as an intermediary step between
|
||||
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
|
||||
+ * purpose of caching A records for the queried name.
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param iq: iterator query state.
|
||||
+ * @param ie: iterator shared global environment.
|
||||
+ * @param id: module id.
|
||||
+ * @return true if the event requires more request processing immediately,
|
||||
+ * false if not. This state only returns true when it is generating
|
||||
+ * a SERVFAIL response because the query has hit a dead end.
|
||||
+ */
|
||||
+static int
|
||||
+asn_processQueryAAAA(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
+ struct iter_env* ie, int id)
|
||||
+{
|
||||
+ struct module_qstate* subq = NULL;
|
||||
+
|
||||
+ log_assert(iq->fetch_a_for_aaaa == 0);
|
||||
+
|
||||
+ /* flag the query properly in order to not loop */
|
||||
+ iq->fetch_a_for_aaaa = 1;
|
||||
+
|
||||
+ /* re-throw same query, but with a different type */
|
||||
+ if(!generate_sub_request(iq->qchase.qname,
|
||||
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass, qstate, id, iq,
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
|
||||
+ "preloading of A record for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass);
|
||||
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
+ }
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
|
||||
+ "preloading records in cache for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass);
|
||||
+
|
||||
+ /* set this query as waiting */
|
||||
+ qstate->ext_state[id] = module_wait_subquery;
|
||||
+ /* at this point break loop */
|
||||
+ return 0;
|
||||
+}
|
||||
+/* ASN: End of added code */
|
||||
|
||||
/**
|
||||
* This is the request event state where the request will be sent to one of
|
||||
@@ -1626,6 +1673,13 @@ processQueryTargets(struct module_qstate
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
+ /* ASN: If we have a AAAA query, then also query for A records */
|
||||
+ if((ie->aaaa_filter) && (iq->qchase.qtype == LDNS_RR_TYPE_AAAA) &&
|
||||
+ (iq->fetch_a_for_aaaa == 0)) {
|
||||
+ return next_state(iq, ASN_FETCH_A_FOR_AAAA_STATE);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
+
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
if(!iq->dp) {
|
||||
@@ -2568,6 +2622,62 @@ processFinished(struct module_qstate* qs
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ASN: Do final processing on responses to A queries originated from AAAA
|
||||
+ * queries. Events reach this state after the iterative resolution algorithm
|
||||
+ * terminates.
|
||||
+ * This is required down the road to decide whether to scrub AAAA records
|
||||
+ * from the results or not.
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param id: module id.
|
||||
+ * @param forq: super query state.
|
||||
+ */
|
||||
+static void
|
||||
+asn_processAAAAResponse(struct module_qstate* qstate, int id,
|
||||
+ struct module_qstate* super)
|
||||
+{
|
||||
+ struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
||||
+ struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
|
||||
+ struct ub_packed_rrset_key* rrset;
|
||||
+ struct delegpt_ns* dpns = NULL;
|
||||
+ int error = (qstate->return_rcode != LDNS_RCODE_NOERROR);
|
||||
+
|
||||
+ log_assert(super_iq->fetch_a_for_aaaa > 0);
|
||||
+
|
||||
+ /* let super go to evaluation of targets after this */
|
||||
+ super_iq->state = QUERYTARGETS_STATE;
|
||||
+
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse",
|
||||
+ &qstate->qinfo);
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse super",
|
||||
+ &super->qinfo);
|
||||
+
|
||||
+ if(super_iq->dp)
|
||||
+ dpns = delegpt_find_ns(super_iq->dp,
|
||||
+ qstate->qinfo.qname, qstate->qinfo.qname_len);
|
||||
+ if (!dpns) {
|
||||
+ /* not interested */
|
||||
+ verbose(VERB_ALGO, "ASN-AAAA-filter: subq: %s, but parent not "
|
||||
+ "interested%s", (error ? "error, but" : "success"),
|
||||
+ (super_iq->dp ? "anymore" : " (was reset)"));
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: superq", &super->qinfo);
|
||||
+ if(super_iq->dp && error)
|
||||
+ delegpt_log(VERB_ALGO, super_iq->dp);
|
||||
+ return;
|
||||
+ } else if (error) {
|
||||
+ verbose(VERB_ALGO, "ASN-AAAA-filter: mark as failed, "
|
||||
+ "and go to target query.");
|
||||
+ /* see if the failure did get (parent-lame) info */
|
||||
+ if(!cache_fill_missing(super->env,
|
||||
+ super_iq->qchase.qclass, super->region,
|
||||
+ super_iq->dp))
|
||||
+ log_err("ASN-AAAA-filter: out of memory adding missing");
|
||||
+ dpns->resolved = 1; /* mark as failed */
|
||||
+ }
|
||||
+}
|
||||
+/* ASN: End of added code */
|
||||
+
|
||||
/*
|
||||
* Return priming query results to interestes super querystates.
|
||||
*
|
||||
@@ -2587,6 +2697,9 @@ iter_inform_super(struct module_qstate*
|
||||
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
|
||||
super->minfo[id])->state == DSNS_FIND_STATE)
|
||||
processDSNSResponse(qstate, id, super);
|
||||
+ else if (super->qinfo.qtype == LDNS_RR_TYPE_AAAA && ((struct iter_qstate*)
|
||||
+ super->minfo[id])->state == ASN_FETCH_A_FOR_AAAA_STATE)
|
||||
+ asn_processAAAAResponse(qstate, id, super);
|
||||
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
|
||||
error_supers(qstate, id, super);
|
||||
else if(qstate->is_priming)
|
||||
@@ -2624,6 +2737,9 @@ iter_handle(struct module_qstate* qstate
|
||||
case INIT_REQUEST_3_STATE:
|
||||
cont = processInitRequest3(qstate, iq, id);
|
||||
break;
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE:
|
||||
+ cont = asn_processQueryAAAA(qstate, iq, ie, id);
|
||||
+ break;
|
||||
case QUERYTARGETS_STATE:
|
||||
cont = processQueryTargets(qstate, iq, ie, id);
|
||||
break;
|
||||
@@ -2863,6 +2979,8 @@ iter_state_to_string(enum iter_state sta
|
||||
return "INIT REQUEST STATE (stage 2)";
|
||||
case INIT_REQUEST_3_STATE:
|
||||
return "INIT REQUEST STATE (stage 3)";
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE:
|
||||
+ return "ASN_FETCH_A_FOR_AAAA_STATE";
|
||||
case QUERYTARGETS_STATE :
|
||||
return "QUERY TARGETS STATE";
|
||||
case PRIME_RESP_STATE :
|
||||
@@ -2887,6 +3005,7 @@ iter_state_is_responsestate(enum iter_st
|
||||
case INIT_REQUEST_STATE :
|
||||
case INIT_REQUEST_2_STATE :
|
||||
case INIT_REQUEST_3_STATE :
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE :
|
||||
case QUERYTARGETS_STATE :
|
||||
case COLLECT_CLASS_STATE :
|
||||
return 0;
|
||||
--- unbound-1.4.17.orig/iterator/iter_utils.c
|
||||
+++ unbound-1.4.17/iterator/iter_utils.c
|
||||
@@ -128,6 +128,7 @@ iter_apply_cfg(struct iter_env* iter_env
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
+ iter_env->aaaa_filter = cfg->aaaa_filter;
|
||||
return 1;
|
||||
}
|
||||
|
||||
--- unbound-1.4.17.orig/iterator/iterator.h
|
||||
+++ unbound-1.4.17/iterator/iterator.h
|
||||
@@ -110,6 +110,9 @@ struct iter_env {
|
||||
* array of max_dependency_depth+1 size.
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
+
|
||||
+ /** ASN: AAAA-filter flag */
|
||||
+ int aaaa_filter;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -135,6 +138,14 @@ enum iter_state {
|
||||
INIT_REQUEST_3_STATE,
|
||||
|
||||
/**
|
||||
+ * This state is responsible for intercepting AAAA queries,
|
||||
+ * and launch a A subquery on the same target, to populate the
|
||||
+ * cache with A records, so the AAAA filter scrubbing logic can
|
||||
+ * work.
|
||||
+ */
|
||||
+ ASN_FETCH_A_FOR_AAAA_STATE,
|
||||
+
|
||||
+ /**
|
||||
* Each time a delegation point changes for a given query or a
|
||||
* query times out and/or wakes up, this state is (re)visited.
|
||||
* This state is reponsible for iterating through a list of
|
||||
@@ -309,6 +320,13 @@ struct iter_qstate {
|
||||
*/
|
||||
int refetch_glue;
|
||||
|
||||
+ /**
|
||||
+ * ASN: This is a flag that, if true, means that this query is
|
||||
+ * for fetching A records to populate cache and determine if we must
|
||||
+ * return AAAA records or not.
|
||||
+ */
|
||||
+ int fetch_a_for_aaaa;
|
||||
+
|
||||
/** list of pending queries to authoritative servers. */
|
||||
struct outbound_list outlist;
|
||||
};
|
||||
--- unbound-1.4.17.orig/util/config_file.h
|
||||
+++ unbound-1.4.17/util/config_file.h
|
||||
@@ -169,6 +169,8 @@ struct config_file {
|
||||
int harden_referral_path;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
+ /** ASN: enable AAAA filter? */
|
||||
+ int aaaa_filter;
|
||||
/** strip away these private addrs from answers, no DNS Rebinding */
|
||||
struct config_strlist* private_address;
|
||||
/** allow domain (and subdomains) to use private address space */
|
||||
--- unbound-1.4.17.orig/util/configlexer.lex
|
||||
+++ unbound-1.4.17/util/configlexer.lex
|
||||
@@ -177,6 +177,7 @@ harden-below-nxdomain{COLON} { YDVAR(1,
|
||||
harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }
|
||||
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
|
||||
+aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) }
|
||||
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
|
||||
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
|
||||
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
|
||||
--- unbound-1.4.17.orig/util/configparser.y
|
||||
+++ unbound-1.4.17/util/configparser.y
|
||||
@@ -92,6 +92,7 @@ extern struct config_parser_state* cfg_p
|
||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
||||
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
|
||||
+%token VAR_AAAA_FILTER
|
||||
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
||||
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||
@@ -151,6 +152,7 @@ content_server: server_num_threads | ser
|
||||
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
||||
server_harden_referral_path | server_private_address |
|
||||
server_private_domain | server_extended_statistics |
|
||||
+ server_aaaa_filter |
|
||||
server_local_data_ptr | server_jostle_timeout |
|
||||
server_unwanted_reply_threshold | server_log_time_ascii |
|
||||
server_domain_insecure | server_val_sig_skew_min |
|
||||
@@ -802,6 +803,15 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
|
||||
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
+ yyerror("expected yes or no.");
|
||||
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
|
||||
+ free($2);
|
||||
+ }
|
||||
+ ;
|
||||
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_private_address:%s)\n", $2));
|
||||
--- unbound-1.4.17.orig/pythonmod/interface.i
|
||||
+++ unbound-1.4.17/pythonmod/interface.i
|
||||
@@ -626,6 +626,7 @@ struct config_file {
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
+ int aaaa_filter; /* ASN */
|
||||
struct config_strlist* private_address;
|
||||
struct config_strlist* private_domain;
|
||||
size_t unwanted_threshold;
|
BIN
external/unbound/contrib/unbound_cacti.tar.gz
vendored
BIN
external/unbound/contrib/unbound_cacti.tar.gz
vendored
Binary file not shown.
2
external/unbound/daemon/cachedump.c
vendored
2
external/unbound/daemon/cachedump.c
vendored
@ -664,7 +664,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
if(!go_on)
|
||||
return 1; /* skip this one, not all references satisfied */
|
||||
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) {
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
23
external/unbound/daemon/remote.c
vendored
23
external/unbound/daemon/remote.c
vendored
@ -38,8 +38,8 @@
|
||||
*
|
||||
* This file contains the remote control functionality for the daemon.
|
||||
* The remote control can be performed using either the commandline
|
||||
* unbound-control tool, or a SSLv3/TLS capable web browser.
|
||||
* The channel is secured using SSLv3 or TLSv1, and certificates.
|
||||
* unbound-control tool, or a TLS capable web browser.
|
||||
* The channel is secured using TLSv1, and certificates.
|
||||
* Both the server and the client(control tool) have their own keys.
|
||||
*/
|
||||
#include "config.h"
|
||||
@ -154,12 +154,17 @@ daemon_remote_create(struct config_file* cfg)
|
||||
free(rc);
|
||||
return NULL;
|
||||
}
|
||||
/* no SSLv2 because has defects */
|
||||
/* no SSLv2, SSLv3 because has defects */
|
||||
if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){
|
||||
log_crypto_err("could not set SSL_OP_NO_SSLv2");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
if(!(SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)){
|
||||
log_crypto_err("could not set SSL_OP_NO_SSLv3");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
|
||||
if(!s_cert || !s_key) {
|
||||
@ -558,7 +563,7 @@ static char*
|
||||
skipwhite(char* str)
|
||||
{
|
||||
/* EOS \0 is not a space */
|
||||
while( isspace(*str) )
|
||||
while( isspace((unsigned char)*str) )
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
@ -849,7 +854,8 @@ print_ext(SSL* ssl, struct stats_info* s)
|
||||
|
||||
/* RCODE */
|
||||
for(i=0; i<STATS_RCODE_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.ans_rcode[i] == 0)
|
||||
/* Always include RCODEs 0-5 */
|
||||
if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0)
|
||||
continue;
|
||||
lt = sldns_lookup_by_id(sldns_rcodes, i);
|
||||
if(lt && lt->name) {
|
||||
@ -1089,8 +1095,13 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
k.qname_len = nmlen;
|
||||
k.qtype = t;
|
||||
k.qclass = c;
|
||||
h = query_info_hash(&k);
|
||||
h = query_info_hash(&k, 0);
|
||||
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||
if(t == LDNS_RR_TYPE_AAAA) {
|
||||
/* for AAAA also flush dns64 bit_cd packet */
|
||||
h = query_info_hash(&k, BIT_CD);
|
||||
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||
}
|
||||
}
|
||||
|
||||
/** flush a type */
|
||||
|
2
external/unbound/daemon/unbound.c
vendored
2
external/unbound/daemon/unbound.c
vendored
@ -287,7 +287,7 @@ checkrlimits(struct config_file* cfg)
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
}
|
||||
#endif
|
||||
log_warn("increased limit(open files) from %u to %u",
|
||||
verbose(VERB_ALGO, "increased limit(open files) from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
}
|
||||
#else
|
||||
|
2
external/unbound/daemon/worker.c
vendored
2
external/unbound/daemon/worker.c
vendored
@ -935,7 +935,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
}
|
||||
h = query_info_hash(&qinfo);
|
||||
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
|
8
external/unbound/dns64/dns64.c
vendored
8
external/unbound/dns64/dns64.c
vendored
@ -399,7 +399,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
|
||||
/* Create the new sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
|
||||
&subq))
|
||||
return module_error;
|
||||
if (subq) {
|
||||
@ -451,7 +451,7 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
/* Start the sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
||||
&subq))
|
||||
0, &subq))
|
||||
{
|
||||
verbose(VERB_ALGO, "dns64: sub-query creation failed");
|
||||
return module_error;
|
||||
@ -520,11 +520,13 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
*
|
||||
* - An internal query.
|
||||
* - A query for a record type other than AAAA.
|
||||
* - CD FLAG was set on querier
|
||||
* - An AAAA query for which an error was returned.
|
||||
* - A successful AAAA query with an answer.
|
||||
*/
|
||||
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
||||
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
||||
|| (qstate->query_flags & BIT_CD)
|
||||
|| qstate->return_rcode != LDNS_RCODE_NOERROR
|
||||
|| (qstate->return_msg &&
|
||||
qstate->return_msg->rep &&
|
||||
@ -813,7 +815,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL))
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
log_err("out of memory");
|
||||
}
|
||||
|
||||
|
49
external/unbound/dnstap/dnstap.c
vendored
49
external/unbound/dnstap/dnstap.c
vendored
@ -37,6 +37,7 @@
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "ldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
@ -65,6 +66,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
{
|
||||
ProtobufCBufferSimple sbuf;
|
||||
|
||||
memset(&sbuf, 0, sizeof(sbuf));
|
||||
sbuf.base.append = protobuf_c_buffer_simple_append;
|
||||
sbuf.len = 0;
|
||||
sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
|
||||
@ -87,9 +89,9 @@ dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
fstrm_res res;
|
||||
if (!buf)
|
||||
return;
|
||||
res = fstrm_io_submit(env->fio, env->fq, buf, len_buf,
|
||||
fstrm_free_wrapper, NULL);
|
||||
if (res != FSTRM_RES_SUCCESS)
|
||||
res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
|
||||
fstrm_free_wrapper, NULL);
|
||||
if (res != fstrm_res_success)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
@ -119,10 +121,12 @@ dt_msg_init(const struct dt_env *env,
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
{
|
||||
char *fio_err;
|
||||
fstrm_res res;
|
||||
struct dt_env *env;
|
||||
struct fstrm_io_options *fopt;
|
||||
struct fstrm_iothr_options *fopt;
|
||||
struct fstrm_unix_writer_options *fuwopt;
|
||||
struct fstrm_writer *fw;
|
||||
struct fstrm_writer_options *fwopt;
|
||||
|
||||
verbose(VERB_OPS, "opening dnstap socket %s", socket_path);
|
||||
log_assert(socket_path != NULL);
|
||||
@ -132,24 +136,29 @@ dt_create(const char *socket_path, unsigned num_workers)
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
fwopt = fstrm_writer_options_init();
|
||||
res = fstrm_writer_options_add_content_type(fwopt,
|
||||
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
log_assert(res == fstrm_res_success);
|
||||
|
||||
fuwopt = fstrm_unix_writer_options_init();
|
||||
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
|
||||
fopt = fstrm_io_options_init();
|
||||
fstrm_io_options_set_content_type(fopt,
|
||||
DNSTAP_CONTENT_TYPE,
|
||||
sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
fstrm_io_options_set_num_queues(fopt, num_workers);
|
||||
fstrm_io_options_set_writer(fopt, fstrm_unix_writer, fuwopt);
|
||||
env->fio = fstrm_io_init(fopt, &fio_err);
|
||||
if (env->fio == NULL) {
|
||||
verbose(VERB_DETAIL, "dt_create: fstrm_io_init() failed: %s",
|
||||
fio_err);
|
||||
free(fio_err);
|
||||
|
||||
fw = fstrm_unix_writer_init(fuwopt, fwopt);
|
||||
log_assert(fw != NULL);
|
||||
|
||||
fopt = fstrm_iothr_options_init();
|
||||
fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
|
||||
env->iothr = fstrm_iothr_init(fopt, &fw);
|
||||
if (env->iothr == NULL) {
|
||||
verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed");
|
||||
fstrm_writer_destroy(&fw);
|
||||
free(env);
|
||||
env = NULL;
|
||||
}
|
||||
fstrm_io_options_destroy(&fopt);
|
||||
fstrm_iothr_options_destroy(&fopt);
|
||||
fstrm_unix_writer_options_destroy(&fuwopt);
|
||||
fstrm_writer_options_destroy(&fwopt);
|
||||
|
||||
return env;
|
||||
}
|
||||
@ -238,8 +247,8 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
int
|
||||
dt_init(struct dt_env *env)
|
||||
{
|
||||
env->fq = fstrm_io_get_queue(env->fio);
|
||||
if (env->fq == NULL)
|
||||
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
|
||||
if (env->ioq == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -250,7 +259,7 @@ dt_delete(struct dt_env *env)
|
||||
if (!env)
|
||||
return;
|
||||
verbose(VERB_OPS, "closing dnstap socket");
|
||||
fstrm_io_destroy(&env->fio);
|
||||
fstrm_iothr_destroy(&env->iothr);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
|
8
external/unbound/dnstap/dnstap.h
vendored
8
external/unbound/dnstap/dnstap.h
vendored
@ -45,11 +45,11 @@ struct fstrm_queue;
|
||||
struct sldns_buffer;
|
||||
|
||||
struct dt_env {
|
||||
/** dnstap I/O socket */
|
||||
struct fstrm_io *fio;
|
||||
/** dnstap I/O thread */
|
||||
struct fstrm_iothr *iothr;
|
||||
|
||||
/** dnstap I/O queue */
|
||||
struct fstrm_queue *fq;
|
||||
/** dnstap I/O thread input queue */
|
||||
struct fstrm_iothr_queue *ioq;
|
||||
|
||||
/** dnstap "identity" field, NULL if disabled */
|
||||
char *identity;
|
||||
|
12
external/unbound/dnstap/dnstap.m4
vendored
12
external/unbound/dnstap/dnstap.m4
vendored
@ -22,7 +22,7 @@ AC_DEFUN([dt_DNSTAP],
|
||||
fi
|
||||
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
|
||||
[Path where protobuf-c is installed, for dnstap]), [
|
||||
# workaround for protobuf includes at old dir before protobuf-1.0.0
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I$withval/include/google"
|
||||
else
|
||||
@ -30,7 +30,7 @@ AC_DEFUN([dt_DNSTAP],
|
||||
fi
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
], [
|
||||
# workaround for protobuf includes at old dir before protobuf-1.0.0
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
@ -41,12 +41,14 @@ AC_DEFUN([dt_DNSTAP],
|
||||
fi
|
||||
])
|
||||
AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
|
||||
[Path where libfstrm in installed, for dnstap]), [
|
||||
[Path where libfstrm is installed, for dnstap]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
])
|
||||
AC_SEARCH_LIBS([fstrm_io_init], [fstrm])
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c])
|
||||
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
|
||||
AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!]))
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
|
||||
$2
|
||||
else
|
||||
$3
|
||||
|
518
external/unbound/dnstap/dnstap.pb-c.c
vendored
518
external/unbound/dnstap/dnstap.pb-c.c
vendored
@ -1,518 +0,0 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
|
||||
/* Do not generate deprecated warnings for self */
|
||||
#ifndef PROTOBUF_C_NO_DEPRECATED
|
||||
#define PROTOBUF_C_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include "dnstap/dnstap.pb-c.h"
|
||||
void dnstap__dnstap__init
|
||||
(Dnstap__Dnstap *message)
|
||||
{
|
||||
static Dnstap__Dnstap init_value = DNSTAP__DNSTAP__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t dnstap__dnstap__get_packed_size
|
||||
(const Dnstap__Dnstap *message)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t dnstap__dnstap__pack
|
||||
(const Dnstap__Dnstap *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t dnstap__dnstap__pack_to_buffer
|
||||
(const Dnstap__Dnstap *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Dnstap__Dnstap *
|
||||
dnstap__dnstap__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Dnstap__Dnstap *)
|
||||
protobuf_c_message_unpack (&dnstap__dnstap__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void dnstap__dnstap__free_unpacked
|
||||
(Dnstap__Dnstap *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__dnstap__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
void dnstap__message__init
|
||||
(Dnstap__Message *message)
|
||||
{
|
||||
static Dnstap__Message init_value = DNSTAP__MESSAGE__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
size_t dnstap__message__get_packed_size
|
||||
(const Dnstap__Message *message)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
|
||||
}
|
||||
size_t dnstap__message__pack
|
||||
(const Dnstap__Message *message,
|
||||
uint8_t *out)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
|
||||
}
|
||||
size_t dnstap__message__pack_to_buffer
|
||||
(const Dnstap__Message *message,
|
||||
ProtobufCBuffer *buffer)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
|
||||
}
|
||||
Dnstap__Message *
|
||||
dnstap__message__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data)
|
||||
{
|
||||
return (Dnstap__Message *)
|
||||
protobuf_c_message_unpack (&dnstap__message__descriptor,
|
||||
allocator, len, data);
|
||||
}
|
||||
void dnstap__message__free_unpacked
|
||||
(Dnstap__Message *message,
|
||||
ProtobufCAllocator *allocator)
|
||||
{
|
||||
PROTOBUF_C_ASSERT (message->base.descriptor == &dnstap__message__descriptor);
|
||||
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
|
||||
}
|
||||
const ProtobufCEnumValue dnstap__dnstap__type__enum_values_by_number[1] =
|
||||
{
|
||||
{ "MESSAGE", "DNSTAP__DNSTAP__TYPE__MESSAGE", 1 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__dnstap__type__value_ranges[] = {
|
||||
{1, 0},{0, 1}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__dnstap__type__enum_values_by_name[1] =
|
||||
{
|
||||
{ "MESSAGE", 0 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Dnstap.Type",
|
||||
"Type",
|
||||
"Dnstap__Dnstap__Type",
|
||||
"dnstap",
|
||||
1,
|
||||
dnstap__dnstap__type__enum_values_by_number,
|
||||
1,
|
||||
dnstap__dnstap__type__enum_values_by_name,
|
||||
1,
|
||||
dnstap__dnstap__type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor dnstap__dnstap__field_descriptors[5] =
|
||||
{
|
||||
{
|
||||
"identity",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_identity),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, identity),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"version",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_version),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, version),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"extra",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, has_extra),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, extra),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"message",
|
||||
14,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_MESSAGE,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, message),
|
||||
&dnstap__message__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"type",
|
||||
15,
|
||||
PROTOBUF_C_LABEL_REQUIRED,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Dnstap, type),
|
||||
&dnstap__dnstap__type__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned dnstap__dnstap__field_indices_by_name[] = {
|
||||
2, /* field[2] = extra */
|
||||
0, /* field[0] = identity */
|
||||
3, /* field[3] = message */
|
||||
4, /* field[4] = type */
|
||||
1, /* field[1] = version */
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__dnstap__number_ranges[2 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 14, 3 },
|
||||
{ 0, 5 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor dnstap__dnstap__descriptor =
|
||||
{
|
||||
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Dnstap",
|
||||
"Dnstap",
|
||||
"Dnstap__Dnstap",
|
||||
"dnstap",
|
||||
sizeof(Dnstap__Dnstap),
|
||||
5,
|
||||
dnstap__dnstap__field_descriptors,
|
||||
dnstap__dnstap__field_indices_by_name,
|
||||
2, dnstap__dnstap__number_ranges,
|
||||
(ProtobufCMessageInit) dnstap__dnstap__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__message__type__enum_values_by_number[10] =
|
||||
{
|
||||
{ "AUTH_QUERY", "DNSTAP__MESSAGE__TYPE__AUTH_QUERY", 1 },
|
||||
{ "AUTH_RESPONSE", "DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE", 2 },
|
||||
{ "RESOLVER_QUERY", "DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY", 3 },
|
||||
{ "RESOLVER_RESPONSE", "DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE", 4 },
|
||||
{ "CLIENT_QUERY", "DNSTAP__MESSAGE__TYPE__CLIENT_QUERY", 5 },
|
||||
{ "CLIENT_RESPONSE", "DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE", 6 },
|
||||
{ "FORWARDER_QUERY", "DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY", 7 },
|
||||
{ "FORWARDER_RESPONSE", "DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE", 8 },
|
||||
{ "STUB_QUERY", "DNSTAP__MESSAGE__TYPE__STUB_QUERY", 9 },
|
||||
{ "STUB_RESPONSE", "DNSTAP__MESSAGE__TYPE__STUB_RESPONSE", 10 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__message__type__value_ranges[] = {
|
||||
{1, 0},{0, 10}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__message__type__enum_values_by_name[10] =
|
||||
{
|
||||
{ "AUTH_QUERY", 0 },
|
||||
{ "AUTH_RESPONSE", 1 },
|
||||
{ "CLIENT_QUERY", 4 },
|
||||
{ "CLIENT_RESPONSE", 5 },
|
||||
{ "FORWARDER_QUERY", 6 },
|
||||
{ "FORWARDER_RESPONSE", 7 },
|
||||
{ "RESOLVER_QUERY", 2 },
|
||||
{ "RESOLVER_RESPONSE", 3 },
|
||||
{ "STUB_QUERY", 8 },
|
||||
{ "STUB_RESPONSE", 9 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__message__type__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Message.Type",
|
||||
"Type",
|
||||
"Dnstap__Message__Type",
|
||||
"dnstap",
|
||||
10,
|
||||
dnstap__message__type__enum_values_by_number,
|
||||
10,
|
||||
dnstap__message__type__enum_values_by_name,
|
||||
1,
|
||||
dnstap__message__type__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor dnstap__message__field_descriptors[14] =
|
||||
{
|
||||
{
|
||||
"type",
|
||||
1,
|
||||
PROTOBUF_C_LABEL_REQUIRED,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
0, /* quantifier_offset */
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, type),
|
||||
&dnstap__message__type__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"socket_family",
|
||||
2,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_family),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_family),
|
||||
&dnstap__socket_family__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"socket_protocol",
|
||||
3,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_ENUM,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_socket_protocol),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, socket_protocol),
|
||||
&dnstap__socket_protocol__descriptor,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_address",
|
||||
4,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_address),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_address),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_address",
|
||||
5,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_address),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_address),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_port",
|
||||
6,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_port),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_port),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_port",
|
||||
7,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_port),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_port),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_time_sec",
|
||||
8,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT64,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_sec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_sec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_time_nsec",
|
||||
9,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_FIXED32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_time_nsec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_time_nsec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_message",
|
||||
10,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_message),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_message),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"query_zone",
|
||||
11,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_query_zone),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, query_zone),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_time_sec",
|
||||
12,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_UINT64,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_sec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_sec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_time_nsec",
|
||||
13,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_FIXED32,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_time_nsec),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_time_nsec),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"response_message",
|
||||
14,
|
||||
PROTOBUF_C_LABEL_OPTIONAL,
|
||||
PROTOBUF_C_TYPE_BYTES,
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, has_response_message),
|
||||
PROTOBUF_C_OFFSETOF(Dnstap__Message, response_message),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* packed */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
static const unsigned dnstap__message__field_indices_by_name[] = {
|
||||
3, /* field[3] = query_address */
|
||||
9, /* field[9] = query_message */
|
||||
5, /* field[5] = query_port */
|
||||
8, /* field[8] = query_time_nsec */
|
||||
7, /* field[7] = query_time_sec */
|
||||
10, /* field[10] = query_zone */
|
||||
4, /* field[4] = response_address */
|
||||
13, /* field[13] = response_message */
|
||||
6, /* field[6] = response_port */
|
||||
12, /* field[12] = response_time_nsec */
|
||||
11, /* field[11] = response_time_sec */
|
||||
1, /* field[1] = socket_family */
|
||||
2, /* field[2] = socket_protocol */
|
||||
0, /* field[0] = type */
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__message__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 14 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor dnstap__message__descriptor =
|
||||
{
|
||||
PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC,
|
||||
"dnstap.Message",
|
||||
"Message",
|
||||
"Dnstap__Message",
|
||||
"dnstap",
|
||||
sizeof(Dnstap__Message),
|
||||
14,
|
||||
dnstap__message__field_descriptors,
|
||||
dnstap__message__field_indices_by_name,
|
||||
1, dnstap__message__number_ranges,
|
||||
(ProtobufCMessageInit) dnstap__message__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__socket_family__enum_values_by_number[2] =
|
||||
{
|
||||
{ "INET", "DNSTAP__SOCKET_FAMILY__INET", 1 },
|
||||
{ "INET6", "DNSTAP__SOCKET_FAMILY__INET6", 2 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__socket_family__value_ranges[] = {
|
||||
{1, 0},{0, 2}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__socket_family__enum_values_by_name[2] =
|
||||
{
|
||||
{ "INET", 0 },
|
||||
{ "INET6", 1 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__socket_family__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.SocketFamily",
|
||||
"SocketFamily",
|
||||
"Dnstap__SocketFamily",
|
||||
"dnstap",
|
||||
2,
|
||||
dnstap__socket_family__enum_values_by_number,
|
||||
2,
|
||||
dnstap__socket_family__enum_values_by_name,
|
||||
1,
|
||||
dnstap__socket_family__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
||||
const ProtobufCEnumValue dnstap__socket_protocol__enum_values_by_number[2] =
|
||||
{
|
||||
{ "UDP", "DNSTAP__SOCKET_PROTOCOL__UDP", 1 },
|
||||
{ "TCP", "DNSTAP__SOCKET_PROTOCOL__TCP", 2 },
|
||||
};
|
||||
static const ProtobufCIntRange dnstap__socket_protocol__value_ranges[] = {
|
||||
{1, 0},{0, 2}
|
||||
};
|
||||
const ProtobufCEnumValueIndex dnstap__socket_protocol__enum_values_by_name[2] =
|
||||
{
|
||||
{ "TCP", 1 },
|
||||
{ "UDP", 0 },
|
||||
};
|
||||
const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor =
|
||||
{
|
||||
PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC,
|
||||
"dnstap.SocketProtocol",
|
||||
"SocketProtocol",
|
||||
"Dnstap__SocketProtocol",
|
||||
"dnstap",
|
||||
2,
|
||||
dnstap__socket_protocol__enum_values_by_number,
|
||||
2,
|
||||
dnstap__socket_protocol__enum_values_by_name,
|
||||
1,
|
||||
dnstap__socket_protocol__value_ranges,
|
||||
NULL,NULL,NULL,NULL /* reserved[1234] */
|
||||
};
|
158
external/unbound/dnstap/dnstap.pb-c.h
vendored
158
external/unbound/dnstap/dnstap.pb-c.h
vendored
@ -1,158 +0,0 @@
|
||||
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
|
||||
|
||||
#ifndef PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
|
||||
#define PROTOBUF_C_dnstap_2fdnstap_2eproto__INCLUDED
|
||||
|
||||
#include <google/protobuf-c/protobuf-c.h>
|
||||
|
||||
PROTOBUF_C_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct _Dnstap__Dnstap Dnstap__Dnstap;
|
||||
typedef struct _Dnstap__Message Dnstap__Message;
|
||||
|
||||
|
||||
/* --- enums --- */
|
||||
|
||||
typedef enum _Dnstap__Dnstap__Type {
|
||||
DNSTAP__DNSTAP__TYPE__MESSAGE = 1
|
||||
} Dnstap__Dnstap__Type;
|
||||
typedef enum _Dnstap__Message__Type {
|
||||
DNSTAP__MESSAGE__TYPE__AUTH_QUERY = 1,
|
||||
DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE = 2,
|
||||
DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY = 3,
|
||||
DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE = 4,
|
||||
DNSTAP__MESSAGE__TYPE__CLIENT_QUERY = 5,
|
||||
DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE = 6,
|
||||
DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY = 7,
|
||||
DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE = 8,
|
||||
DNSTAP__MESSAGE__TYPE__STUB_QUERY = 9,
|
||||
DNSTAP__MESSAGE__TYPE__STUB_RESPONSE = 10
|
||||
} Dnstap__Message__Type;
|
||||
typedef enum _Dnstap__SocketFamily {
|
||||
DNSTAP__SOCKET_FAMILY__INET = 1,
|
||||
DNSTAP__SOCKET_FAMILY__INET6 = 2
|
||||
} Dnstap__SocketFamily;
|
||||
typedef enum _Dnstap__SocketProtocol {
|
||||
DNSTAP__SOCKET_PROTOCOL__UDP = 1,
|
||||
DNSTAP__SOCKET_PROTOCOL__TCP = 2
|
||||
} Dnstap__SocketProtocol;
|
||||
|
||||
/* --- messages --- */
|
||||
|
||||
struct _Dnstap__Dnstap
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
protobuf_c_boolean has_identity;
|
||||
ProtobufCBinaryData identity;
|
||||
protobuf_c_boolean has_version;
|
||||
ProtobufCBinaryData version;
|
||||
protobuf_c_boolean has_extra;
|
||||
ProtobufCBinaryData extra;
|
||||
Dnstap__Dnstap__Type type;
|
||||
Dnstap__Message *message;
|
||||
};
|
||||
#define DNSTAP__DNSTAP__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__dnstap__descriptor) \
|
||||
, 0,{0,NULL}, 0,{0,NULL}, 0,{0,NULL}, 0, NULL }
|
||||
|
||||
|
||||
struct _Dnstap__Message
|
||||
{
|
||||
ProtobufCMessage base;
|
||||
Dnstap__Message__Type type;
|
||||
protobuf_c_boolean has_socket_family;
|
||||
Dnstap__SocketFamily socket_family;
|
||||
protobuf_c_boolean has_socket_protocol;
|
||||
Dnstap__SocketProtocol socket_protocol;
|
||||
protobuf_c_boolean has_query_address;
|
||||
ProtobufCBinaryData query_address;
|
||||
protobuf_c_boolean has_response_address;
|
||||
ProtobufCBinaryData response_address;
|
||||
protobuf_c_boolean has_query_port;
|
||||
uint32_t query_port;
|
||||
protobuf_c_boolean has_response_port;
|
||||
uint32_t response_port;
|
||||
protobuf_c_boolean has_query_time_sec;
|
||||
uint64_t query_time_sec;
|
||||
protobuf_c_boolean has_query_time_nsec;
|
||||
uint32_t query_time_nsec;
|
||||
protobuf_c_boolean has_query_message;
|
||||
ProtobufCBinaryData query_message;
|
||||
protobuf_c_boolean has_query_zone;
|
||||
ProtobufCBinaryData query_zone;
|
||||
protobuf_c_boolean has_response_time_sec;
|
||||
uint64_t response_time_sec;
|
||||
protobuf_c_boolean has_response_time_nsec;
|
||||
uint32_t response_time_nsec;
|
||||
protobuf_c_boolean has_response_message;
|
||||
ProtobufCBinaryData response_message;
|
||||
};
|
||||
#define DNSTAP__MESSAGE__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&dnstap__message__descriptor) \
|
||||
, 0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,0, 0,0, 0,{0,NULL}, 0,{0,NULL}, 0,0, 0,0, 0,{0,NULL} }
|
||||
|
||||
|
||||
/* Dnstap__Dnstap methods */
|
||||
void dnstap__dnstap__init
|
||||
(Dnstap__Dnstap *message);
|
||||
size_t dnstap__dnstap__get_packed_size
|
||||
(const Dnstap__Dnstap *message);
|
||||
size_t dnstap__dnstap__pack
|
||||
(const Dnstap__Dnstap *message,
|
||||
uint8_t *out);
|
||||
size_t dnstap__dnstap__pack_to_buffer
|
||||
(const Dnstap__Dnstap *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Dnstap__Dnstap *
|
||||
dnstap__dnstap__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void dnstap__dnstap__free_unpacked
|
||||
(Dnstap__Dnstap *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* Dnstap__Message methods */
|
||||
void dnstap__message__init
|
||||
(Dnstap__Message *message);
|
||||
size_t dnstap__message__get_packed_size
|
||||
(const Dnstap__Message *message);
|
||||
size_t dnstap__message__pack
|
||||
(const Dnstap__Message *message,
|
||||
uint8_t *out);
|
||||
size_t dnstap__message__pack_to_buffer
|
||||
(const Dnstap__Message *message,
|
||||
ProtobufCBuffer *buffer);
|
||||
Dnstap__Message *
|
||||
dnstap__message__unpack
|
||||
(ProtobufCAllocator *allocator,
|
||||
size_t len,
|
||||
const uint8_t *data);
|
||||
void dnstap__message__free_unpacked
|
||||
(Dnstap__Message *message,
|
||||
ProtobufCAllocator *allocator);
|
||||
/* --- per-message closures --- */
|
||||
|
||||
typedef void (*Dnstap__Dnstap_Closure)
|
||||
(const Dnstap__Dnstap *message,
|
||||
void *closure_data);
|
||||
typedef void (*Dnstap__Message_Closure)
|
||||
(const Dnstap__Message *message,
|
||||
void *closure_data);
|
||||
|
||||
/* --- services --- */
|
||||
|
||||
|
||||
/* --- descriptors --- */
|
||||
|
||||
extern const ProtobufCEnumDescriptor dnstap__socket_family__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__socket_protocol__descriptor;
|
||||
extern const ProtobufCMessageDescriptor dnstap__dnstap__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__dnstap__type__descriptor;
|
||||
extern const ProtobufCMessageDescriptor dnstap__message__descriptor;
|
||||
extern const ProtobufCEnumDescriptor dnstap__message__type__descriptor;
|
||||
|
||||
PROTOBUF_C_END_DECLS
|
||||
|
||||
|
||||
#endif /* PROTOBUF_dnstap_2fdnstap_2eproto__INCLUDED */
|
99
external/unbound/doc/Changelog
vendored
99
external/unbound/doc/Changelog
vendored
@ -1,3 +1,102 @@
|
||||
1 December 2014: Wouter
|
||||
- Fix bug#632: unbound fails to build on AArch64, protects
|
||||
getentropy compat code from calling sysctl if it is has been removed.
|
||||
|
||||
29 November 2014: Wouter
|
||||
- Add include to getentropy_linux.c, hopefully fixing debian build.
|
||||
|
||||
28 November 2014: Wouter
|
||||
- Fix makefile for build from noexec source tree.
|
||||
|
||||
26 November 2014: Wouter
|
||||
- Fix libunbound undefined symbol errors for main.
|
||||
Referencing main does not seem to be possible for libunbound.
|
||||
|
||||
24 November 2014: Wouter
|
||||
- Fix log at high verbosity and memory allocation failure.
|
||||
- iana portlist update.
|
||||
|
||||
21 November 2014: Wouter
|
||||
- Fix crash on multiple thread random usage on systems without
|
||||
arc4random.
|
||||
|
||||
20 November 2014: Wouter
|
||||
- fix compat/getentropy_win.c check if CryptGenRandom works and no
|
||||
immediate exit on windows.
|
||||
|
||||
19 November 2014: Wouter
|
||||
- Fix cdflag dns64 processing.
|
||||
|
||||
18 November 2014: Wouter
|
||||
- Fix that CD flag disables DNS64 processing, returning the DNSSEC
|
||||
signed AAAA denial.
|
||||
- iana portlist update.
|
||||
|
||||
17 November 2014: Wouter
|
||||
- Fix #627: SSL_CTX_load_verify_locations return code not properly
|
||||
checked.
|
||||
|
||||
14 November 2014: Wouter
|
||||
- parser with bison 2.7
|
||||
|
||||
13 November 2014: Wouter
|
||||
- Patch from Stephane Lapie for ASAHI Net that implements aaaa-filter,
|
||||
added to contrib/aaaa-filter-iterator.patch.
|
||||
|
||||
12 November 2014: Wouter
|
||||
- trunk has 1.5.1 in development.
|
||||
- Patch from Robert Edmonds to build pyunbound python module
|
||||
differently. No versioninfo, with -shared and without $(LIBS).
|
||||
- Patch from Robert Edmonds fixes hyphens in unbound-anchor man page.
|
||||
- Removed 'increased limit open files' log message that is written
|
||||
to console. It is only written on verbosity 4 and higher.
|
||||
This keeps system bootup console cleaner.
|
||||
- Patch from James Raftery, always print stats for rcodes 0..5.
|
||||
|
||||
11 November 2014: Wouter
|
||||
- iana portlist update.
|
||||
- Fix bug where forward or stub addresses with same address but
|
||||
different port number were not tried.
|
||||
- version number in svn trunk is 1.5.0
|
||||
- tag 1.5.0rc1
|
||||
- review fix from Ralph.
|
||||
|
||||
7 November 2014: Wouter
|
||||
- dnstap fixes by Robert Edmonds:
|
||||
dnstap/dnstap.m4: cosmetic fixes
|
||||
dnstap/: Remove compiled protoc-c output files
|
||||
dnstap/dnstap.m4: Error out if required libraries are not found
|
||||
dnstap: Fix ProtobufCBufferSimple usage that is incorrect as of
|
||||
protobuf-c 1.0.0
|
||||
dnstap/: Adapt to API changes in latest libfstrm (>= 0.2.0)
|
||||
|
||||
4 November 2014: Wouter
|
||||
- Add ub_ctx_add_ta_autr function to add a RFC5011 automatically
|
||||
tracked trust anchor to libunbound.
|
||||
- Redefine internal minievent symbols to unique symbols that helps
|
||||
linking on platforms where the linker leaks names across modules.
|
||||
|
||||
27 October 2014: Wouter
|
||||
- Disabled use of SSLv3 in remote-control and ssl-upstream.
|
||||
- iana portlist update.
|
||||
|
||||
16 October 2014: Wouter
|
||||
- Documented dns64 configuration in unbound.conf man page.
|
||||
|
||||
13 October 2014: Wouter
|
||||
- Fix #617: in ldns in unbound, lowercase WKS services.
|
||||
- Fix ctype invocation casts.
|
||||
|
||||
10 October 2014: Wouter
|
||||
- Fix unbound-checkconf check for module config with dns64 module.
|
||||
- Fix unbound capsforid fallback, it ignores TTLs in comparison.
|
||||
|
||||
6 October 2014: Wouter
|
||||
- Fix #614: man page variable substitution bug.
|
||||
6 October 2014: Willem
|
||||
- Whitespaces after $ORIGIN are not part of the origin dname (ldns).
|
||||
- $TTL's value starts at position 5 (ldns).
|
||||
|
||||
1 October 2014: Wouter
|
||||
- fix #613: Allow tab ws in var length last rdfs (in ldns str2wire).
|
||||
|
||||
|
BIN
external/unbound/doc/ietf67-design-02.odp
vendored
BIN
external/unbound/doc/ietf67-design-02.odp
vendored
Binary file not shown.
13
external/unbound/doc/libunbound.3.in
vendored
13
external/unbound/doc/libunbound.3.in
vendored
@ -22,6 +22,7 @@
|
||||
.B ub_ctx_resolvconf,
|
||||
.B ub_ctx_hosts,
|
||||
.B ub_ctx_add_ta,
|
||||
.B ub_ctx_add_ta_autr,
|
||||
.B ub_ctx_add_ta_file,
|
||||
.B ub_ctx_trustedkeys,
|
||||
.B ub_ctx_debugout,
|
||||
@ -73,6 +74,9 @@
|
||||
\fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_add_ta_autr\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
@ -231,6 +235,15 @@ first resolve is done.
|
||||
The format is a string, similar to the zone\-file format,
|
||||
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
|
||||
.TP
|
||||
.B ub_ctx_add_ta_autr
|
||||
Add filename with automatically tracked trust anchor to the given context.
|
||||
Pass name of a file with the managed trust anchor. You can create this
|
||||
file with \fIunbound\-anchor\fR(8) for the root anchor. You can also
|
||||
create it with an initial file with one line with a DNSKEY or DS record.
|
||||
If the file is writable, it is updated when the trust anchor changes.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_add_ta_file
|
||||
Add trust anchors to the given context.
|
||||
Pass name of a file with DS and DNSKEY records in zone file format.
|
||||
|
6
external/unbound/doc/unbound-anchor.8.in
vendored
6
external/unbound/doc/unbound-anchor.8.in
vendored
@ -24,14 +24,14 @@ Suggested usage:
|
||||
.nf
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
|
||||
unbound-anchor \-a "@UNBOUND_ROOTKEY_FILE@"
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
# start validating resolver
|
||||
# the unbound.conf contains:
|
||||
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
|
||||
unbound -c unbound.conf
|
||||
unbound \-c unbound.conf
|
||||
.fi
|
||||
.P
|
||||
This tool provides builtin default contents for the root anchor and root
|
||||
@ -138,7 +138,7 @@ tracking, or if an error occurred.
|
||||
.P
|
||||
You can check the exit value in this manner:
|
||||
.nf
|
||||
unbound-anchor -a "root.key" || logger "Please check root.key"
|
||||
unbound-anchor \-a "root.key" || logger "Please check root.key"
|
||||
.fi
|
||||
Or something more suitable for your operational environment.
|
||||
.SH "TRUST"
|
||||
|
13
external/unbound/doc/unbound.conf.5.in
vendored
13
external/unbound/doc/unbound.conf.5.in
vendored
@ -1082,6 +1082,19 @@ and the word "python" has to be put in the \fBmodule\-config:\fR option
|
||||
.TP
|
||||
.B python\-script: \fI<python file>\fR
|
||||
The script file to load.
|
||||
.SS "DNS64 Module Options"
|
||||
.LP
|
||||
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
||||
validator iterator" directive and be compiled into the daemon to be
|
||||
enabled. These settings go in the \fBserver:\fR section.
|
||||
.TP
|
||||
.B dns64\-prefix: \fI<IPv6 prefix>\fR
|
||||
This sets the DNS64 prefix to use to synthesize AAAA records with.
|
||||
It must be /96 or shorter. The default prefix is 64:ff9b::/96.
|
||||
.TP
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
4
external/unbound/iterator/iter_delegpt.c
vendored
4
external/unbound/iterator/iter_delegpt.c
vendored
@ -147,7 +147,9 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
{
|
||||
struct delegpt_addr* p = dp->target_list;
|
||||
while(p) {
|
||||
if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0) {
|
||||
if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0
|
||||
&& ((struct sockaddr_in*)addr)->sin_port ==
|
||||
((struct sockaddr_in*)&p->addr)->sin_port) {
|
||||
return p;
|
||||
}
|
||||
p = p->next_target;
|
||||
|
14
external/unbound/iterator/iter_utils.c
vendored
14
external/unbound/iterator/iter_utils.c
vendored
@ -425,10 +425,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
|
||||
void
|
||||
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
||||
struct regional* region)
|
||||
struct regional* region, uint16_t flags)
|
||||
{
|
||||
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
||||
pside, region))
|
||||
pside, region, flags))
|
||||
log_err("out of memory: cannot store data in cache");
|
||||
}
|
||||
|
||||
@ -457,7 +457,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
||||
fptr_ok(fptr_whitelist_modenv_detect_cycle(
|
||||
qstate->env->detect_cycle));
|
||||
return (*qstate->env->detect_cycle)(qstate, &qinf,
|
||||
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming);
|
||||
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming,
|
||||
qstate->is_valrec);
|
||||
}
|
||||
|
||||
void
|
||||
@ -666,7 +667,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
|
||||
k1->rk.rrset_class != k2->rk.rrset_class ||
|
||||
query_dname_compare(k1->rk.dname, k2->rk.dname) != 0)
|
||||
return 0;
|
||||
if(d1->ttl != d2->ttl ||
|
||||
if( /* do not check ttl: d1->ttl != d2->ttl || */
|
||||
d1->count != d2->count ||
|
||||
d1->rrsig_count != d2->rrsig_count ||
|
||||
d1->trust != d2->trust ||
|
||||
@ -675,7 +676,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
|
||||
t = d1->count + d1->rrsig_count;
|
||||
for(i=0; i<t; i++) {
|
||||
if(d1->rr_len[i] != d2->rr_len[i] ||
|
||||
d1->rr_ttl[i] != d2->rr_ttl[i] ||
|
||||
/* no ttl check: d1->rr_ttl[i] != d2->rr_ttl[i] ||*/
|
||||
memcmp(d1->rr_data[i], d2->rr_data[i],
|
||||
d1->rr_len[i]) != 0)
|
||||
return 0;
|
||||
@ -689,8 +690,11 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
|
||||
size_t i;
|
||||
if(p->flags != q->flags ||
|
||||
p->qdcount != q->qdcount ||
|
||||
/* do not check TTL, this may differ */
|
||||
/*
|
||||
p->ttl != q->ttl ||
|
||||
p->prefetch_ttl != q->prefetch_ttl ||
|
||||
*/
|
||||
p->security != q->security ||
|
||||
p->an_numrrsets != q->an_numrrsets ||
|
||||
p->ns_numrrsets != q->ns_numrrsets ||
|
||||
|
3
external/unbound/iterator/iter_utils.h
vendored
3
external/unbound/iterator/iter_utils.h
vendored
@ -124,6 +124,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||
* @param pside: true if dp is parentside, thus message is 'fresh' and NS
|
||||
* can be prefetch-updates.
|
||||
* @param region: to copy modified (cache is better) rrs back to.
|
||||
* @param flags: with BIT_CD for dns64 AAAA translated queries.
|
||||
* @return void, because we are not interested in alloc errors,
|
||||
* the iterator and validator can operate on the results in their
|
||||
* scratch space (the qstate.region) and are not dependent on the cache.
|
||||
@ -132,7 +133,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||
*/
|
||||
void iter_dns_store(struct module_env* env, struct query_info* qinf,
|
||||
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
||||
struct regional* region);
|
||||
struct regional* region, uint16_t flags);
|
||||
|
||||
/**
|
||||
* Select randomly with n/m probability.
|
||||
|
27
external/unbound/iterator/iterator.c
vendored
27
external/unbound/iterator/iterator.c
vendored
@ -257,7 +257,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
verbose(VERB_ALGO, "error response for prefetch in cache");
|
||||
/* attempt to adjust the cache entry prefetch */
|
||||
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
|
||||
NORR_TTL))
|
||||
NORR_TTL, qstate->query_flags))
|
||||
return error_response(qstate, id, rcode);
|
||||
/* if that fails (not in cache), fall through to store err */
|
||||
}
|
||||
@ -270,7 +270,8 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL);
|
||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
|
||||
qstate->query_flags);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
|
||||
@ -486,6 +487,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
|
||||
struct query_info qinf;
|
||||
int prime = (finalstate == PRIME_RESP_STATE)?1:0;
|
||||
int valrec = 0;
|
||||
qinf.qname = qname;
|
||||
qinf.qname_len = qnamelen;
|
||||
qinf.qtype = qtype;
|
||||
@ -499,12 +501,15 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
* the resolution chain, which might have a validator. We are
|
||||
* uninterested in validating things not on the direct resolution
|
||||
* path. */
|
||||
if(!v)
|
||||
if(!v) {
|
||||
qflags |= BIT_CD;
|
||||
valrec = 1;
|
||||
}
|
||||
|
||||
/* attach subquery, lookup existing or make a new one */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) {
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
|
||||
&subq)) {
|
||||
return 0;
|
||||
}
|
||||
*subq_ret = subq;
|
||||
@ -938,7 +943,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
} else {
|
||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->region, qstate->env->scratch);
|
||||
iq->qchase.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
@ -1991,7 +1997,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS,
|
||||
qstate->region);
|
||||
qstate->region, qstate->query_flags);
|
||||
/* close down outstanding requests to be discarded */
|
||||
outbound_list_clear(&iq->outlist);
|
||||
iq->num_current_queries = 0;
|
||||
@ -2029,7 +2035,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Store the referral under the current query */
|
||||
/* no prefetch-leeway, since its not the answer */
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, 0, 0, NULL);
|
||||
iq->response->rep, 1, 0, 0, NULL, 0);
|
||||
if(iq->store_parent_NS)
|
||||
iter_store_parentside_NS(qstate->env,
|
||||
iq->response->rep);
|
||||
@ -2128,7 +2134,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* prefetchleeway applied because this updates answer parts */
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS, NULL);
|
||||
iq->dp&&iq->dp->has_parent_side_NS, NULL,
|
||||
qstate->query_flags);
|
||||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
@ -2209,7 +2216,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
|
||||
/**
|
||||
* Return priming query results to interestes super querystates.
|
||||
* Return priming query results to interested super querystates.
|
||||
*
|
||||
* Sets the delegation point and delegation message (not nonRD queries).
|
||||
* This is a callback from walk_supers.
|
||||
@ -2640,7 +2647,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iter_dns_store(qstate->env, &qstate->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS,
|
||||
qstate->region);
|
||||
qstate->region, qstate->query_flags);
|
||||
}
|
||||
}
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
|
6
external/unbound/ldns/keyraw.c
vendored
6
external/unbound/ldns/keyraw.c
vendored
@ -324,8 +324,10 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
|
||||
ec = EC_KEY_new_by_curve_name(NID_secp384r1);
|
||||
} else ec = NULL;
|
||||
if(!ec) return NULL;
|
||||
if(keylen+1 > sizeof(buf))
|
||||
return NULL; /* sanity check */
|
||||
if(keylen+1 > sizeof(buf)) { /* sanity check */
|
||||
EC_KEY_free(ec);
|
||||
return NULL;
|
||||
}
|
||||
/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
|
||||
* of openssl) for uncompressed data */
|
||||
buf[0] = POINT_CONVERSION_UNCOMPRESSED;
|
||||
|
12
external/unbound/ldns/parseutil.c
vendored
12
external/unbound/ldns/parseutil.c
vendored
@ -288,9 +288,9 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
if ((*str_p)[0] && isdigit((*str_p)[0]) &&
|
||||
(*str_p)[1] && isdigit((*str_p)[1]) &&
|
||||
(*str_p)[2] && isdigit((*str_p)[2])) {
|
||||
if ((*str_p)[0] && isdigit((unsigned char)(*str_p)[0]) &&
|
||||
(*str_p)[1] && isdigit((unsigned char)(*str_p)[1]) &&
|
||||
(*str_p)[2] && isdigit((unsigned char)(*str_p)[2])) {
|
||||
|
||||
val = (uint16_t)(((*str_p)[0] - '0') * 100 +
|
||||
((*str_p)[1] - '0') * 10 +
|
||||
@ -303,7 +303,7 @@ sldns_parse_escape(uint8_t *ch_p, const char** str_p)
|
||||
*str_p += 3;
|
||||
return 1;
|
||||
|
||||
} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
|
||||
} else if ((*str_p)[0] && !isdigit((unsigned char)(*str_p)[0])) {
|
||||
|
||||
*ch_p = (uint8_t)*(*str_p)++;
|
||||
return 1;
|
||||
@ -467,7 +467,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||
ch = *src++;
|
||||
--src_sz;
|
||||
|
||||
} while (isspace(ch) && src_sz > 0);
|
||||
} while (isspace((unsigned char)ch) && src_sz > 0);
|
||||
|
||||
if (ch == '=' || ch == '\0')
|
||||
break;
|
||||
@ -572,7 +572,7 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||
ch = *src++;
|
||||
src_sz--;
|
||||
|
||||
} while (isspace(ch));
|
||||
} while (isspace((unsigned char)ch));
|
||||
|
||||
if (ch != '=')
|
||||
return -1;
|
||||
|
8
external/unbound/ldns/sbuffer.h
vendored
8
external/unbound/ldns/sbuffer.h
vendored
@ -35,9 +35,9 @@ INLINE uint16_t
|
||||
sldns_read_uint16(const void *src)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
return ntohs(*(uint16_t *) src);
|
||||
return ntohs(*(const uint16_t *) src);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) src;
|
||||
const uint8_t *p = (const uint8_t *) src;
|
||||
return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
|
||||
#endif
|
||||
}
|
||||
@ -46,9 +46,9 @@ INLINE uint32_t
|
||||
sldns_read_uint32(const void *src)
|
||||
{
|
||||
#ifdef ALLOW_UNALIGNED_ACCESSES
|
||||
return ntohl(*(uint32_t *) src);
|
||||
return ntohl(*(const uint32_t *) src);
|
||||
#else
|
||||
uint8_t *p = (uint8_t *) src;
|
||||
const uint8_t *p = (const uint8_t *) src;
|
||||
return ( ((uint32_t) p[0] << 24)
|
||||
| ((uint32_t) p[1] << 16)
|
||||
| ((uint32_t) p[2] << 8)
|
||||
|
94
external/unbound/ldns/str2wire.c
vendored
94
external/unbound/ldns/str2wire.c
vendored
@ -245,7 +245,7 @@ rrinternal_get_ttl(sldns_buffer* strbuf, char* token, size_t token_len,
|
||||
}
|
||||
*ttl = (uint32_t) sldns_str2period(token, &endptr);
|
||||
|
||||
if (strlen(token) > 0 && !isdigit((int)token[0])) {
|
||||
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
|
||||
*not_there = 1;
|
||||
/* ah, it's not there or something */
|
||||
if (default_ttl == 0) {
|
||||
@ -384,11 +384,11 @@ rrinternal_spool_hex(char* token, uint8_t* rr, size_t rr_len,
|
||||
{
|
||||
char* p = token;
|
||||
while(*p) {
|
||||
if(isspace(*p)) {
|
||||
if(isspace((unsigned char)*p)) {
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
if(!isxdigit(*p))
|
||||
if(!isxdigit((unsigned char)*p))
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_RDATA,
|
||||
p-token);
|
||||
if(*cur_hex_data_size >= hex_data_size)
|
||||
@ -827,6 +827,20 @@ const char* sldns_get_errorstr_parse(int e)
|
||||
return lt?lt->name:"unknown error";
|
||||
}
|
||||
|
||||
/* Strip whitespace from the start and the end of <line>. */
|
||||
static char *
|
||||
sldns_strip_ws(char *line)
|
||||
{
|
||||
char *s = line, *e;
|
||||
|
||||
for (s = line; *s && isspace((unsigned char)*s); s++)
|
||||
;
|
||||
for (e = strchr(s, 0); e > s+2 && isspace((unsigned char)e[-1]) && e[-2] != '\\'; e--)
|
||||
;
|
||||
*e = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||
struct sldns_file_parse_state* parse_state)
|
||||
{
|
||||
@ -852,28 +866,23 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
if(strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
|
||||
size_t off = 8;
|
||||
if(strncmp(line, "$ORIGIN", 7) == 0 && isspace((unsigned char)line[7])) {
|
||||
int s;
|
||||
*len = 0;
|
||||
*dname_len = 0;
|
||||
if(!parse_state) return LDNS_WIREPARSE_ERR_OK;
|
||||
while(isspace(line[off]))
|
||||
off++;
|
||||
parse_state->origin_len = sizeof(parse_state->origin);
|
||||
s = sldns_str2wire_dname_buf(line+off, parse_state->origin,
|
||||
&parse_state->origin_len);
|
||||
s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
|
||||
parse_state->origin, &parse_state->origin_len);
|
||||
if(s) parse_state->origin_len = 0;
|
||||
return s;
|
||||
} else if(strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
|
||||
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
|
||||
const char* end = NULL;
|
||||
size_t off = 8;
|
||||
*len = 0;
|
||||
*dname_len = 0;
|
||||
if(!parse_state) return LDNS_WIREPARSE_ERR_OK;
|
||||
while(isspace(line[off]))
|
||||
off++;
|
||||
parse_state->default_ttl = sldns_str2period(line+off, &end);
|
||||
parse_state->default_ttl = sldns_str2period(
|
||||
sldns_strip_ws(line+5), &end);
|
||||
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
|
||||
*len = 0;
|
||||
*dname_len = 0;
|
||||
@ -1188,11 +1197,11 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
const char* s = str;
|
||||
size_t dlen = 0; /* number of hexdigits parsed */
|
||||
while(*s) {
|
||||
if(isspace(*s)) {
|
||||
if(isspace((unsigned char)*s)) {
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(!isxdigit(*s))
|
||||
if(!isxdigit((unsigned char)*s))
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
|
||||
if(*len < dlen/2 + 1)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
|
||||
@ -1392,7 +1401,7 @@ static int
|
||||
loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
|
||||
{
|
||||
uint32_t meters = 0, cm = 0, val;
|
||||
while (isblank(*my_str)) {
|
||||
while (isblank((unsigned char)*my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
meters = (uint32_t)strtol(my_str, &my_str, 10);
|
||||
@ -1443,17 +1452,17 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
|
||||
char *my_str = (char *) str;
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
h = (uint32_t) strtol(my_str, &my_str, 10);
|
||||
} else {
|
||||
return LDNS_WIREPARSE_ERR_INVALID_STR;
|
||||
}
|
||||
|
||||
while (isblank((int) *my_str)) {
|
||||
while (isblank((unsigned char) *my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
m = (uint32_t) strtol(my_str, &my_str, 10);
|
||||
} else if (*my_str == 'N' || *my_str == 'S') {
|
||||
goto north;
|
||||
@ -1461,16 +1470,16 @@ int sldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_INVALID_STR;
|
||||
}
|
||||
|
||||
while (isblank((int) *my_str)) {
|
||||
while (isblank((unsigned char) *my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
s = strtod(my_str, &my_str);
|
||||
}
|
||||
|
||||
/* skip blanks before norterness */
|
||||
while (isblank((int) *my_str)) {
|
||||
while (isblank((unsigned char) *my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
@ -1497,21 +1506,21 @@ north:
|
||||
} else {
|
||||
latitude = equator - latitude;
|
||||
}
|
||||
while (isblank(*my_str)) {
|
||||
while (isblank((unsigned char)*my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
h = (uint32_t) strtol(my_str, &my_str, 10);
|
||||
} else {
|
||||
return LDNS_WIREPARSE_ERR_INVALID_STR;
|
||||
}
|
||||
|
||||
while (isblank((int) *my_str)) {
|
||||
while (isblank((unsigned char) *my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
m = (uint32_t) strtol(my_str, &my_str, 10);
|
||||
} else if (*my_str == 'E' || *my_str == 'W') {
|
||||
goto east;
|
||||
@ -1519,16 +1528,16 @@ north:
|
||||
return LDNS_WIREPARSE_ERR_INVALID_STR;
|
||||
}
|
||||
|
||||
while (isblank(*my_str)) {
|
||||
while (isblank((unsigned char)*my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
if (isdigit((int) *my_str)) {
|
||||
if (isdigit((unsigned char) *my_str)) {
|
||||
s = strtod(my_str, &my_str);
|
||||
}
|
||||
|
||||
/* skip blanks before easterness */
|
||||
while (isblank(*my_str)) {
|
||||
while (isblank((unsigned char)*my_str)) {
|
||||
my_str++;
|
||||
}
|
||||
|
||||
@ -1591,6 +1600,17 @@ east:
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ldns_tolower_str(char* s)
|
||||
{
|
||||
if(s) {
|
||||
while(*s) {
|
||||
*s = (char)tolower((unsigned char)*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
int rd_len = 1;
|
||||
@ -1605,6 +1625,7 @@ int sldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
|
||||
while(sldns_bget_token(&strbuf, token, "\t\n ", sizeof(token)) > 0) {
|
||||
ldns_tolower_str(token);
|
||||
if(!have_proto) {
|
||||
struct protoent *p = getprotobyname(token);
|
||||
have_proto = 1;
|
||||
@ -1682,11 +1703,11 @@ int sldns_str2wire_nsap_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
if(slen > LDNS_MAX_RDFLEN*2)
|
||||
return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW;
|
||||
while(*s) {
|
||||
if(isspace(*s) || *s == '.') {
|
||||
if(isspace((unsigned char)*s) || *s == '.') {
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(!isxdigit(*s))
|
||||
if(!isxdigit((unsigned char)*s))
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
|
||||
if(*len < dlen/2 + 1)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
|
||||
@ -1713,11 +1734,11 @@ int sldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
if(slen > LDNS_MAX_RDFLEN*2)
|
||||
return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW;
|
||||
while(*s) {
|
||||
if(isspace(*s) || *s == '.') {
|
||||
if(isspace((unsigned char)*s) || *s == '.') {
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(!isxdigit(*s))
|
||||
if(!isxdigit((unsigned char)*s))
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str);
|
||||
if(*len < dlen/2 + 1)
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
|
||||
@ -1820,7 +1841,8 @@ int sldns_str2wire_nsec3_salt_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
rd[0] = (uint8_t) (salt_length_str / 2);
|
||||
for (i = 0; i < salt_length_str; i += 2) {
|
||||
if (isxdigit((int)str[i]) && isxdigit((int)str[i+1])) {
|
||||
if (isxdigit((unsigned char)str[i]) &&
|
||||
isxdigit((unsigned char)str[i+1])) {
|
||||
rd[1+i/2] = (uint8_t)(sldns_hexdigit_to_int(str[i])*16
|
||||
+ sldns_hexdigit_to_int(str[i+1]));
|
||||
} else {
|
||||
@ -1907,7 +1929,7 @@ int sldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
if(*len < slen+1)
|
||||
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
for (ptr = str; *ptr; ptr++) {
|
||||
if(!isalnum(*ptr))
|
||||
if(!isalnum((unsigned char)*ptr))
|
||||
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_TAG, ptr-str);
|
||||
}
|
||||
rd[0] = slen;
|
||||
|
8
external/unbound/ldns/wire2str.c
vendored
8
external/unbound/ldns/wire2str.c
vendored
@ -722,7 +722,7 @@ static int dname_char_print(char** s, size_t* slen, uint8_t c)
|
||||
{
|
||||
if(c == '.' || c == ';' || c == '(' || c == ')' || c == '\\')
|
||||
return sldns_str_print(s, slen, "\\%c", c);
|
||||
else if(!(isascii((int)c) && isgraph((int)c)))
|
||||
else if(!(isascii((unsigned char)c) && isgraph((unsigned char)c)))
|
||||
return sldns_str_print(s, slen, "\\%03u", (unsigned)c);
|
||||
/* plain printout */
|
||||
if(*slen) {
|
||||
@ -1064,7 +1064,7 @@ int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||
/** printout escaped TYPE_STR character */
|
||||
static int str_char_print(char** s, size_t* sl, uint8_t c)
|
||||
{
|
||||
if(isprint((int)c) || c == '\t') {
|
||||
if(isprint((unsigned char)c) || c == '\t') {
|
||||
if(c == '\"' || c == '\\')
|
||||
return sldns_str_print(s, sl, "\\%c", c);
|
||||
if(*sl) {
|
||||
@ -1625,7 +1625,7 @@ int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl)
|
||||
if(*dl < 1+n)
|
||||
return -1;
|
||||
for(i=0; i<n; i++)
|
||||
if(!isalnum((int)(*d)[i]))
|
||||
if(!isalnum((unsigned char)(*d)[i]))
|
||||
return -1;
|
||||
for(i=0; i<n; i++)
|
||||
w += sldns_str_print(s, sl, "%c", (char)(*d)[i]);
|
||||
@ -1713,7 +1713,7 @@ int sldns_wire2str_edns_nsid_print(char** s, size_t* sl, uint8_t* data,
|
||||
size_t i, printed=0;
|
||||
w += print_hex_buf(s, sl, data, len);
|
||||
for(i=0; i<len; i++) {
|
||||
if(isprint((int)data[i]) || data[i] == '\t') {
|
||||
if(isprint((unsigned char)data[i]) || data[i] == '\t') {
|
||||
if(!printed) {
|
||||
w += sldns_str_print(s, sl, " (");
|
||||
printed = 1;
|
||||
|
24
external/unbound/libunbound/libunbound.c
vendored
24
external/unbound/libunbound/libunbound.c
vendored
@ -363,6 +363,26 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
|
||||
{
|
||||
char* dup = strdup(fname);
|
||||
if(!dup) return UB_NOMEM;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
|
||||
dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int
|
||||
ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
|
||||
{
|
||||
@ -959,7 +979,7 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname)
|
||||
parse++;
|
||||
addr = parse;
|
||||
/* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */
|
||||
while(isxdigit(*parse) || *parse=='.' || *parse==':')
|
||||
while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':')
|
||||
parse++;
|
||||
/* terminate after the address, remove newline */
|
||||
*parse = 0;
|
||||
@ -1031,7 +1051,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
|
||||
/* format: <addr> spaces <name> spaces <name> ... */
|
||||
addr = parse;
|
||||
/* skip addr */
|
||||
while(isxdigit(*parse) || *parse == '.' || *parse == ':')
|
||||
while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':')
|
||||
parse++;
|
||||
if(*parse == '\n' || *parse == 0)
|
||||
continue;
|
||||
|
1
external/unbound/libunbound/ubsyms.def
vendored
1
external/unbound/libunbound/ubsyms.def
vendored
@ -8,6 +8,7 @@ ub_ctx_set_fwd
|
||||
ub_ctx_resolvconf
|
||||
ub_ctx_hosts
|
||||
ub_ctx_add_ta
|
||||
ub_ctx_add_ta_autr
|
||||
ub_ctx_add_ta_file
|
||||
ub_ctx_trustedkeys
|
||||
ub_ctx_debugout
|
||||
|
17
external/unbound/libunbound/unbound.h
vendored
17
external/unbound/libunbound/unbound.h
vendored
@ -356,6 +356,21 @@ int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta);
|
||||
*/
|
||||
int ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname);
|
||||
|
||||
/**
|
||||
* Add trust anchor to the given context that is tracked with RFC5011
|
||||
* automated trust anchor maintenance. The file is written to when the
|
||||
* trust anchor is changed.
|
||||
* Pass the name of a file that was output from eg. unbound-anchor,
|
||||
* or you can start it by providing a trusted DNSKEY or DS record on one
|
||||
* line in the file.
|
||||
* @param ctx: context.
|
||||
* At this time it is only possible to add trusted keys before the
|
||||
* first resolve is done.
|
||||
* @param fname: filename of file with trust anchor.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname);
|
||||
|
||||
/**
|
||||
* Add trust anchors to the given context.
|
||||
* Pass the name of a bind-style config file with trusted-keys{}.
|
||||
@ -508,7 +523,7 @@ void ub_resolve_free(struct ub_result* result);
|
||||
|
||||
/**
|
||||
* Convert error value to a human readable string.
|
||||
* @param err: error code from one of the ub_val* functions.
|
||||
* @param err: error code from one of the libunbound functions.
|
||||
* @return pointer to constant text string, zero terminated.
|
||||
*/
|
||||
const char* ub_strerror(int err);
|
||||
|
3
external/unbound/monero-config.sh
vendored
3
external/unbound/monero-config.sh
vendored
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./configure --prefix=${CMAKE_FIND_ROOT_PATH} --build=${GCC_PREFIX} --host=${GCC_PREFIX} --disable-shared --enable-static --sysconfdir=${CMAKE_FIND_ROOT_PATH}/etc --localstatedir=${CMAKE_FIND_ROOT_PATH}/var --sbindir=${CMAKE_FIND_ROOT_PATH}/bin --disable-gost --disable-rpath --with-libevent=no --with-libexpat=${CMAKE_FIND_ROOT_PATH} --without-pyunbound --without-pythonmodule --with-ssl=${CMAKE_FIND_ROOT_PATH} --without-pthreads --with-libunbound-only
|
4
external/unbound/pythonmod/pythonmod_utils.c
vendored
4
external/unbound/pythonmod/pythonmod_utils.c
vendored
@ -67,7 +67,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
|
||||
}
|
||||
|
||||
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
|
||||
qstate->prefetch_leeway, 0, NULL);
|
||||
qstate->prefetch_leeway, 0, NULL, qstate->query_flags);
|
||||
}
|
||||
|
||||
/* Invalidate the message associated with query_info stored in message cache */
|
||||
@ -78,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin
|
||||
struct reply_info *r;
|
||||
size_t i, j;
|
||||
|
||||
h = query_info_hash(qinfo);
|
||||
h = query_info_hash(qinfo, qstate->query_flags);
|
||||
if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))
|
||||
{
|
||||
r = (struct reply_info*)(e->data);
|
||||
|
34
external/unbound/services/cache/dns.c
vendored
34
external/unbound/services/cache/dns.c
vendored
@ -184,7 +184,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
/** lookup message in message cache */
|
||||
static struct msgreply_entry*
|
||||
msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, time_t now, int wr)
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info k;
|
||||
@ -194,7 +194,7 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
h = query_info_hash(&k);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, wr);
|
||||
|
||||
if(!e) return NULL;
|
||||
@ -226,8 +226,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||
addr_to_additional(akey, region, *msg, now);
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
} else {
|
||||
/* BIT_CD on false because delegpt lookup does
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_A, qclass, now, 0);
|
||||
LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
@ -244,8 +246,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||
addr_to_additional(akey, region, *msg, now);
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
} else {
|
||||
/* BIT_CD on false because delegpt lookup does
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, now, 0);
|
||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
@ -276,8 +280,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||
ns->name, LDNS_RR_TYPE_A, qclass);
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
} else {
|
||||
/* BIT_CD on false because delegpt lookup does
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_A, qclass, now, 0);
|
||||
LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
@ -294,8 +300,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||
ns->name, LDNS_RR_TYPE_AAAA, qclass);
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
} else {
|
||||
/* BIT_CD on false because delegpt lookup does
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, now, 0);
|
||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
@ -626,7 +634,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
struct dns_msg*
|
||||
dns_cache_lookup(struct module_env* env,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
struct regional* region, struct regional* scratch)
|
||||
uint16_t flags, struct regional* region, struct regional* scratch)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info k;
|
||||
@ -639,7 +647,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
h = query_info_hash(&k);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(e) {
|
||||
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
|
||||
@ -716,7 +724,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
if(env->cfg->harden_below_nxdomain)
|
||||
while(!dname_is_root(k.qname)) {
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(e) {
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
@ -741,7 +749,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
int
|
||||
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
||||
struct regional* region)
|
||||
struct regional* region, uint16_t flags)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
/* alloc, malloc properly (not in region, like msg is) */
|
||||
@ -786,7 +794,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
* Not AA from cache. Not CD in cache (depends on client bit). */
|
||||
rep->flags |= (BIT_RA | BIT_QR);
|
||||
rep->flags &= ~(BIT_AA | BIT_CD);
|
||||
h = query_info_hash(&qinf);
|
||||
h = query_info_hash(&qinf, flags);
|
||||
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
|
||||
region);
|
||||
/* qname is used inside query_info_entrysetup, and set to
|
||||
@ -798,11 +806,11 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
|
||||
int
|
||||
dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
||||
time_t adjust)
|
||||
time_t adjust, uint16_t flags)
|
||||
{
|
||||
struct msgreply_entry* msg;
|
||||
msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, *env->now, 1);
|
||||
qinfo->qtype, qinfo->qclass, flags, *env->now, 1);
|
||||
if(msg) {
|
||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||
if(rep) {
|
||||
|
9
external/unbound/services/cache/dns.h
vendored
9
external/unbound/services/cache/dns.h
vendored
@ -79,11 +79,12 @@ struct dns_msg {
|
||||
* can be updated to full TTL even in prefetch situations.
|
||||
* @param region: region to allocate better entries from cache into.
|
||||
* (used when is_referral is false).
|
||||
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||
* @return 0 on alloc error (out of memory).
|
||||
*/
|
||||
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
||||
struct regional* region);
|
||||
struct regional* region, uint16_t flags);
|
||||
|
||||
/**
|
||||
* Store message in the cache. Stores in message cache and rrset cache.
|
||||
@ -132,6 +133,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
|
||||
* @param qnamelen: length of qname.
|
||||
* @param qtype: query type.
|
||||
* @param qclass: query class.
|
||||
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||
* @param region: where to allocate result.
|
||||
* @param scratch: where to allocate temporary data.
|
||||
* @return new response message (alloced in region, rrsets do not have IDs).
|
||||
@ -140,7 +142,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
|
||||
*/
|
||||
struct dns_msg* dns_cache_lookup(struct module_env* env,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
struct regional* region, struct regional* scratch);
|
||||
uint16_t flags, struct regional* region, struct regional* scratch);
|
||||
|
||||
/**
|
||||
* find and add A and AAAA records for missing nameservers in delegpt
|
||||
@ -186,9 +188,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
* @param env: module environment with caches and time.
|
||||
* @param qinfo: query info for the query that needs adjustment.
|
||||
* @param adjust: time in seconds to add to the prefetch_leeway.
|
||||
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||
* @return false if not in cache. true if added.
|
||||
*/
|
||||
int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
||||
time_t adjust);
|
||||
time_t adjust, uint16_t flags);
|
||||
|
||||
#endif /* SERVICES_CACHE_DNS_H */
|
||||
|
43
external/unbound/services/mesh.c
vendored
43
external/unbound/services/mesh.c
vendored
@ -132,6 +132,11 @@ mesh_state_compare(const void* ap, const void* bp)
|
||||
if(!a->s.is_priming && b->s.is_priming)
|
||||
return 1;
|
||||
|
||||
if(a->s.is_valrec && !b->s.is_valrec)
|
||||
return -1;
|
||||
if(!a->s.is_valrec && b->s.is_valrec)
|
||||
return 1;
|
||||
|
||||
if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD))
|
||||
return -1;
|
||||
if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
|
||||
@ -277,11 +282,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||
uint16_t qid)
|
||||
{
|
||||
/* do not use CD flag from user for mesh state, we want the CD-query
|
||||
* to receive validation anyway, to protect out cache contents and
|
||||
* avoid bad-data in this cache that a downstream validator cannot
|
||||
* remove from this cache */
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@ -311,7 +312,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
@ -375,7 +376,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@ -386,7 +387,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@ -428,7 +429,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
@ -447,7 +448,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@ -496,7 +497,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime)
|
||||
uint16_t qflags, int prime, int valrec)
|
||||
{
|
||||
struct regional* region = alloc_reg_obtain(env->alloc);
|
||||
struct mesh_state* mstate;
|
||||
@ -533,6 +534,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
/* remove all weird bits from qflags */
|
||||
mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
|
||||
mstate->s.is_priming = prime;
|
||||
mstate->s.is_valrec = valrec;
|
||||
mstate->s.reply = NULL;
|
||||
mstate->s.region = region;
|
||||
mstate->s.curmod = 0;
|
||||
@ -679,11 +681,12 @@ void mesh_detach_subs(struct module_qstate* qstate)
|
||||
}
|
||||
|
||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, struct module_qstate** newq)
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
|
||||
{
|
||||
/* find it, if not, create it */
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime);
|
||||
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime,
|
||||
valrec);
|
||||
int was_detached;
|
||||
if(mesh_detect_cycle_found(qstate, sub)) {
|
||||
verbose(VERB_ALGO, "attach failed, cycle detected");
|
||||
@ -694,7 +697,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
struct rbnode_t* n;
|
||||
#endif
|
||||
/* create a new one */
|
||||
sub = mesh_state_create(qstate->env, qinfo, qflags, prime);
|
||||
sub = mesh_state_create(qstate->env, qinfo, qflags, prime,
|
||||
valrec);
|
||||
if(!sub) {
|
||||
log_err("mesh_attach_sub: out of memory");
|
||||
return 0;
|
||||
@ -941,13 +945,14 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
|
||||
}
|
||||
|
||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime)
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec)
|
||||
{
|
||||
struct mesh_state key;
|
||||
struct mesh_state* result;
|
||||
|
||||
key.node.key = &key;
|
||||
key.s.is_priming = prime;
|
||||
key.s.is_valrec = valrec;
|
||||
key.s.qinfo = *qinfo;
|
||||
key.s.query_flags = qflags;
|
||||
|
||||
@ -1107,8 +1112,9 @@ mesh_log_list(struct mesh_area* mesh)
|
||||
struct mesh_state* m;
|
||||
int num = 0;
|
||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s mod%d %s%s",
|
||||
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s%s mod%d %s%s",
|
||||
num++, (m->s.is_priming)?"p":"", /* prime */
|
||||
(m->s.is_valrec)?"v":"", /* prime */
|
||||
(m->s.query_flags&BIT_RD)?"RD":"",
|
||||
(m->s.query_flags&BIT_CD)?"CD":"",
|
||||
(m->super_set.count==0)?"d":"", /* detached */
|
||||
@ -1178,10 +1184,11 @@ mesh_get_mem(struct mesh_area* mesh)
|
||||
|
||||
int
|
||||
mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t flags, int prime)
|
||||
uint16_t flags, int prime, int valrec)
|
||||
{
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime);
|
||||
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime,
|
||||
valrec);
|
||||
return mesh_detect_cycle_found(qstate, dep_m);
|
||||
}
|
||||
|
||||
|
13
external/unbound/services/mesh.h
vendored
13
external/unbound/services/mesh.h
vendored
@ -353,12 +353,13 @@ void mesh_detach_subs(struct module_qstate* qstate);
|
||||
* @param qinfo: what to query for (copied).
|
||||
* @param qflags: what flags to use (RD / CD flag or not).
|
||||
* @param prime: if it is a (stub) priming query.
|
||||
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||
* @param newq: If the new subquery needs initialisation, it is returned,
|
||||
* otherwise NULL is returned.
|
||||
* @return: false on error, true if success (and init may be needed).
|
||||
*/
|
||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, struct module_qstate** newq);
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
|
||||
|
||||
/**
|
||||
* Query state is done, send messages to reply entries.
|
||||
@ -406,10 +407,12 @@ void mesh_state_delete(struct module_qstate* qstate);
|
||||
* @param qinfo: query info that the mesh is for.
|
||||
* @param qflags: flags for query (RD / CD flag).
|
||||
* @param prime: if true, it is a priming query, set is_priming on mesh state.
|
||||
* @param valrec: if true, it is a validation recursion query, and sets
|
||||
* is_valrec on the mesh state.
|
||||
* @return: new mesh state or NULL on allocation error.
|
||||
*/
|
||||
struct mesh_state* mesh_state_create(struct module_env* env,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime);
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||
|
||||
/**
|
||||
* Cleanup a mesh state and its query state. Does not do rbtree or
|
||||
@ -432,10 +435,11 @@ void mesh_delete_all(struct mesh_area* mesh);
|
||||
* @param qinfo: what query
|
||||
* @param qflags: if RD / CD bit is set or not.
|
||||
* @param prime: if it is a priming query.
|
||||
* @param valrec: if it is a validation-recursion query.
|
||||
* @return: mesh state or NULL if not found.
|
||||
*/
|
||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime);
|
||||
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||
|
||||
/**
|
||||
* Setup attachment super/sub relation between super and sub mesh state.
|
||||
@ -523,13 +527,14 @@ size_t mesh_get_mem(struct mesh_area* mesh);
|
||||
* @param qinfo: query info for dependency.
|
||||
* @param flags: query flags of dependency.
|
||||
* @param prime: if dependency is a priming query or not.
|
||||
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||
* @return true if the name,type,class exists and the given qstate mesh exists
|
||||
* as a dependency of that name. Thus if qstate becomes dependent on
|
||||
* name,type,class then a cycle is created, this is return value 1.
|
||||
* Too large to search is value 2 (also true).
|
||||
*/
|
||||
int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t flags, int prime);
|
||||
uint16_t flags, int prime, int valrec);
|
||||
|
||||
/** compare two mesh_states */
|
||||
int mesh_state_compare(const void* ap, const void* bp);
|
||||
|
8
external/unbound/services/modstack.c
vendored
8
external/unbound/services/modstack.c
vendored
@ -60,12 +60,12 @@ count_modules(const char* s)
|
||||
return 0;
|
||||
while(*s) {
|
||||
/* skip whitespace */
|
||||
while(*s && isspace((int)*s))
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
if(*s && !isspace((int)*s)) {
|
||||
if(*s && !isspace((unsigned char)*s)) {
|
||||
/* skip identifier */
|
||||
num++;
|
||||
while(*s && !isspace((int)*s))
|
||||
while(*s && !isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ module_func_block* module_factory(const char** str)
|
||||
const char* s = *str;
|
||||
const char** names = module_list_avail();
|
||||
fbgetfunctype* fb = module_funcs_avail();
|
||||
while(*s && isspace((int)*s))
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
while(names[i]) {
|
||||
if(strncmp(names[i], s, strlen(names[i])) == 0) {
|
||||
|
6
external/unbound/services/outside_network.c
vendored
6
external/unbound/services/outside_network.c
vendored
@ -1334,16 +1334,16 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
|
||||
while(lablen) {
|
||||
while(lablen--) {
|
||||
/* only perturb A-Z, a-z */
|
||||
if(isalpha((int)*d)) {
|
||||
if(isalpha((unsigned char)*d)) {
|
||||
/* get a random bit */
|
||||
if(bits == 0) {
|
||||
random = ub_random(rnd);
|
||||
bits = 30;
|
||||
}
|
||||
if(random & 0x1) {
|
||||
*d = (uint8_t)toupper((int)*d);
|
||||
*d = (uint8_t)toupper((unsigned char)*d);
|
||||
} else {
|
||||
*d = (uint8_t)tolower((int)*d);
|
||||
*d = (uint8_t)tolower((unsigned char)*d);
|
||||
}
|
||||
random >>= 1;
|
||||
bits--;
|
||||
|
@ -392,10 +392,17 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 iterator") != 0
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&& strcmp(cfg->module_conf, "python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
|
||||
#endif
|
||||
) {
|
||||
fatal_exit("module conf '%s' is not known to work",
|
||||
|
2
external/unbound/smallapp/unbound-control.c
vendored
2
external/unbound/smallapp/unbound-control.c
vendored
@ -149,6 +149,8 @@ setup_ctx(struct config_file* cfg)
|
||||
ssl_err("could not allocate SSL_CTX pointer");
|
||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2))
|
||||
ssl_err("could not set SSL_OP_NO_SSLv2");
|
||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3))
|
||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||
if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) ||
|
||||
!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_check_private_key(ctx))
|
||||
|
2
external/unbound/smallapp/unbound-host.c
vendored
2
external/unbound/smallapp/unbound-host.c
vendored
@ -409,7 +409,7 @@ extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern char* optarg;
|
||||
|
||||
/** Main routine for checkconf */
|
||||
/** Main routine for unbound-host */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
|
1
external/unbound/testcode/petal.c
vendored
1
external/unbound/testcode/petal.c
vendored
@ -235,6 +235,7 @@ setup_ctx(char* key, char* cert)
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if(!ctx) print_exit("out of memory");
|
||||
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
|
||||
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
|
||||
if(!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM))
|
||||
print_exit("cannot read cert");
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
|
||||
|
6
external/unbound/testcode/readhex.c
vendored
6
external/unbound/testcode/readhex.c
vendored
@ -49,7 +49,7 @@ static void
|
||||
skip_whites(const char** p)
|
||||
{
|
||||
while(1) {
|
||||
while(isspace((int)**p))
|
||||
while(isspace((unsigned char)**p))
|
||||
(*p)++;
|
||||
if(**p == ';') {
|
||||
/* comment, skip until newline */
|
||||
@ -71,11 +71,11 @@ void hex_to_buf(sldns_buffer* pkt, const char* hex)
|
||||
skip_whites(&p);
|
||||
if(sldns_buffer_position(pkt) == sldns_buffer_limit(pkt))
|
||||
fatal_exit("hex_to_buf: buffer too small");
|
||||
if(!isalnum((int)*p))
|
||||
if(!isalnum((unsigned char)*p))
|
||||
break;
|
||||
val = sldns_hexdigit_to_int(*p++) << 4;
|
||||
skip_whites(&p);
|
||||
log_assert(*p && isalnum((int)*p));
|
||||
log_assert(*p && isalnum((unsigned char)*p));
|
||||
val |= sldns_hexdigit_to_int(*p++);
|
||||
sldns_buffer_write_u8(pkt, (uint8_t)val);
|
||||
skip_whites(&p);
|
||||
|
40
external/unbound/testcode/replay.c
vendored
40
external/unbound/testcode/replay.c
vendored
@ -130,7 +130,7 @@ strip_end_white(char* p)
|
||||
{
|
||||
size_t i;
|
||||
for(i = strlen(p); i > 0; i--) {
|
||||
if(isspace((int)p[i-1]))
|
||||
if(isspace((unsigned char)p[i-1]))
|
||||
p[i-1] = 0;
|
||||
else return;
|
||||
}
|
||||
@ -170,14 +170,14 @@ replay_range_read(char* remain, FILE* in, const char* name,
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
pstate->lineno++;
|
||||
parse = line;
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(!*parse || *parse == ';') {
|
||||
pos = ftello(in);
|
||||
continue;
|
||||
}
|
||||
if(parse_keyword(&parse, "ADDRESS")) {
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
strip_end_white(parse);
|
||||
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) {
|
||||
@ -281,7 +281,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
return NULL;
|
||||
}
|
||||
remain += skip;
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(parse_keyword(&remain, "NOTHING")) {
|
||||
mom->evt_type = repevt_nothing;
|
||||
@ -303,10 +303,10 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
mom->evt_type = repevt_timeout;
|
||||
} else if(parse_keyword(&remain, "TIME_PASSES")) {
|
||||
mom->evt_type = repevt_time_passes;
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(parse_keyword(&remain, "EVAL")) {
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
mom->string = strdup(remain);
|
||||
if(!mom->string) fatal_exit("out of memory");
|
||||
@ -316,7 +316,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
}
|
||||
} else if(parse_keyword(&remain, "CHECK_AUTOTRUST")) {
|
||||
mom->evt_type = repevt_autotrust_check;
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
|
||||
remain[strlen(remain)-1] = 0;
|
||||
@ -333,20 +333,20 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
} else if(parse_keyword(&remain, "INFRA_RTT")) {
|
||||
char *s, *m;
|
||||
mom->evt_type = repevt_infra_rtt;
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
s = remain;
|
||||
remain = strchr(s, ' ');
|
||||
if(!remain) fatal_exit("expected three args for INFRA_RTT");
|
||||
remain[0] = 0;
|
||||
remain++;
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
m = strchr(remain, ' ');
|
||||
if(!m) fatal_exit("expected three args for INFRA_RTT");
|
||||
m[0] = 0;
|
||||
m++;
|
||||
while(isspace((int)*m))
|
||||
while(isspace((unsigned char)*m))
|
||||
m++;
|
||||
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
|
||||
fatal_exit("bad infra_rtt address %s", s);
|
||||
@ -361,10 +361,10 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(parse_keyword(&remain, "ADDRESS")) {
|
||||
while(isspace((int)*remain))
|
||||
while(isspace((unsigned char)*remain))
|
||||
remain++;
|
||||
if(strlen(remain) > 0) /* remove \n */
|
||||
remain[strlen(remain)-1] = 0;
|
||||
@ -408,7 +408,7 @@ static struct replay_scenario*
|
||||
make_scenario(char* line)
|
||||
{
|
||||
struct replay_scenario* scen;
|
||||
while(isspace((int)*line))
|
||||
while(isspace((unsigned char)*line))
|
||||
line++;
|
||||
if(!*line) {
|
||||
log_err("scenario: no title given");
|
||||
@ -442,7 +442,7 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
|
||||
parse=line;
|
||||
pstate.lineno++;
|
||||
(*lineno)++;
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(!*parse)
|
||||
continue; /* empty line */
|
||||
@ -651,7 +651,7 @@ do_macro_variable(rbtree_t* store, char* buf, size_t remain)
|
||||
char sv;
|
||||
if(at[0]==0)
|
||||
return NULL; /* no variable name after $ */
|
||||
while(*at && (isalnum((int)*at) || *at=='_')) {
|
||||
while(*at && (isalnum((unsigned char)*at) || *at=='_')) {
|
||||
at++;
|
||||
}
|
||||
/* terminator, we are working in macro_expand() buffer */
|
||||
@ -724,7 +724,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart)
|
||||
/* remember start pos of expr, skip the first number */
|
||||
at = orig;
|
||||
*arithstart = at;
|
||||
while(*at && (isdigit((int)*at) || *at == '.'))
|
||||
while(*at && (isdigit((unsigned char)*at) || *at == '.'))
|
||||
at++;
|
||||
return at;
|
||||
}
|
||||
@ -737,7 +737,7 @@ do_macro_arith(char* orig, size_t remain, char** arithstart)
|
||||
*arithstart = NULL;
|
||||
return do_macro_arith(orig, remain, arithstart);
|
||||
}
|
||||
if(isdigit((int)operator)) {
|
||||
if(isdigit((unsigned char)operator)) {
|
||||
*arithstart = orig;
|
||||
return at+skip; /* do nothing, but setup for later number */
|
||||
}
|
||||
@ -820,13 +820,13 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text)
|
||||
at = do_macro_recursion(store, runtime, at, remain);
|
||||
} else if(*at == '$') {
|
||||
at = do_macro_variable(store, at, remain);
|
||||
} else if(isdigit((int)*at)) {
|
||||
} else if(isdigit((unsigned char)*at)) {
|
||||
at = do_macro_arith(at, remain, &arithstart);
|
||||
} else {
|
||||
/* copy until whitespace or operator */
|
||||
if(*at && (isalnum((int)*at) || *at=='_')) {
|
||||
if(*at && (isalnum((unsigned char)*at) || *at=='_')) {
|
||||
at++;
|
||||
while(*at && (isalnum((int)*at) || *at=='_'))
|
||||
while(*at && (isalnum((unsigned char)*at) || *at=='_'))
|
||||
at++;
|
||||
} else at++;
|
||||
}
|
||||
|
10
external/unbound/testcode/testbound.c
vendored
10
external/unbound/testcode/testbound.c
vendored
@ -97,7 +97,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[])
|
||||
{
|
||||
const char *p = args, *np;
|
||||
size_t len;
|
||||
while(p && isspace((int)*p))
|
||||
while(p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
while(p && *p) {
|
||||
/* find location of next string and length of this one */
|
||||
@ -115,7 +115,7 @@ add_opts(const char* args, int* pass_argc, char* pass_argv[])
|
||||
(*pass_argc)++;
|
||||
/* go to next option */
|
||||
p = np;
|
||||
while(p && isspace((int)*p))
|
||||
while(p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
@ -140,7 +140,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
|
||||
char* parse;
|
||||
FILE* spool;
|
||||
/* find filename for new file */
|
||||
while(isspace((int)*id))
|
||||
while(isspace((unsigned char)*id))
|
||||
id++;
|
||||
if(strlen(id)==0)
|
||||
fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno);
|
||||
@ -158,7 +158,7 @@ spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse = line;
|
||||
(*lineno)++;
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(strncmp(parse, "AUTOTRUST_END", 13) == 0) {
|
||||
fclose(spool);
|
||||
@ -197,7 +197,7 @@ setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse = line;
|
||||
(*lineno)++;
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(!*parse || parse[0] == ';')
|
||||
continue;
|
||||
|
14
external/unbound/testcode/testpkts.c
vendored
14
external/unbound/testcode/testpkts.c
vendored
@ -81,7 +81,7 @@ static int str_keyword(char** str, const char* keyword)
|
||||
if(strncmp(*str, keyword, len) != 0)
|
||||
return 0;
|
||||
*str += len;
|
||||
while(isspace((int)**str))
|
||||
while(isspace((unsigned char)**str))
|
||||
(*str)++;
|
||||
return 1;
|
||||
}
|
||||
@ -138,7 +138,7 @@ static void matchline(char* line, struct entry* e)
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse MATCH: '%s'", parse);
|
||||
@ -226,11 +226,11 @@ static void adjustline(char* line, struct entry* e,
|
||||
e->copy_query = 1;
|
||||
} else if(str_keyword(&parse, "sleep=")) {
|
||||
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else if(str_keyword(&parse, "packet_sleep=")) {
|
||||
pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse ADJUST: '%s'", parse);
|
||||
@ -344,7 +344,7 @@ hex_buffer2wire(sldns_buffer *data_buffer)
|
||||
for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) {
|
||||
c = (int) data_wire[data_buf_pos];
|
||||
|
||||
if (state < 2 && !isascii(c)) {
|
||||
if (state < 2 && !isascii((unsigned char)c)) {
|
||||
/*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
|
||||
state = 2;
|
||||
}
|
||||
@ -422,7 +422,7 @@ get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse)
|
||||
int status;
|
||||
|
||||
end=parse;
|
||||
while(!isspace((int)*end) && !isendline(*end))
|
||||
while(!isspace((unsigned char)*end) && !isendline(*end))
|
||||
end++;
|
||||
store = *end;
|
||||
*end = 0;
|
||||
@ -518,7 +518,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
parse = line;
|
||||
pstate->lineno++;
|
||||
|
||||
while(isspace((int)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
/* test for keywords */
|
||||
if(isendline(*parse))
|
||||
|
24
external/unbound/util/config_file.c
vendored
24
external/unbound/util/config_file.c
vendored
@ -1105,7 +1105,7 @@ cfg_count_numbers(const char* s)
|
||||
/* sp ::= (space|tab)* */
|
||||
int num = 0;
|
||||
while(*s) {
|
||||
while(*s && isspace((int)*s))
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
if(!*s) /* end of string */
|
||||
break;
|
||||
@ -1113,9 +1113,9 @@ cfg_count_numbers(const char* s)
|
||||
s++;
|
||||
if(!*s) /* only - not allowed */
|
||||
return 0;
|
||||
if(!isdigit((int)*s)) /* bad character */
|
||||
if(!isdigit((unsigned char)*s)) /* bad character */
|
||||
return 0;
|
||||
while(*s && isdigit((int)*s))
|
||||
while(*s && isdigit((unsigned char)*s))
|
||||
s++;
|
||||
num++;
|
||||
}
|
||||
@ -1127,7 +1127,7 @@ static int isalldigit(const char* str, size_t l)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<l; i++)
|
||||
if(!isdigit(str[i]))
|
||||
if(!isdigit((unsigned char)str[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -1153,13 +1153,13 @@ cfg_parse_memsize(const char* str, size_t* res)
|
||||
else if(len > 1 && str[len-1] == 'B')
|
||||
len--;
|
||||
|
||||
if(len > 1 && tolower(str[len-1]) == 'g')
|
||||
if(len > 1 && tolower((unsigned char)str[len-1]) == 'g')
|
||||
mult = 1024*1024*1024;
|
||||
else if(len > 1 && tolower(str[len-1]) == 'm')
|
||||
else if(len > 1 && tolower((unsigned char)str[len-1]) == 'm')
|
||||
mult = 1024*1024;
|
||||
else if(len > 1 && tolower(str[len-1]) == 'k')
|
||||
else if(len > 1 && tolower((unsigned char)str[len-1]) == 'k')
|
||||
mult = 1024;
|
||||
else if(len > 0 && isdigit(str[len-1]))
|
||||
else if(len > 0 && isdigit((unsigned char)str[len-1]))
|
||||
mult = 1;
|
||||
else {
|
||||
log_err("unknown size specifier: '%s'", str);
|
||||
@ -1322,7 +1322,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val)
|
||||
|
||||
/* parse it as: [zone_name] [between stuff] [zone_type] */
|
||||
name = val;
|
||||
while(*name && isspace(*name))
|
||||
while(*name && isspace((unsigned char)*name))
|
||||
name++;
|
||||
if(!*name) {
|
||||
log_err("syntax error: too short: %s", val);
|
||||
@ -1341,7 +1341,7 @@ cfg_parse_local_zone(struct config_file* cfg, const char* val)
|
||||
buf[name_end-name] = '\0';
|
||||
|
||||
type = last_space_pos(name_end);
|
||||
while(type && *type && isspace(*type))
|
||||
while(type && *type && isspace((unsigned char)*type))
|
||||
type++;
|
||||
if(!type || !*type) {
|
||||
log_err("syntax error: expected zone type: %s", val);
|
||||
@ -1368,7 +1368,7 @@ char* cfg_ptr_reverse(char* str)
|
||||
|
||||
/* parse it as: [IP] [between stuff] [name] */
|
||||
ip = str;
|
||||
while(*ip && isspace(*ip))
|
||||
while(*ip && isspace((unsigned char)*ip))
|
||||
ip++;
|
||||
if(!*ip) {
|
||||
log_err("syntax error: too short: %s", str);
|
||||
@ -1423,7 +1423,7 @@ char* cfg_ptr_reverse(char* str)
|
||||
}
|
||||
|
||||
/* printed the reverse address, now the between goop and name on end */
|
||||
while(*ip_end && isspace(*ip_end))
|
||||
while(*ip_end && isspace((unsigned char)*ip_end))
|
||||
ip_end++;
|
||||
if(name>ip_end) {
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%.*s",
|
||||
|
4
external/unbound/util/configlexer.c
vendored
4
external/unbound/util/configlexer.c
vendored
@ -10,7 +10,7 @@
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 5
|
||||
#define YY_FLEX_SUBMINOR_VERSION 36
|
||||
#define YY_FLEX_SUBMINOR_VERSION 37
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
@ -3787,7 +3787,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
|
||||
YY_BUFFER_STATE b;
|
||||
char *buf;
|
||||
yy_size_t n;
|
||||
int i;
|
||||
yy_size_t i;
|
||||
|
||||
/* Get memory for full buffer, including space for trailing EOB's. */
|
||||
n = _yybytes_len + 2;
|
||||
|
408
external/unbound/util/configparser.c
vendored
408
external/unbound/util/configparser.c
vendored
File diff suppressed because it is too large
Load Diff
12
external/unbound/util/configparser.h
vendored
12
external/unbound/util/configparser.h
vendored
@ -1,4 +1,4 @@
|
||||
/* A Bison parser, made by GNU Bison 2.6.1. */
|
||||
/* A Bison parser, made by GNU Bison 2.7. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_UTIL_CONFIGPARSER_H
|
||||
# define YY_UTIL_CONFIGPARSER_H
|
||||
#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
@ -347,13 +347,13 @@ extern int yydebug;
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
/* Line 2049 of yacc.c */
|
||||
/* Line 2058 of yacc.c */
|
||||
#line 64 "./util/configparser.y"
|
||||
|
||||
char* str;
|
||||
|
||||
|
||||
/* Line 2049 of yacc.c */
|
||||
/* Line 2058 of yacc.c */
|
||||
#line 358 "util/configparser.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
@ -377,4 +377,4 @@ int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_UTIL_CONFIGPARSER_H */
|
||||
#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */
|
||||
|
30
external/unbound/util/data/dname.c
vendored
30
external/unbound/util/data/dname.c
vendored
@ -114,8 +114,8 @@ query_dname_compare(register uint8_t* d1, register uint8_t* d2)
|
||||
while(lab1--) {
|
||||
/* compare bytes first for speed */
|
||||
if(*d1 != *d2 &&
|
||||
tolower((int)*d1) != tolower((int)*d2)) {
|
||||
if(tolower((int)*d1) < tolower((int)*d2))
|
||||
tolower((unsigned char)*d1) != tolower((unsigned char)*d2)) {
|
||||
if(tolower((unsigned char)*d1) < tolower((unsigned char)*d2))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
@ -138,7 +138,7 @@ query_dname_tolower(uint8_t* dname)
|
||||
while(labellen) {
|
||||
dname++;
|
||||
while(labellen--) {
|
||||
*dname = (uint8_t)tolower((int)*dname);
|
||||
*dname = (uint8_t)tolower((unsigned char)*dname);
|
||||
dname++;
|
||||
}
|
||||
labellen = *dname;
|
||||
@ -167,7 +167,7 @@ pkt_dname_tolower(sldns_buffer* pkt, uint8_t* dname)
|
||||
if(dname+lablen >= sldns_buffer_end(pkt))
|
||||
return;
|
||||
while(lablen--) {
|
||||
*dname = (uint8_t)tolower((int)*dname);
|
||||
*dname = (uint8_t)tolower((unsigned char)*dname);
|
||||
dname++;
|
||||
}
|
||||
if(dname >= sldns_buffer_end(pkt))
|
||||
@ -256,8 +256,8 @@ dname_pkt_compare(sldns_buffer* pkt, uint8_t* d1, uint8_t* d2)
|
||||
log_assert(len1 == len2 && len1 != 0);
|
||||
/* compare labels */
|
||||
while(len1--) {
|
||||
if(tolower((int)*d1++) != tolower((int)*d2++)) {
|
||||
if(tolower((int)d1[-1]) < tolower((int)d2[-1]))
|
||||
if(tolower((unsigned char)*d1++) != tolower((unsigned char)*d2++)) {
|
||||
if(tolower((unsigned char)d1[-1]) < tolower((unsigned char)d2[-1]))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
@ -282,7 +282,7 @@ dname_query_hash(uint8_t* dname, hashvalue_t h)
|
||||
labuf[0] = lablen;
|
||||
i=0;
|
||||
while(lablen--)
|
||||
labuf[++i] = (uint8_t)tolower((int)*dname++);
|
||||
labuf[++i] = (uint8_t)tolower((unsigned char)*dname++);
|
||||
h = hashlittle(labuf, labuf[0] + 1, h);
|
||||
lablen = *dname++;
|
||||
}
|
||||
@ -310,7 +310,7 @@ dname_pkt_hash(sldns_buffer* pkt, uint8_t* dname, hashvalue_t h)
|
||||
labuf[0] = lablen;
|
||||
i=0;
|
||||
while(lablen--)
|
||||
labuf[++i] = (uint8_t)tolower((int)*dname++);
|
||||
labuf[++i] = (uint8_t)tolower((unsigned char)*dname++);
|
||||
h = hashlittle(labuf, labuf[0] + 1, h);
|
||||
lablen = *dname++;
|
||||
}
|
||||
@ -423,8 +423,8 @@ static int
|
||||
memlowercmp(uint8_t* p1, uint8_t* p2, uint8_t len)
|
||||
{
|
||||
while(len--) {
|
||||
if(*p1 != *p2 && tolower((int)*p1) != tolower((int)*p2)) {
|
||||
if(tolower((int)*p1) < tolower((int)*p2))
|
||||
if(*p1 != *p2 && tolower((unsigned char)*p1) != tolower((unsigned char)*p2)) {
|
||||
if(tolower((unsigned char)*p1) < tolower((unsigned char)*p2))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
@ -480,10 +480,10 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
|
||||
* lastdiff = c;
|
||||
* lastmlabs = atlabel; } apart from d1++,d2++ */
|
||||
while(len1) {
|
||||
if(*d1 != *d2 && tolower((int)*d1)
|
||||
!= tolower((int)*d2)) {
|
||||
if(tolower((int)*d1) <
|
||||
tolower((int)*d2)) {
|
||||
if(*d1 != *d2 && tolower((unsigned char)*d1)
|
||||
!= tolower((unsigned char)*d2)) {
|
||||
if(tolower((unsigned char)*d1) <
|
||||
tolower((unsigned char)*d2)) {
|
||||
lastdiff = -1;
|
||||
lastmlabs = atlabel;
|
||||
d1 += len1;
|
||||
@ -561,7 +561,7 @@ void dname_str(uint8_t* dname, char* str)
|
||||
return;
|
||||
}
|
||||
while(lablen--) {
|
||||
if(isalnum((int)*dname)
|
||||
if(isalnum((unsigned char)*dname)
|
||||
|| *dname == '-' || *dname == '_'
|
||||
|| *dname == '*')
|
||||
*s++ = *(char*)dname++;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user