Merge pull request #1084
5850122
remove errant target_link_libraries (Riccardo Spagni)58abc09
don't build any miniupnpc executables (Riccardo Spagni)114e368
don't build miniupnpc test executables (Riccardo Spagni)bb69371
updated miniupnp (Riccardo Spagni)f62ebc5
update rapidjson (Riccardo Spagni)
This commit is contained in:
commit
77224bbf48
8
external/CMakeLists.txt
vendored
8
external/CMakeLists.txt
vendored
@ -59,15 +59,15 @@ else()
|
|||||||
|
|
||||||
add_subdirectory(miniupnpc)
|
add_subdirectory(miniupnpc)
|
||||||
|
|
||||||
set_property(TARGET upnpc-static PROPERTY FOLDER "external")
|
set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||||
elseif(NOT MSVC)
|
elseif(NOT MSVC)
|
||||||
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(UPNP_STATIC true PARENT_SCOPE)
|
set(UPNP_STATIC true PARENT_SCOPE)
|
||||||
set(UPNP_LIBRARIES "upnpc-static" PARENT_SCOPE)
|
set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Unbound)
|
find_package(Unbound)
|
||||||
|
43
external/miniupnpc/CMakeLists.txt
vendored
43
external/miniupnpc/CMakeLists.txt
vendored
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required (VERSION 2.6)
|
cmake_minimum_required (VERSION 2.6)
|
||||||
|
|
||||||
project (miniupnpc C)
|
project (miniupnpc C)
|
||||||
set (MINIUPNPC_VERSION 1.9)
|
set (MINIUPNPC_VERSION 2.0)
|
||||||
set (MINIUPNPC_API_VERSION 16)
|
set (MINIUPNPC_API_VERSION 16)
|
||||||
|
|
||||||
# - we comment out this block as we don't support these other build types
|
# - we comment out this block as we don't support these other build types
|
||||||
@ -20,9 +20,7 @@ endif()
|
|||||||
|
|
||||||
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
||||||
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
|
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
|
||||||
if (NOT WIN32)
|
option (UPNPC_BUILD_TESTS "Build test executables" FALSE)
|
||||||
option (UPNPC_BUILD_TESTS "Build test executables" FALSE)
|
|
||||||
endif (NOT WIN32)
|
|
||||||
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
||||||
|
|
||||||
mark_as_advanced (NO_GETADDRINFO)
|
mark_as_advanced (NO_GETADDRINFO)
|
||||||
@ -34,6 +32,10 @@ endif (NO_GETADDRINFO)
|
|||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
|
add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
|
||||||
add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE)
|
add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE)
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
|
# add_definitions (-D_POSIX_C_SOURCE=200112L)
|
||||||
|
add_definitions (-D_XOPEN_SOURCE=600)
|
||||||
|
endif (NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||||
else (NOT WIN32)
|
else (NOT WIN32)
|
||||||
add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
|
add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
|
||||||
endif (NOT WIN32)
|
endif (NOT WIN32)
|
||||||
@ -68,8 +70,8 @@ if (CMAKE_COMPILER_IS_GNUC)
|
|||||||
endif ()
|
endif ()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file (miniupnpcstrings.h.cmake ${CMAKE_BINARY_DIR}/miniupnpcstrings.h)
|
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h)
|
||||||
include_directories (${CMAKE_BINARY_DIR})
|
include_directories (${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
set (MINIUPNPC_SOURCES
|
set (MINIUPNPC_SOURCES
|
||||||
igd_desc_parse.c
|
igd_desc_parse.c
|
||||||
@ -78,7 +80,6 @@ set (MINIUPNPC_SOURCES
|
|||||||
minisoap.c
|
minisoap.c
|
||||||
minissdpc.c
|
minissdpc.c
|
||||||
miniwget.c
|
miniwget.c
|
||||||
upnpc.c
|
|
||||||
upnpcommands.c
|
upnpcommands.c
|
||||||
upnpdev.c
|
upnpdev.c
|
||||||
upnpreplyparse.c
|
upnpreplyparse.c
|
||||||
@ -117,21 +118,25 @@ if (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
|
|||||||
endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
|
endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
|
||||||
|
|
||||||
if (UPNPC_BUILD_STATIC)
|
if (UPNPC_BUILD_STATIC)
|
||||||
add_library (upnpc-static STATIC ${MINIUPNPC_SOURCES})
|
add_library (libminiupnpc-static STATIC ${MINIUPNPC_SOURCES})
|
||||||
set_target_properties (upnpc-static PROPERTIES OUTPUT_NAME "miniupnpc")
|
set_target_properties (libminiupnpc-static PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||||
target_link_libraries (upnpc-static ${LDLIBS})
|
target_link_libraries (libminiupnpc-static ${LDLIBS})
|
||||||
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-static)
|
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} libminiupnpc-static)
|
||||||
set (UPNPC_LIBRARY_TARGET upnpc-static)
|
set (UPNPC_LIBRARY_TARGET libminiupnpc-static)
|
||||||
|
# add_executable (upnpc-static upnpc.c)
|
||||||
|
# target_link_libraries (upnpc-static LINK_PRIVATE libminiupnpc-static)
|
||||||
endif (UPNPC_BUILD_STATIC)
|
endif (UPNPC_BUILD_STATIC)
|
||||||
|
|
||||||
if (UPNPC_BUILD_SHARED)
|
if (UPNPC_BUILD_SHARED)
|
||||||
add_library (upnpc-shared SHARED ${MINIUPNPC_SOURCES})
|
add_library (libminiupnpc-shared SHARED ${MINIUPNPC_SOURCES})
|
||||||
set_target_properties (upnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc")
|
set_target_properties (libminiupnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc")
|
||||||
set_target_properties (upnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION})
|
set_target_properties (libminiupnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION})
|
||||||
set_target_properties (upnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION})
|
set_target_properties (libminiupnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION})
|
||||||
target_link_libraries (upnpc-shared ${LDLIBS})
|
target_link_libraries (libminiupnpc-shared ${LDLIBS})
|
||||||
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-shared)
|
set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} libminiupnpc-shared)
|
||||||
set (UPNPC_LIBRARY_TARGET upnpc-shared)
|
set (UPNPC_LIBRARY_TARGET libminiupnpc-shared)
|
||||||
|
add_executable (upnpc-shared upnpc.c)
|
||||||
|
target_link_libraries (upnpc-shared LINK_PRIVATE libminiupnpc-shared)
|
||||||
endif (UPNPC_BUILD_SHARED)
|
endif (UPNPC_BUILD_SHARED)
|
||||||
|
|
||||||
if (UPNPC_BUILD_TESTS)
|
if (UPNPC_BUILD_TESTS)
|
||||||
|
4
external/miniupnpc/Changelog.txt
vendored
4
external/miniupnpc/Changelog.txt
vendored
@ -1,6 +1,8 @@
|
|||||||
$Id: Changelog.txt,v 1.222 2016/01/24 17:24:35 nanard Exp $
|
$Id: Changelog.txt,v 1.223 2016/04/19 21:06:20 nanard Exp $
|
||||||
miniUPnP client Changelog.
|
miniUPnP client Changelog.
|
||||||
|
|
||||||
|
VERSION 2.0 : released 2016/04/19
|
||||||
|
|
||||||
2016/01/24:
|
2016/01/24:
|
||||||
change miniwget to return HTTP status code
|
change miniwget to return HTTP status code
|
||||||
increments API_VERSION to 16
|
increments API_VERSION to 16
|
||||||
|
9
external/miniupnpc/Makefile
vendored
9
external/miniupnpc/Makefile
vendored
@ -38,6 +38,9 @@ CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT
|
|||||||
CFLAGS += -DMINIUPNPC_GET_SRC_ADDR
|
CFLAGS += -DMINIUPNPC_GET_SRC_ADDR
|
||||||
CFLAGS += -D_BSD_SOURCE
|
CFLAGS += -D_BSD_SOURCE
|
||||||
CFLAGS += -D_DEFAULT_SOURCE
|
CFLAGS += -D_DEFAULT_SOURCE
|
||||||
|
ifeq ($(OS), NetBSD)
|
||||||
|
CFLAGS += -D_NETBSD_SOURCE
|
||||||
|
endif
|
||||||
ifneq ($(OS), FreeBSD)
|
ifneq ($(OS), FreeBSD)
|
||||||
ifneq ($(OS), Darwin)
|
ifneq ($(OS), Darwin)
|
||||||
#CFLAGS += -D_POSIX_C_SOURCE=200112L
|
#CFLAGS += -D_POSIX_C_SOURCE=200112L
|
||||||
@ -136,7 +139,11 @@ endif
|
|||||||
|
|
||||||
LIBDIR ?= lib
|
LIBDIR ?= lib
|
||||||
# install directories
|
# install directories
|
||||||
INSTALLPREFIX ?= $(PREFIX)/usr
|
ifeq ($(strip $(PREFIX)),)
|
||||||
|
INSTALLPREFIX ?= /usr
|
||||||
|
else
|
||||||
|
INSTALLPREFIX ?= $(PREFIX)
|
||||||
|
endif
|
||||||
INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
|
INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
|
||||||
INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR)
|
INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR)
|
||||||
INSTALLDIRBIN = $(INSTALLPREFIX)/bin
|
INSTALLDIRBIN = $(INSTALLPREFIX)/bin
|
||||||
|
5
external/miniupnpc/README
vendored
5
external/miniupnpc/README
vendored
@ -3,7 +3,7 @@ Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|||||||
github: https://github.com/miniupnp/miniupnp
|
github: https://github.com/miniupnp/miniupnp
|
||||||
freecode: http://freecode.com/projects/miniupnp
|
freecode: http://freecode.com/projects/miniupnp
|
||||||
Author: Thomas Bernard
|
Author: Thomas Bernard
|
||||||
Copyright (c) 2005-2014 Thomas Bernard
|
Copyright (c) 2005-2016 Thomas Bernard
|
||||||
This software is subject to the conditions detailed in the
|
This software is subject to the conditions detailed in the
|
||||||
LICENSE file provided within this distribution.
|
LICENSE file provided within this distribution.
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ To use the libminiupnpc in your application, link it with
|
|||||||
libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
|
libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
|
||||||
upnpcommands.h and miniwget.h :
|
upnpcommands.h and miniwget.h :
|
||||||
- upnpDiscover()
|
- upnpDiscover()
|
||||||
|
- UPNP_GetValidIGD()
|
||||||
- miniwget()
|
- miniwget()
|
||||||
- parserootdesc()
|
- parserootdesc()
|
||||||
- GetUPNPUrls()
|
- GetUPNPUrls()
|
||||||
@ -59,3 +60,5 @@ send me an email !
|
|||||||
For any question, you can use the web forum :
|
For any question, you can use the web forum :
|
||||||
http://miniupnp.tuxfamily.org/forum/
|
http://miniupnp.tuxfamily.org/forum/
|
||||||
|
|
||||||
|
Bugs should be reported on github :
|
||||||
|
https://github.com/miniupnp/miniupnp/issues
|
||||||
|
2
external/miniupnpc/VERSION
vendored
2
external/miniupnpc/VERSION
vendored
@ -1 +1 @@
|
|||||||
1.9
|
2.0
|
||||||
|
3
external/miniupnpc/minissdpc.c
vendored
3
external/miniupnpc/minissdpc.c
vendored
@ -11,6 +11,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#if defined (__NetBSD__)
|
||||||
|
#include <net/if.h>
|
||||||
|
#endif
|
||||||
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
|
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
4
external/miniupnpc/miniupnpc.h
vendored
4
external/miniupnpc/miniupnpc.h
vendored
@ -1,4 +1,4 @@
|
|||||||
/* $Id: miniupnpc.h,v 1.49 2016/01/24 17:24:36 nanard Exp $ */
|
/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */
|
||||||
/* Project: miniupnp
|
/* Project: miniupnp
|
||||||
* http://miniupnp.free.fr/
|
* http://miniupnp.free.fr/
|
||||||
* Author: Thomas Bernard
|
* Author: Thomas Bernard
|
||||||
@ -19,7 +19,7 @@
|
|||||||
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
||||||
|
|
||||||
/* versions : */
|
/* versions : */
|
||||||
#define MINIUPNPC_VERSION "1.9"
|
#define MINIUPNPC_VERSION "2.0"
|
||||||
#define MINIUPNPC_API_VERSION 16
|
#define MINIUPNPC_API_VERSION 16
|
||||||
|
|
||||||
/* Source port:
|
/* Source port:
|
||||||
|
532
external/rapidjson/allocators.h
vendored
532
external/rapidjson/allocators.h
vendored
@ -1,261 +1,271 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ALLOCATORS_H_
|
#ifndef RAPIDJSON_ALLOCATORS_H_
|
||||||
#define RAPIDJSON_ALLOCATORS_H_
|
#define RAPIDJSON_ALLOCATORS_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "rapidjson.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Allocator
|
// Allocator
|
||||||
|
|
||||||
/*! \class rapidjson::Allocator
|
/*! \class rapidjson::Allocator
|
||||||
\brief Concept for allocating, resizing and freeing memory block.
|
\brief Concept for allocating, resizing and freeing memory block.
|
||||||
|
|
||||||
Note that Malloc() and Realloc() are non-static but Free() is static.
|
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
|
So if an allocator need to support Free(), it needs to put its pointer in
|
||||||
the header of memory block.
|
the header of memory block.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
concept Allocator {
|
concept Allocator {
|
||||||
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
||||||
|
|
||||||
// Allocate a memory block.
|
// Allocate a memory block.
|
||||||
// \param size of the memory block in bytes.
|
// \param size of the memory block in bytes.
|
||||||
// \returns pointer to the memory block.
|
// \returns pointer to the memory block.
|
||||||
void* Malloc(size_t size);
|
void* Malloc(size_t size);
|
||||||
|
|
||||||
// Resize a memory block.
|
// Resize a memory block.
|
||||||
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
|
// \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 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.
|
// \param newSize the new size in bytes.
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
|
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
|
||||||
|
|
||||||
// Free a memory block.
|
// Free a memory block.
|
||||||
// \param pointer to the memory block. Null pointer is permitted.
|
// \param pointer to the memory block. Null pointer is permitted.
|
||||||
static void Free(void *ptr);
|
static void Free(void *ptr);
|
||||||
};
|
};
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// CrtAllocator
|
// CrtAllocator
|
||||||
|
|
||||||
//! C-runtime library allocator.
|
//! C-runtime library allocator.
|
||||||
/*! This class is just wrapper for standard C library memory routines.
|
/*! This class is just wrapper for standard C library memory routines.
|
||||||
\note implements Allocator concept
|
\note implements Allocator concept
|
||||||
*/
|
*/
|
||||||
class CrtAllocator {
|
class CrtAllocator {
|
||||||
public:
|
public:
|
||||||
static const bool kNeedFree = true;
|
static const bool kNeedFree = true;
|
||||||
void* Malloc(size_t size) {
|
void* Malloc(size_t size) {
|
||||||
if (size) // behavior of malloc(0) is implementation defined.
|
if (size) // behavior of malloc(0) is implementation defined.
|
||||||
return std::malloc(size);
|
return std::malloc(size);
|
||||||
else
|
else
|
||||||
return NULL; // standardize to returning NULL.
|
return NULL; // standardize to returning NULL.
|
||||||
}
|
}
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
||||||
(void)originalSize;
|
(void)originalSize;
|
||||||
if (newSize == 0) {
|
if (newSize == 0) {
|
||||||
std::free(originalPtr);
|
std::free(originalPtr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return std::realloc(originalPtr, newSize);
|
return std::realloc(originalPtr, newSize);
|
||||||
}
|
}
|
||||||
static void Free(void *ptr) { std::free(ptr); }
|
static void Free(void *ptr) { std::free(ptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// MemoryPoolAllocator
|
// MemoryPoolAllocator
|
||||||
|
|
||||||
//! Default memory allocator used by the parser and DOM.
|
//! Default memory allocator used by the parser and DOM.
|
||||||
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
|
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
|
||||||
|
|
||||||
It does not free memory blocks. And Realloc() only allocate new memory.
|
It does not free memory blocks. And Realloc() only allocate new memory.
|
||||||
|
|
||||||
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
|
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
|
||||||
|
|
||||||
User may also supply a buffer as the first chunk.
|
User may also supply a buffer as the first chunk.
|
||||||
|
|
||||||
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
|
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
|
||||||
|
|
||||||
The user-buffer is not deallocated by this allocator.
|
The user-buffer is not deallocated by this allocator.
|
||||||
|
|
||||||
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
|
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
|
||||||
\note implements Allocator concept
|
\note implements Allocator concept
|
||||||
*/
|
*/
|
||||||
template <typename BaseAllocator = CrtAllocator>
|
template <typename BaseAllocator = CrtAllocator>
|
||||||
class MemoryPoolAllocator {
|
class MemoryPoolAllocator {
|
||||||
public:
|
public:
|
||||||
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
||||||
|
|
||||||
//! Constructor with chunkSize.
|
//! Constructor with chunkSize.
|
||||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
\param baseAllocator The allocator for allocating memory chunks.
|
||||||
*/
|
*/
|
||||||
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Constructor with user-supplied buffer.
|
//! 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 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.
|
The user buffer will not be deallocated when this allocator is destructed.
|
||||||
|
|
||||||
\param buffer User supplied buffer.
|
\param buffer User supplied buffer.
|
||||||
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
|
\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 chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||||
\param baseAllocator The allocator for allocating memory chunks.
|
\param baseAllocator The allocator for allocating memory chunks.
|
||||||
*/
|
*/
|
||||||
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||||
{
|
{
|
||||||
RAPIDJSON_ASSERT(buffer != 0);
|
RAPIDJSON_ASSERT(buffer != 0);
|
||||||
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
||||||
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
||||||
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
||||||
chunkHead_->size = 0;
|
chunkHead_->size = 0;
|
||||||
chunkHead_->next = 0;
|
chunkHead_->next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destructor.
|
//! Destructor.
|
||||||
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
||||||
*/
|
*/
|
||||||
~MemoryPoolAllocator() {
|
~MemoryPoolAllocator() {
|
||||||
Clear();
|
Clear();
|
||||||
RAPIDJSON_DELETE(ownBaseAllocator_);
|
RAPIDJSON_DELETE(ownBaseAllocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
||||||
void Clear() {
|
void Clear() {
|
||||||
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
||||||
ChunkHeader* next = chunkHead_->next;
|
ChunkHeader* next = chunkHead_->next;
|
||||||
baseAllocator_->Free(chunkHead_);
|
baseAllocator_->Free(chunkHead_);
|
||||||
chunkHead_ = next;
|
chunkHead_ = next;
|
||||||
}
|
}
|
||||||
if (chunkHead_ && chunkHead_ == userBuffer_)
|
if (chunkHead_ && chunkHead_ == userBuffer_)
|
||||||
chunkHead_->size = 0; // Clear user buffer
|
chunkHead_->size = 0; // Clear user buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Computes the total capacity of allocated memory chunks.
|
//! Computes the total capacity of allocated memory chunks.
|
||||||
/*! \return total capacity in bytes.
|
/*! \return total capacity in bytes.
|
||||||
*/
|
*/
|
||||||
size_t Capacity() const {
|
size_t Capacity() const {
|
||||||
size_t capacity = 0;
|
size_t capacity = 0;
|
||||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||||
capacity += c->capacity;
|
capacity += c->capacity;
|
||||||
return capacity;
|
return capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Computes the memory blocks allocated.
|
//! Computes the memory blocks allocated.
|
||||||
/*! \return total used bytes.
|
/*! \return total used bytes.
|
||||||
*/
|
*/
|
||||||
size_t Size() const {
|
size_t Size() const {
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||||
size += c->size;
|
size += c->size;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Allocates a memory block. (concept Allocator)
|
//! Allocates a memory block. (concept Allocator)
|
||||||
void* Malloc(size_t size) {
|
void* Malloc(size_t size) {
|
||||||
if (!size)
|
if (!size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
size = RAPIDJSON_ALIGN(size);
|
size = RAPIDJSON_ALIGN(size);
|
||||||
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
||||||
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
|
if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
|
||||||
|
return NULL;
|
||||||
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
|
|
||||||
chunkHead_->size += size;
|
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
|
||||||
return buffer;
|
chunkHead_->size += size;
|
||||||
}
|
return buffer;
|
||||||
|
}
|
||||||
//! Resizes a memory block (concept Allocator)
|
|
||||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
//! Resizes a memory block (concept Allocator)
|
||||||
if (originalPtr == 0)
|
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
||||||
return Malloc(newSize);
|
if (originalPtr == 0)
|
||||||
|
return Malloc(newSize);
|
||||||
if (newSize == 0)
|
|
||||||
return NULL;
|
if (newSize == 0)
|
||||||
|
return NULL;
|
||||||
// Do not shrink if new size is smaller than original
|
|
||||||
if (originalSize >= newSize)
|
originalSize = RAPIDJSON_ALIGN(originalSize);
|
||||||
return originalPtr;
|
newSize = RAPIDJSON_ALIGN(newSize);
|
||||||
|
|
||||||
// Simply expand it if it is the last allocation and there is sufficient space
|
// Do not shrink if new size is smaller than original
|
||||||
if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
if (originalSize >= newSize)
|
||||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
return originalPtr;
|
||||||
increment = RAPIDJSON_ALIGN(increment);
|
|
||||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
// Simply expand it if it is the last allocation and there is sufficient space
|
||||||
chunkHead_->size += increment;
|
if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
||||||
return originalPtr;
|
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||||
}
|
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||||
}
|
chunkHead_->size += increment;
|
||||||
|
return originalPtr;
|
||||||
// Realloc process: allocate and copy memory, do not free original buffer.
|
}
|
||||||
void* newBuffer = Malloc(newSize);
|
}
|
||||||
RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
|
|
||||||
if (originalSize)
|
// Realloc process: allocate and copy memory, do not free original buffer.
|
||||||
std::memcpy(newBuffer, originalPtr, originalSize);
|
if (void* newBuffer = Malloc(newSize)) {
|
||||||
return newBuffer;
|
if (originalSize)
|
||||||
}
|
std::memcpy(newBuffer, originalPtr, originalSize);
|
||||||
|
return newBuffer;
|
||||||
//! Frees a memory block (concept Allocator)
|
}
|
||||||
static void Free(void *ptr) { (void)ptr; } // Do nothing
|
else
|
||||||
|
return NULL;
|
||||||
private:
|
}
|
||||||
//! Copy constructor is not permitted.
|
|
||||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
|
//! Frees a memory block (concept Allocator)
|
||||||
//! Copy assignment operator is not permitted.
|
static void Free(void *ptr) { (void)ptr; } // Do nothing
|
||||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
|
|
||||||
|
private:
|
||||||
//! Creates a new chunk.
|
//! Copy constructor is not permitted.
|
||||||
/*! \param capacity Capacity of the chunk in bytes.
|
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
|
||||||
*/
|
//! Copy assignment operator is not permitted.
|
||||||
void AddChunk(size_t capacity) {
|
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
|
||||||
if (!baseAllocator_)
|
|
||||||
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
|
//! Creates a new chunk.
|
||||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity));
|
/*! \param capacity Capacity of the chunk in bytes.
|
||||||
chunk->capacity = capacity;
|
\return true if success.
|
||||||
chunk->size = 0;
|
*/
|
||||||
chunk->next = chunkHead_;
|
bool AddChunk(size_t capacity) {
|
||||||
chunkHead_ = chunk;
|
if (!baseAllocator_)
|
||||||
}
|
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
|
||||||
|
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
|
||||||
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
|
chunk->capacity = capacity;
|
||||||
|
chunk->size = 0;
|
||||||
//! Chunk header for perpending to each chunk.
|
chunk->next = chunkHead_;
|
||||||
/*! Chunks are stored as a singly linked list.
|
chunkHead_ = chunk;
|
||||||
*/
|
return true;
|
||||||
struct ChunkHeader {
|
}
|
||||||
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
|
else
|
||||||
size_t size; //!< Current size of allocated memory in bytes.
|
return false;
|
||||||
ChunkHeader *next; //!< Next chunk in the linked list.
|
}
|
||||||
};
|
|
||||||
|
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
|
||||||
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.
|
//! Chunk header for perpending to each chunk.
|
||||||
void *userBuffer_; //!< User supplied buffer.
|
/*! Chunks are stored as a singly linked list.
|
||||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
*/
|
||||||
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
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.
|
||||||
RAPIDJSON_NAMESPACE_END
|
ChunkHeader *next; //!< Next chunk in the linked list.
|
||||||
|
};
|
||||||
#endif // RAPIDJSON_ENCODINGS_H_
|
|
||||||
|
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
||||||
|
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||||
|
void *userBuffer_; //!< User supplied buffer.
|
||||||
|
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||||
|
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
||||||
|
};
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_ENCODINGS_H_
|
||||||
|
4705
external/rapidjson/document.h
vendored
4705
external/rapidjson/document.h
vendored
File diff suppressed because it is too large
Load Diff
569
external/rapidjson/encodedstream.h
vendored
569
external/rapidjson/encodedstream.h
vendored
@ -1,270 +1,299 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
|
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
|
||||||
#define RAPIDJSON_ENCODEDSTREAM_H_
|
#define RAPIDJSON_ENCODEDSTREAM_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
|
#include "memorystream.h"
|
||||||
#ifdef __GNUC__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_PUSH
|
||||||
#endif
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
|
#endif
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_PUSH
|
||||||
#endif
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
|
#endif
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
//! Input byte stream wrapper with a statically bound encoding.
|
|
||||||
/*!
|
//! 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.
|
\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 {
|
template <typename Encoding, typename InputByteStream>
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
class EncodedInputStream {
|
||||||
public:
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||||
typedef typename Encoding::Ch Ch;
|
public:
|
||||||
|
typedef typename Encoding::Ch Ch;
|
||||||
EncodedInputStream(InputByteStream& is) : is_(is) {
|
|
||||||
current_ = Encoding::TakeBOM(is_);
|
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; }
|
Ch Peek() const { return current_; }
|
||||||
size_t Tell() const { return is_.Tell(); }
|
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); }
|
// Not implemented
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
private:
|
|
||||||
EncodedInputStream(const EncodedInputStream&);
|
private:
|
||||||
EncodedInputStream& operator=(const EncodedInputStream&);
|
EncodedInputStream(const EncodedInputStream&);
|
||||||
|
EncodedInputStream& operator=(const EncodedInputStream&);
|
||||||
InputByteStream& is_;
|
|
||||||
Ch current_;
|
InputByteStream& is_;
|
||||||
};
|
Ch current_;
|
||||||
|
};
|
||||||
//! Output byte stream wrapper with statically bound encoding.
|
|
||||||
/*!
|
//! Specialized for UTF8 MemoryStream.
|
||||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
template <>
|
||||||
\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
|
class EncodedInputStream<UTF8<>, MemoryStream> {
|
||||||
*/
|
public:
|
||||||
template <typename Encoding, typename OutputByteStream>
|
typedef UTF8<>::Ch Ch;
|
||||||
class EncodedOutputStream {
|
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
EncodedInputStream(MemoryStream& is) : is_(is) {
|
||||||
public:
|
if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();
|
||||||
typedef typename Encoding::Ch Ch;
|
if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();
|
||||||
|
if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();
|
||||||
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
|
}
|
||||||
if (putBOM)
|
Ch Peek() const { return is_.Peek(); }
|
||||||
Encoding::PutBOM(os_);
|
Ch Take() { return is_.Take(); }
|
||||||
}
|
size_t Tell() const { return is_.Tell(); }
|
||||||
|
|
||||||
void Put(Ch c) { Encoding::Put(os_, c); }
|
// Not implemented
|
||||||
void Flush() { os_.Flush(); }
|
void Put(Ch) {}
|
||||||
|
void Flush() {}
|
||||||
// Not implemented
|
Ch* PutBegin() { return 0; }
|
||||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
size_t PutEnd(Ch*) { return 0; }
|
||||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
MemoryStream& is_;
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
private:
|
||||||
|
EncodedInputStream(const EncodedInputStream&);
|
||||||
private:
|
EncodedInputStream& operator=(const EncodedInputStream&);
|
||||||
EncodedOutputStream(const EncodedOutputStream&);
|
};
|
||||||
EncodedOutputStream& operator=(const EncodedOutputStream&);
|
|
||||||
|
//! Output byte stream wrapper with statically bound encoding.
|
||||||
OutputByteStream& os_;
|
/*!
|
||||||
};
|
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
||||||
|
\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
|
||||||
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
*/
|
||||||
|
template <typename Encoding, typename OutputByteStream>
|
||||||
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
|
class EncodedOutputStream {
|
||||||
/*!
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||||
\tparam CharType Type of character for reading.
|
public:
|
||||||
\tparam InputByteStream type of input byte stream to be wrapped.
|
typedef typename Encoding::Ch Ch;
|
||||||
*/
|
|
||||||
template <typename CharType, typename InputByteStream>
|
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
|
||||||
class AutoUTFInputStream {
|
if (putBOM)
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
Encoding::PutBOM(os_);
|
||||||
public:
|
}
|
||||||
typedef CharType Ch;
|
|
||||||
|
void Put(Ch c) { Encoding::Put(os_, c); }
|
||||||
//! Constructor.
|
void Flush() { os_.Flush(); }
|
||||||
/*!
|
|
||||||
\param is input stream to be wrapped.
|
// Not implemented
|
||||||
\param type UTF encoding type if it is not detected from the stream.
|
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
*/
|
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
DetectType();
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
|
|
||||||
takeFunc_ = f[type_];
|
private:
|
||||||
current_ = takeFunc_(*is_);
|
EncodedOutputStream(const EncodedOutputStream&);
|
||||||
}
|
EncodedOutputStream& operator=(const EncodedOutputStream&);
|
||||||
|
|
||||||
UTFType GetType() const { return type_; }
|
OutputByteStream& os_;
|
||||||
bool HasBOM() const { return hasBOM_; }
|
};
|
||||||
|
|
||||||
Ch Peek() const { return current_; }
|
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
||||||
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
|
|
||||||
size_t Tell() const { return is_->Tell(); }
|
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
|
||||||
|
/*!
|
||||||
// Not implemented
|
\tparam CharType Type of character for reading.
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
\tparam InputByteStream type of input byte stream to be wrapped.
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
*/
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
template <typename CharType, typename InputByteStream>
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
class AutoUTFInputStream {
|
||||||
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||||
private:
|
public:
|
||||||
AutoUTFInputStream(const AutoUTFInputStream&);
|
typedef CharType Ch;
|
||||||
AutoUTFInputStream& operator=(const AutoUTFInputStream&);
|
|
||||||
|
//! Constructor.
|
||||||
// Detect encoding type with BOM or RFC 4627
|
/*!
|
||||||
void DetectType() {
|
\param is input stream to be wrapped.
|
||||||
// BOM (Byte Order Mark):
|
\param type UTF encoding type if it is not detected from the stream.
|
||||||
// 00 00 FE FF UTF-32BE
|
*/
|
||||||
// FF FE 00 00 UTF-32LE
|
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
|
||||||
// FE FF UTF-16BE
|
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
||||||
// FF FE UTF-16LE
|
DetectType();
|
||||||
// EF BB BF UTF-8
|
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
|
||||||
|
takeFunc_ = f[type_];
|
||||||
const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
|
current_ = takeFunc_(*is_);
|
||||||
if (!c)
|
}
|
||||||
return;
|
|
||||||
|
UTFType GetType() const { return type_; }
|
||||||
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
bool HasBOM() const { return hasBOM_; }
|
||||||
hasBOM_ = false;
|
|
||||||
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
Ch Peek() const { return current_; }
|
||||||
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
|
||||||
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
size_t Tell() const { return is_->Tell(); }
|
||||||
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(); }
|
// Not implemented
|
||||||
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
// RFC 4627: Section 3
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
// "Since the first two characters of a JSON text will always be ASCII
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
// characters [RFC0020], it is possible to determine whether an octet
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
// 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."
|
private:
|
||||||
// 00 00 00 xx UTF-32BE
|
AutoUTFInputStream(const AutoUTFInputStream&);
|
||||||
// 00 xx 00 xx UTF-16BE
|
AutoUTFInputStream& operator=(const AutoUTFInputStream&);
|
||||||
// xx 00 00 00 UTF-32LE
|
|
||||||
// xx 00 xx 00 UTF-16LE
|
// Detect encoding type with BOM or RFC 4627
|
||||||
// xx xx xx xx UTF-8
|
void DetectType() {
|
||||||
|
// BOM (Byte Order Mark):
|
||||||
if (!hasBOM_) {
|
// 00 00 FE FF UTF-32BE
|
||||||
unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
// FF FE 00 00 UTF-32LE
|
||||||
switch (pattern) {
|
// FE FF UTF-16BE
|
||||||
case 0x08: type_ = kUTF32BE; break;
|
// FF FE UTF-16LE
|
||||||
case 0x0A: type_ = kUTF16BE; break;
|
// EF BB BF UTF-8
|
||||||
case 0x01: type_ = kUTF32LE; break;
|
|
||||||
case 0x05: type_ = kUTF16LE; break;
|
const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
|
||||||
case 0x0F: type_ = kUTF8; break;
|
if (!c)
|
||||||
default: break; // Use type defined by user.
|
return;
|
||||||
}
|
|
||||||
}
|
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
||||||
|
hasBOM_ = false;
|
||||||
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||||
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||||
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
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(); }
|
||||||
typedef Ch (*TakeFunc)(InputByteStream& is);
|
|
||||||
InputByteStream* is_;
|
// RFC 4627: Section 3
|
||||||
UTFType type_;
|
// "Since the first two characters of a JSON text will always be ASCII
|
||||||
Ch current_;
|
// characters [RFC0020], it is possible to determine whether an octet
|
||||||
TakeFunc takeFunc_;
|
// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
|
||||||
bool hasBOM_;
|
// at the pattern of nulls in the first four octets."
|
||||||
};
|
// 00 00 00 xx UTF-32BE
|
||||||
|
// 00 xx 00 xx UTF-16BE
|
||||||
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
|
// xx 00 00 00 UTF-32LE
|
||||||
/*!
|
// xx 00 xx 00 UTF-16LE
|
||||||
\tparam CharType Type of character for writing.
|
// xx xx xx xx UTF-8
|
||||||
\tparam OutputByteStream type of output byte stream to be wrapped.
|
|
||||||
*/
|
if (!hasBOM_) {
|
||||||
template <typename CharType, typename OutputByteStream>
|
unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
||||||
class AutoUTFOutputStream {
|
switch (pattern) {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
case 0x08: type_ = kUTF32BE; break;
|
||||||
public:
|
case 0x0A: type_ = kUTF16BE; break;
|
||||||
typedef CharType Ch;
|
case 0x01: type_ = kUTF32LE; break;
|
||||||
|
case 0x05: type_ = kUTF16LE; break;
|
||||||
//! Constructor.
|
case 0x0F: type_ = kUTF8; break;
|
||||||
/*!
|
default: break; // Use type defined by user.
|
||||||
\param os output stream to be wrapped.
|
}
|
||||||
\param type UTF encoding type.
|
}
|
||||||
\param putBOM Whether to write BOM at the beginning of the stream.
|
|
||||||
*/
|
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
||||||
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
|
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||||
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||||
|
}
|
||||||
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
|
||||||
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
typedef Ch (*TakeFunc)(InputByteStream& is);
|
||||||
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
InputByteStream* is_;
|
||||||
|
UTFType type_;
|
||||||
static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
|
Ch current_;
|
||||||
putFunc_ = f[type_];
|
TakeFunc takeFunc_;
|
||||||
|
bool hasBOM_;
|
||||||
if (putBOM)
|
};
|
||||||
PutBOM();
|
|
||||||
}
|
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
|
||||||
|
/*!
|
||||||
UTFType GetType() const { return type_; }
|
\tparam CharType Type of character for writing.
|
||||||
|
\tparam OutputByteStream type of output byte stream to be wrapped.
|
||||||
void Put(Ch c) { putFunc_(*os_, c); }
|
*/
|
||||||
void Flush() { os_->Flush(); }
|
template <typename CharType, typename OutputByteStream>
|
||||||
|
class AutoUTFOutputStream {
|
||||||
// Not implemented
|
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
public:
|
||||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
typedef CharType Ch;
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
//! Constructor.
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
/*!
|
||||||
|
\param os output stream to be wrapped.
|
||||||
private:
|
\param type UTF encoding type.
|
||||||
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
\param putBOM Whether to write BOM at the beginning of the stream.
|
||||||
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
|
*/
|
||||||
|
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
|
||||||
void PutBOM() {
|
RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
|
||||||
typedef void (*PutBOMFunc)(OutputByteStream&);
|
|
||||||
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
|
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
||||||
f[type_](*os_);
|
if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||||
}
|
if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||||
|
|
||||||
typedef void (*PutFunc)(OutputByteStream&, Ch);
|
static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
|
||||||
|
putFunc_ = f[type_];
|
||||||
OutputByteStream* os_;
|
|
||||||
UTFType type_;
|
if (putBOM)
|
||||||
PutFunc putFunc_;
|
PutBOM();
|
||||||
};
|
}
|
||||||
|
|
||||||
#undef RAPIDJSON_ENCODINGS_FUNC
|
UTFType GetType() const { return type_; }
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
void Put(Ch c) { putFunc_(*os_, c); }
|
||||||
|
void Flush() { os_->Flush(); }
|
||||||
#ifdef __clang__
|
|
||||||
RAPIDJSON_DIAG_POP
|
// Not implemented
|
||||||
#endif
|
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
|
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||||
#ifdef __GNUC__
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
RAPIDJSON_DIAG_POP
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
#endif
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
private:
|
||||||
|
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
||||||
|
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
|
||||||
|
|
||||||
|
void PutBOM() {
|
||||||
|
typedef void (*PutBOMFunc)(OutputByteStream&);
|
||||||
|
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
|
||||||
|
f[type_](*os_);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*PutFunc)(OutputByteStream&, Ch);
|
||||||
|
|
||||||
|
OutputByteStream* os_;
|
||||||
|
UTFType type_;
|
||||||
|
PutFunc putFunc_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef RAPIDJSON_ENCODINGS_FUNC
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_FILESTREAM_H_
|
||||||
|
1351
external/rapidjson/encodings.h
vendored
1351
external/rapidjson/encodings.h
vendored
File diff suppressed because it is too large
Load Diff
2
external/rapidjson/error/en.h
vendored
2
external/rapidjson/error/en.h
vendored
@ -38,7 +38,7 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
|||||||
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||||
|
|
||||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
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 kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
||||||
|
|
||||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||||
|
|
||||||
|
198
external/rapidjson/filereadstream.h
vendored
198
external/rapidjson/filereadstream.h
vendored
@ -1,99 +1,99 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FILEREADSTREAM_H_
|
#ifndef RAPIDJSON_FILEREADSTREAM_H_
|
||||||
#define RAPIDJSON_FILEREADSTREAM_H_
|
#define RAPIDJSON_FILEREADSTREAM_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
//! File byte stream for input using fread().
|
//! File byte stream for input using fread().
|
||||||
/*!
|
/*!
|
||||||
\note implements Stream concept
|
\note implements Stream concept
|
||||||
*/
|
*/
|
||||||
class FileReadStream {
|
class FileReadStream {
|
||||||
public:
|
public:
|
||||||
typedef char Ch; //!< Character type (byte).
|
typedef char Ch; //!< Character type (byte).
|
||||||
|
|
||||||
//! Constructor.
|
//! Constructor.
|
||||||
/*!
|
/*!
|
||||||
\param fp File pointer opened for read.
|
\param fp File pointer opened for read.
|
||||||
\param buffer user-supplied buffer.
|
\param buffer user-supplied buffer.
|
||||||
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
||||||
*/
|
*/
|
||||||
FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
||||||
RAPIDJSON_ASSERT(fp_ != 0);
|
RAPIDJSON_ASSERT(fp_ != 0);
|
||||||
RAPIDJSON_ASSERT(bufferSize >= 4);
|
RAPIDJSON_ASSERT(bufferSize >= 4);
|
||||||
Read();
|
Read();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ch Peek() const { return *current_; }
|
Ch Peek() const { return *current_; }
|
||||||
Ch Take() { Ch c = *current_; Read(); return c; }
|
Ch Take() { Ch c = *current_; Read(); return c; }
|
||||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
// For encoding detection only.
|
// For encoding detection only.
|
||||||
const Ch* Peek4() const {
|
const Ch* Peek4() const {
|
||||||
return (current_ + 4 <= bufferLast_) ? current_ : 0;
|
return (current_ + 4 <= bufferLast_) ? current_ : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Read() {
|
void Read() {
|
||||||
if (current_ < bufferLast_)
|
if (current_ < bufferLast_)
|
||||||
++current_;
|
++current_;
|
||||||
else if (!eof_) {
|
else if (!eof_) {
|
||||||
count_ += readCount_;
|
count_ += readCount_;
|
||||||
readCount_ = fread(buffer_, 1, bufferSize_, fp_);
|
readCount_ = fread(buffer_, 1, bufferSize_, fp_);
|
||||||
bufferLast_ = buffer_ + readCount_ - 1;
|
bufferLast_ = buffer_ + readCount_ - 1;
|
||||||
current_ = buffer_;
|
current_ = buffer_;
|
||||||
|
|
||||||
if (readCount_ < bufferSize_) {
|
if (readCount_ < bufferSize_) {
|
||||||
buffer_[readCount_] = '\0';
|
buffer_[readCount_] = '\0';
|
||||||
++bufferLast_;
|
++bufferLast_;
|
||||||
eof_ = true;
|
eof_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::FILE* fp_;
|
std::FILE* fp_;
|
||||||
Ch *buffer_;
|
Ch *buffer_;
|
||||||
size_t bufferSize_;
|
size_t bufferSize_;
|
||||||
Ch *bufferLast_;
|
Ch *bufferLast_;
|
||||||
Ch *current_;
|
Ch *current_;
|
||||||
size_t readCount_;
|
size_t readCount_;
|
||||||
size_t count_; //!< Number of characters read
|
size_t count_; //!< Number of characters read
|
||||||
bool eof_;
|
bool eof_;
|
||||||
};
|
};
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
#endif // RAPIDJSON_FILESTREAM_H_
|
||||||
|
208
external/rapidjson/filewritestream.h
vendored
208
external/rapidjson/filewritestream.h
vendored
@ -1,104 +1,104 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
|
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
|
||||||
#define RAPIDJSON_FILEWRITESTREAM_H_
|
#define RAPIDJSON_FILEWRITESTREAM_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
//! Wrapper of C file stream for input using fread().
|
//! Wrapper of C file stream for input using fread().
|
||||||
/*!
|
/*!
|
||||||
\note implements Stream concept
|
\note implements Stream concept
|
||||||
*/
|
*/
|
||||||
class FileWriteStream {
|
class FileWriteStream {
|
||||||
public:
|
public:
|
||||||
typedef char Ch; //!< Character type. Only support char.
|
typedef char Ch; //!< Character type. Only support char.
|
||||||
|
|
||||||
FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
|
FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
|
||||||
RAPIDJSON_ASSERT(fp_ != 0);
|
RAPIDJSON_ASSERT(fp_ != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Put(char c) {
|
void Put(char c) {
|
||||||
if (current_ >= bufferEnd_)
|
if (current_ >= bufferEnd_)
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
*current_++ = c;
|
*current_++ = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PutN(char c, size_t n) {
|
void PutN(char c, size_t n) {
|
||||||
size_t avail = static_cast<size_t>(bufferEnd_ - current_);
|
size_t avail = static_cast<size_t>(bufferEnd_ - current_);
|
||||||
while (n > avail) {
|
while (n > avail) {
|
||||||
std::memset(current_, c, avail);
|
std::memset(current_, c, avail);
|
||||||
current_ += avail;
|
current_ += avail;
|
||||||
Flush();
|
Flush();
|
||||||
n -= avail;
|
n -= avail;
|
||||||
avail = static_cast<size_t>(bufferEnd_ - current_);
|
avail = static_cast<size_t>(bufferEnd_ - current_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
std::memset(current_, c, n);
|
std::memset(current_, c, n);
|
||||||
current_ += n;
|
current_ += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flush() {
|
void Flush() {
|
||||||
if (current_ != buffer_) {
|
if (current_ != buffer_) {
|
||||||
size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||||
if (result < static_cast<size_t>(current_ - buffer_)) {
|
if (result < static_cast<size_t>(current_ - buffer_)) {
|
||||||
// failure deliberately ignored at this time
|
// failure deliberately ignored at this time
|
||||||
// added to avoid warn_unused_result build errors
|
// added to avoid warn_unused_result build errors
|
||||||
}
|
}
|
||||||
current_ = buffer_;
|
current_ = buffer_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not implemented
|
// Not implemented
|
||||||
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Prohibit copy constructor & assignment operator.
|
// Prohibit copy constructor & assignment operator.
|
||||||
FileWriteStream(const FileWriteStream&);
|
FileWriteStream(const FileWriteStream&);
|
||||||
FileWriteStream& operator=(const FileWriteStream&);
|
FileWriteStream& operator=(const FileWriteStream&);
|
||||||
|
|
||||||
std::FILE* fp_;
|
std::FILE* fp_;
|
||||||
char *buffer_;
|
char *buffer_;
|
||||||
char *bufferEnd_;
|
char *bufferEnd_;
|
||||||
char *current_;
|
char *current_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Implement specialized version of PutN() with memset() for better performance.
|
//! Implement specialized version of PutN() with memset() for better performance.
|
||||||
template<>
|
template<>
|
||||||
inline void PutN(FileWriteStream& stream, char c, size_t n) {
|
inline void PutN(FileWriteStream& stream, char c, size_t n) {
|
||||||
stream.PutN(c, n);
|
stream.PutN(c, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // RAPIDJSON_FILESTREAM_H_
|
#endif // RAPIDJSON_FILESTREAM_H_
|
||||||
|
151
external/rapidjson/fwd.h
vendored
Normal file
151
external/rapidjson/fwd.h
vendored
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_FWD_H_
|
||||||
|
#define RAPIDJSON_FWD_H_
|
||||||
|
|
||||||
|
#include "rapidjson.h"
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
// encodings.h
|
||||||
|
|
||||||
|
template<typename CharType> struct UTF8;
|
||||||
|
template<typename CharType> struct UTF16;
|
||||||
|
template<typename CharType> struct UTF16BE;
|
||||||
|
template<typename CharType> struct UTF16LE;
|
||||||
|
template<typename CharType> struct UTF32;
|
||||||
|
template<typename CharType> struct UTF32BE;
|
||||||
|
template<typename CharType> struct UTF32LE;
|
||||||
|
template<typename CharType> struct ASCII;
|
||||||
|
template<typename CharType> struct AutoUTF;
|
||||||
|
|
||||||
|
template<typename SourceEncoding, typename TargetEncoding>
|
||||||
|
struct Transcoder;
|
||||||
|
|
||||||
|
// allocators.h
|
||||||
|
|
||||||
|
class CrtAllocator;
|
||||||
|
|
||||||
|
template <typename BaseAllocator>
|
||||||
|
class MemoryPoolAllocator;
|
||||||
|
|
||||||
|
// stream.h
|
||||||
|
|
||||||
|
template <typename Encoding>
|
||||||
|
struct GenericStringStream;
|
||||||
|
|
||||||
|
typedef GenericStringStream<UTF8<char> > StringStream;
|
||||||
|
|
||||||
|
template <typename Encoding>
|
||||||
|
struct GenericInsituStringStream;
|
||||||
|
|
||||||
|
typedef GenericInsituStringStream<UTF8<char> > InsituStringStream;
|
||||||
|
|
||||||
|
// stringbuffer.h
|
||||||
|
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
class GenericStringBuffer;
|
||||||
|
|
||||||
|
typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;
|
||||||
|
|
||||||
|
// filereadstream.h
|
||||||
|
|
||||||
|
class FileReadStream;
|
||||||
|
|
||||||
|
// filewritestream.h
|
||||||
|
|
||||||
|
class FileWriteStream;
|
||||||
|
|
||||||
|
// memorybuffer.h
|
||||||
|
|
||||||
|
template <typename Allocator>
|
||||||
|
struct GenericMemoryBuffer;
|
||||||
|
|
||||||
|
typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;
|
||||||
|
|
||||||
|
// memorystream.h
|
||||||
|
|
||||||
|
struct MemoryStream;
|
||||||
|
|
||||||
|
// reader.h
|
||||||
|
|
||||||
|
template<typename Encoding, typename Derived>
|
||||||
|
struct BaseReaderHandler;
|
||||||
|
|
||||||
|
template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>
|
||||||
|
class GenericReader;
|
||||||
|
|
||||||
|
typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
|
||||||
|
|
||||||
|
// writer.h
|
||||||
|
|
||||||
|
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
||||||
|
class Writer;
|
||||||
|
|
||||||
|
// prettywriter.h
|
||||||
|
|
||||||
|
template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
|
||||||
|
class PrettyWriter;
|
||||||
|
|
||||||
|
// document.h
|
||||||
|
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
struct GenericMember;
|
||||||
|
|
||||||
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
|
class GenericMemberIterator;
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
|
struct GenericStringRef;
|
||||||
|
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
class GenericValue;
|
||||||
|
|
||||||
|
typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
|
||||||
|
|
||||||
|
template <typename Encoding, typename Allocator, typename StackAllocator>
|
||||||
|
class GenericDocument;
|
||||||
|
|
||||||
|
typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;
|
||||||
|
|
||||||
|
// pointer.h
|
||||||
|
|
||||||
|
template <typename ValueType, typename Allocator>
|
||||||
|
class GenericPointer;
|
||||||
|
|
||||||
|
typedef GenericPointer<Value, CrtAllocator> Pointer;
|
||||||
|
|
||||||
|
// schema.h
|
||||||
|
|
||||||
|
template <typename SchemaDocumentType>
|
||||||
|
class IGenericRemoteSchemaDocumentProvider;
|
||||||
|
|
||||||
|
template <typename ValueT, typename Allocator>
|
||||||
|
class GenericSchemaDocument;
|
||||||
|
|
||||||
|
typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;
|
||||||
|
typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename SchemaDocumentType,
|
||||||
|
typename OutputHandler,
|
||||||
|
typename StateAllocator>
|
||||||
|
class GenericSchemaValidator;
|
||||||
|
|
||||||
|
typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_RAPIDJSONFWD_H_
|
0
external/rapidjson/internal/biginteger.h
vendored
Executable file → Normal file
0
external/rapidjson/internal/biginteger.h
vendored
Executable file → Normal file
2
external/rapidjson/internal/diyfp.h
vendored
2
external/rapidjson/internal/diyfp.h
vendored
@ -41,7 +41,7 @@ RAPIDJSON_DIAG_OFF(padded)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct DiyFp {
|
struct DiyFp {
|
||||||
DiyFp() {}
|
DiyFp() : f(), e() {}
|
||||||
|
|
||||||
DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}
|
DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}
|
||||||
|
|
||||||
|
42
external/rapidjson/internal/dtoa.h
vendored
42
external/rapidjson/internal/dtoa.h
vendored
@ -29,6 +29,7 @@ namespace internal {
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
|
RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
|
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
|
||||||
@ -101,7 +102,8 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||||||
kappa--;
|
kappa--;
|
||||||
if (p2 < delta) {
|
if (p2 < delta) {
|
||||||
*K += kappa;
|
*K += kappa;
|
||||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-static_cast<int>(kappa)]);
|
int index = -static_cast<int>(kappa);
|
||||||
|
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast<int>(kappa)] : 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,10 +147,10 @@ inline char* WriteExponent(int K, char* buffer) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* Prettify(char* buffer, int length, int k) {
|
inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
|
||||||
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
||||||
|
|
||||||
if (length <= kk && kk <= 21) {
|
if (0 <= k && kk <= 21) {
|
||||||
// 1234e7 -> 12340000000
|
// 1234e7 -> 12340000000
|
||||||
for (int i = length; i < kk; i++)
|
for (int i = length; i < kk; i++)
|
||||||
buffer[i] = '0';
|
buffer[i] = '0';
|
||||||
@ -160,7 +162,16 @@ inline char* Prettify(char* buffer, int length, int k) {
|
|||||||
// 1234e-2 -> 12.34
|
// 1234e-2 -> 12.34
|
||||||
std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
|
std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
|
||||||
buffer[kk] = '.';
|
buffer[kk] = '.';
|
||||||
return &buffer[length + 1];
|
if (0 > k + maxDecimalPlaces) {
|
||||||
|
// When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
|
||||||
|
// Remove extra trailing zeros (at least one) after truncation.
|
||||||
|
for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
|
||||||
|
if (buffer[i] != '0')
|
||||||
|
return &buffer[i + 1];
|
||||||
|
return &buffer[kk + 2]; // Reserve one zero
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return &buffer[length + 1];
|
||||||
}
|
}
|
||||||
else if (-6 < kk && kk <= 0) {
|
else if (-6 < kk && kk <= 0) {
|
||||||
// 1234e-6 -> 0.001234
|
// 1234e-6 -> 0.001234
|
||||||
@ -170,7 +181,23 @@ inline char* Prettify(char* buffer, int length, int k) {
|
|||||||
buffer[1] = '.';
|
buffer[1] = '.';
|
||||||
for (int i = 2; i < offset; i++)
|
for (int i = 2; i < offset; i++)
|
||||||
buffer[i] = '0';
|
buffer[i] = '0';
|
||||||
return &buffer[length + offset];
|
if (length - kk > maxDecimalPlaces) {
|
||||||
|
// When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
|
||||||
|
// Remove extra trailing zeros (at least one) after truncation.
|
||||||
|
for (int i = maxDecimalPlaces + 1; i > 2; i--)
|
||||||
|
if (buffer[i] != '0')
|
||||||
|
return &buffer[i + 1];
|
||||||
|
return &buffer[3]; // Reserve one zero
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return &buffer[length + offset];
|
||||||
|
}
|
||||||
|
else if (kk < -maxDecimalPlaces) {
|
||||||
|
// Truncate to zero
|
||||||
|
buffer[0] = '0';
|
||||||
|
buffer[1] = '.';
|
||||||
|
buffer[2] = '0';
|
||||||
|
return &buffer[3];
|
||||||
}
|
}
|
||||||
else if (length == 1) {
|
else if (length == 1) {
|
||||||
// 1e30
|
// 1e30
|
||||||
@ -186,7 +213,8 @@ inline char* Prettify(char* buffer, int length, int k) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char* dtoa(double value, char* buffer) {
|
inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
|
||||||
|
RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
|
||||||
Double d(value);
|
Double d(value);
|
||||||
if (d.IsZero()) {
|
if (d.IsZero()) {
|
||||||
if (d.Sign())
|
if (d.Sign())
|
||||||
@ -203,7 +231,7 @@ inline char* dtoa(double value, char* buffer) {
|
|||||||
}
|
}
|
||||||
int length, K;
|
int length, K;
|
||||||
Grisu2(value, buffer, &length, &K);
|
Grisu2(value, buffer, &length, &K);
|
||||||
return Prettify(buffer, length, K);
|
return Prettify(buffer, length, K, maxDecimalPlaces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
external/rapidjson/internal/ieee754.h
vendored
1
external/rapidjson/internal/ieee754.h
vendored
@ -40,6 +40,7 @@ public:
|
|||||||
|
|
||||||
bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
|
bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
|
||||||
bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
|
bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
|
||||||
|
bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
|
||||||
bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
|
bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
|
||||||
bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
|
bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
|
||||||
|
|
||||||
|
362
external/rapidjson/internal/meta.h
vendored
362
external/rapidjson/internal/meta.h
vendored
@ -1,181 +1,181 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_META_H_
|
#ifndef RAPIDJSON_INTERNAL_META_H_
|
||||||
#define RAPIDJSON_INTERNAL_META_H_
|
#define RAPIDJSON_INTERNAL_META_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#endif
|
#endif
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(6334)
|
RAPIDJSON_DIAG_OFF(6334)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//@cond RAPIDJSON_INTERNAL
|
//@cond RAPIDJSON_INTERNAL
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
|
// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
|
||||||
template <typename T> struct Void { typedef void Type; };
|
template <typename T> struct Void { typedef void Type; };
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// BoolType, TrueType, FalseType
|
// BoolType, TrueType, FalseType
|
||||||
//
|
//
|
||||||
template <bool Cond> struct BoolType {
|
template <bool Cond> struct BoolType {
|
||||||
static const bool Value = Cond;
|
static const bool Value = Cond;
|
||||||
typedef BoolType Type;
|
typedef BoolType Type;
|
||||||
};
|
};
|
||||||
typedef BoolType<true> TrueType;
|
typedef BoolType<true> TrueType;
|
||||||
typedef BoolType<false> FalseType;
|
typedef BoolType<false> FalseType;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
|
// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
|
||||||
//
|
//
|
||||||
|
|
||||||
template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
|
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 <> 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 <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 <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
|
||||||
|
|
||||||
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
|
template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
|
||||||
template <> struct AndExprCond<true, true> : TrueType {};
|
template <> struct AndExprCond<true, true> : TrueType {};
|
||||||
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
|
template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
|
||||||
template <> struct OrExprCond<false, false> : FalseType {};
|
template <> struct OrExprCond<false, false> : FalseType {};
|
||||||
|
|
||||||
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
|
template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
|
||||||
template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::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 AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
|
||||||
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
|
template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// AddConst, MaybeAddConst, RemoveConst
|
// AddConst, MaybeAddConst, RemoveConst
|
||||||
template <typename T> struct AddConst { typedef const T Type; };
|
template <typename T> struct AddConst { typedef const T Type; };
|
||||||
template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
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 { typedef T Type; };
|
||||||
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// IsSame, IsConst, IsMoreConst, IsPointer
|
// IsSame, IsConst, IsMoreConst, IsPointer
|
||||||
//
|
//
|
||||||
template <typename T, typename U> struct IsSame : FalseType {};
|
template <typename T, typename U> struct IsSame : FalseType {};
|
||||||
template <typename T> struct IsSame<T, T> : TrueType {};
|
template <typename T> struct IsSame<T, T> : TrueType {};
|
||||||
|
|
||||||
template <typename T> struct IsConst : FalseType {};
|
template <typename T> struct IsConst : FalseType {};
|
||||||
template <typename T> struct IsConst<const T> : TrueType {};
|
template <typename T> struct IsConst<const T> : TrueType {};
|
||||||
|
|
||||||
template <typename CT, typename T>
|
template <typename CT, typename T>
|
||||||
struct IsMoreConst
|
struct IsMoreConst
|
||||||
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
|
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
|
||||||
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
|
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
|
||||||
|
|
||||||
template <typename T> struct IsPointer : FalseType {};
|
template <typename T> struct IsPointer : FalseType {};
|
||||||
template <typename T> struct IsPointer<T*> : TrueType {};
|
template <typename T> struct IsPointer<T*> : TrueType {};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// IsBaseOf
|
// IsBaseOf
|
||||||
//
|
//
|
||||||
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
|
|
||||||
template <typename B, typename D> struct IsBaseOf
|
template <typename B, typename D> struct IsBaseOf
|
||||||
: BoolType< ::std::is_base_of<B,D>::value> {};
|
: BoolType< ::std::is_base_of<B,D>::value> {};
|
||||||
|
|
||||||
#else // simplified version adopted from Boost
|
#else // simplified version adopted from Boost
|
||||||
|
|
||||||
template<typename B, typename D> struct IsBaseOfImpl {
|
template<typename B, typename D> struct IsBaseOfImpl {
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
|
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
|
||||||
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
|
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
|
||||||
|
|
||||||
typedef char (&Yes)[1];
|
typedef char (&Yes)[1];
|
||||||
typedef char (&No) [2];
|
typedef char (&No) [2];
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static Yes Check(const D*, T);
|
static Yes Check(const D*, T);
|
||||||
static No Check(const B*, int);
|
static No Check(const B*, int);
|
||||||
|
|
||||||
struct Host {
|
struct Host {
|
||||||
operator const B*() const;
|
operator const B*() const;
|
||||||
operator const D*();
|
operator const D*();
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
|
enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename B, typename D> struct IsBaseOf
|
template <typename B, typename D> struct IsBaseOf
|
||||||
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
|
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
|
||||||
|
|
||||||
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
|
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// EnableIf / DisableIf
|
// EnableIf / DisableIf
|
||||||
//
|
//
|
||||||
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
|
template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
|
||||||
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
||||||
|
|
||||||
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
|
template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
|
||||||
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
|
template <typename T> struct DisableIfCond<true, T> { /* empty */ };
|
||||||
|
|
||||||
template <typename Condition, typename T = void>
|
template <typename Condition, typename T = void>
|
||||||
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
||||||
|
|
||||||
template <typename Condition, typename T = void>
|
template <typename Condition, typename T = void>
|
||||||
struct DisableIf : DisableIfCond<Condition::Value, T> {};
|
struct DisableIf : DisableIfCond<Condition::Value, T> {};
|
||||||
|
|
||||||
// SFINAE helpers
|
// SFINAE helpers
|
||||||
struct SfinaeTag {};
|
struct SfinaeTag {};
|
||||||
template <typename T> struct RemoveSfinaeTag;
|
template <typename T> struct RemoveSfinaeTag;
|
||||||
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
|
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
|
||||||
|
|
||||||
#define RAPIDJSON_REMOVEFPTR_(type) \
|
#define RAPIDJSON_REMOVEFPTR_(type) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
|
typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
|
||||||
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
|
< ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF(cond) \
|
#define RAPIDJSON_ENABLEIF(cond) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF(cond) \
|
#define RAPIDJSON_DISABLEIF(cond) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||||
|
|
||||||
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||||
|
|
||||||
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
||||||
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
|
||||||
<RAPIDJSON_REMOVEFPTR_(cond), \
|
<RAPIDJSON_REMOVEFPTR_(cond), \
|
||||||
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
RAPIDJSON_REMOVEFPTR_(returntype)>::Type
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
//@endcond
|
//@endcond
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // RAPIDJSON_INTERNAL_META_H_
|
#endif // RAPIDJSON_INTERNAL_META_H_
|
||||||
|
110
external/rapidjson/internal/pow10.h
vendored
110
external/rapidjson/internal/pow10.h
vendored
@ -1,55 +1,55 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_POW10_
|
#ifndef RAPIDJSON_POW10_
|
||||||
#define RAPIDJSON_POW10_
|
#define RAPIDJSON_POW10_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
//! Computes integer powers of 10 in double (10.0^n).
|
//! Computes integer powers of 10 in double (10.0^n).
|
||||||
/*! This function uses lookup table for fast and accurate results.
|
/*! This function uses lookup table for fast and accurate results.
|
||||||
\param n non-negative exponent. Must <= 308.
|
\param n non-negative exponent. Must <= 308.
|
||||||
\return 10.0^n
|
\return 10.0^n
|
||||||
*/
|
*/
|
||||||
inline double Pow10(int n) {
|
inline double Pow10(int n) {
|
||||||
static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
|
static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
|
||||||
1e+0,
|
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+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+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+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+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+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+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+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+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+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+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+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+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+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+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+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
|
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
|
||||||
};
|
};
|
||||||
RAPIDJSON_ASSERT(n >= 0 && n <= 308);
|
RAPIDJSON_ASSERT(n >= 0 && n <= 308);
|
||||||
return e[n];
|
return e[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#endif // RAPIDJSON_POW10_
|
#endif // RAPIDJSON_POW10_
|
||||||
|
731
external/rapidjson/internal/regex.h
vendored
Normal file
731
external/rapidjson/internal/regex.h
vendored
Normal file
@ -0,0 +1,731 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_INTERNAL_REGEX_H_
|
||||||
|
#define RAPIDJSON_INTERNAL_REGEX_H_
|
||||||
|
|
||||||
|
#include "../allocators.h"
|
||||||
|
#include "../stream.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
|
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||||
|
#define RAPIDJSON_REGEX_VERBOSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// DecodedStream
|
||||||
|
|
||||||
|
template <typename SourceStream, typename Encoding>
|
||||||
|
class DecodedStream {
|
||||||
|
public:
|
||||||
|
DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); }
|
||||||
|
unsigned Peek() { return codepoint_; }
|
||||||
|
unsigned Take() {
|
||||||
|
unsigned c = codepoint_;
|
||||||
|
if (c) // No further decoding when '\0'
|
||||||
|
Decode();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Decode() {
|
||||||
|
if (!Encoding::Decode(ss_, &codepoint_))
|
||||||
|
codepoint_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceStream& ss_;
|
||||||
|
unsigned codepoint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// GenericRegex
|
||||||
|
|
||||||
|
static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1
|
||||||
|
static const SizeType kRegexInvalidRange = ~SizeType(0);
|
||||||
|
|
||||||
|
template <typename Encoding, typename Allocator>
|
||||||
|
class GenericRegexSearch;
|
||||||
|
|
||||||
|
//! Regular expression engine with subset of ECMAscript grammar.
|
||||||
|
/*!
|
||||||
|
Supported regular expression syntax:
|
||||||
|
- \c ab Concatenation
|
||||||
|
- \c a|b Alternation
|
||||||
|
- \c a? Zero or one
|
||||||
|
- \c a* Zero or more
|
||||||
|
- \c a+ One or more
|
||||||
|
- \c a{3} Exactly 3 times
|
||||||
|
- \c a{3,} At least 3 times
|
||||||
|
- \c a{3,5} 3 to 5 times
|
||||||
|
- \c (ab) Grouping
|
||||||
|
- \c ^a At the beginning
|
||||||
|
- \c a$ At the end
|
||||||
|
- \c . Any character
|
||||||
|
- \c [abc] Character classes
|
||||||
|
- \c [a-c] Character class range
|
||||||
|
- \c [a-z0-9_] Character class combination
|
||||||
|
- \c [^abc] Negated character classes
|
||||||
|
- \c [^a-c] Negated character class range
|
||||||
|
- \c [\b] Backspace (U+0008)
|
||||||
|
- \c \\| \\\\ ... Escape characters
|
||||||
|
- \c \\f Form feed (U+000C)
|
||||||
|
- \c \\n Line feed (U+000A)
|
||||||
|
- \c \\r Carriage return (U+000D)
|
||||||
|
- \c \\t Tab (U+0009)
|
||||||
|
- \c \\v Vertical tab (U+000B)
|
||||||
|
|
||||||
|
\note This is a Thompson NFA engine, implemented with reference to
|
||||||
|
Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).",
|
||||||
|
https://swtch.com/~rsc/regexp/regexp1.html
|
||||||
|
*/
|
||||||
|
template <typename Encoding, typename Allocator = CrtAllocator>
|
||||||
|
class GenericRegex {
|
||||||
|
public:
|
||||||
|
typedef Encoding EncodingType;
|
||||||
|
typedef typename Encoding::Ch Ch;
|
||||||
|
template <typename, typename> friend class GenericRegexSearch;
|
||||||
|
|
||||||
|
GenericRegex(const Ch* source, Allocator* allocator = 0) :
|
||||||
|
states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
|
||||||
|
anchorBegin_(), anchorEnd_()
|
||||||
|
{
|
||||||
|
GenericStringStream<Encoding> ss(source);
|
||||||
|
DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);
|
||||||
|
Parse(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
~GenericRegex() {}
|
||||||
|
|
||||||
|
bool IsValid() const {
|
||||||
|
return root_ != kRegexInvalidState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Operator {
|
||||||
|
kZeroOrOne,
|
||||||
|
kZeroOrMore,
|
||||||
|
kOneOrMore,
|
||||||
|
kConcatenation,
|
||||||
|
kAlternation,
|
||||||
|
kLeftParenthesis
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.'
|
||||||
|
static const unsigned kRangeCharacterClass = 0xFFFFFFFE;
|
||||||
|
static const unsigned kRangeNegationFlag = 0x80000000;
|
||||||
|
|
||||||
|
struct Range {
|
||||||
|
unsigned start; //
|
||||||
|
unsigned end;
|
||||||
|
SizeType next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
SizeType out; //!< Equals to kInvalid for matching state
|
||||||
|
SizeType out1; //!< Equals to non-kInvalid for split
|
||||||
|
SizeType rangeStart;
|
||||||
|
unsigned codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Frag {
|
||||||
|
Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {}
|
||||||
|
SizeType start;
|
||||||
|
SizeType out; //!< link-list of all output states
|
||||||
|
SizeType minIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
State& GetState(SizeType index) {
|
||||||
|
RAPIDJSON_ASSERT(index < stateCount_);
|
||||||
|
return states_.template Bottom<State>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const State& GetState(SizeType index) const {
|
||||||
|
RAPIDJSON_ASSERT(index < stateCount_);
|
||||||
|
return states_.template Bottom<State>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
Range& GetRange(SizeType index) {
|
||||||
|
RAPIDJSON_ASSERT(index < rangeCount_);
|
||||||
|
return ranges_.template Bottom<Range>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Range& GetRange(SizeType index) const {
|
||||||
|
RAPIDJSON_ASSERT(index < rangeCount_);
|
||||||
|
return ranges_.template Bottom<Range>()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
void Parse(DecodedStream<InputStream, Encoding>& ds) {
|
||||||
|
Allocator allocator;
|
||||||
|
Stack<Allocator> operandStack(&allocator, 256); // Frag
|
||||||
|
Stack<Allocator> operatorStack(&allocator, 256); // Operator
|
||||||
|
Stack<Allocator> atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis)
|
||||||
|
|
||||||
|
*atomCountStack.template Push<unsigned>() = 0;
|
||||||
|
|
||||||
|
unsigned codepoint;
|
||||||
|
while (ds.Peek() != 0) {
|
||||||
|
switch (codepoint = ds.Take()) {
|
||||||
|
case '^':
|
||||||
|
anchorBegin_ = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '$':
|
||||||
|
anchorEnd_ = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '|':
|
||||||
|
while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation)
|
||||||
|
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
||||||
|
return;
|
||||||
|
*operatorStack.template Push<Operator>() = kAlternation;
|
||||||
|
*atomCountStack.template Top<unsigned>() = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '(':
|
||||||
|
*operatorStack.template Push<Operator>() = kLeftParenthesis;
|
||||||
|
*atomCountStack.template Push<unsigned>() = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ')':
|
||||||
|
while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis)
|
||||||
|
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
||||||
|
return;
|
||||||
|
if (operatorStack.Empty())
|
||||||
|
return;
|
||||||
|
operatorStack.template Pop<Operator>(1);
|
||||||
|
atomCountStack.template Pop<unsigned>(1);
|
||||||
|
ImplicitConcatenation(atomCountStack, operatorStack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
if (!Eval(operandStack, kZeroOrOne))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
if (!Eval(operandStack, kZeroOrMore))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
if (!Eval(operandStack, kOneOrMore))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '{':
|
||||||
|
{
|
||||||
|
unsigned n, m;
|
||||||
|
if (!ParseUnsigned(ds, &n))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ds.Peek() == ',') {
|
||||||
|
ds.Take();
|
||||||
|
if (ds.Peek() == '}')
|
||||||
|
m = kInfinityQuantifier;
|
||||||
|
else if (!ParseUnsigned(ds, &m) || m < n)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m = n;
|
||||||
|
|
||||||
|
if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')
|
||||||
|
return;
|
||||||
|
ds.Take();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
PushOperand(operandStack, kAnyCharacterClass);
|
||||||
|
ImplicitConcatenation(atomCountStack, operatorStack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
SizeType range;
|
||||||
|
if (!ParseRange(ds, &range))
|
||||||
|
return;
|
||||||
|
SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass);
|
||||||
|
GetState(s).rangeStart = range;
|
||||||
|
*operandStack.template Push<Frag>() = Frag(s, s, s);
|
||||||
|
}
|
||||||
|
ImplicitConcatenation(atomCountStack, operatorStack);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\': // Escape character
|
||||||
|
if (!CharacterEscape(ds, &codepoint))
|
||||||
|
return; // Unsupported escape character
|
||||||
|
// fall through to default
|
||||||
|
|
||||||
|
default: // Pattern character
|
||||||
|
PushOperand(operandStack, codepoint);
|
||||||
|
ImplicitConcatenation(atomCountStack, operatorStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!operatorStack.Empty())
|
||||||
|
if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Link the operand to matching state.
|
||||||
|
if (operandStack.GetSize() == sizeof(Frag)) {
|
||||||
|
Frag* e = operandStack.template Pop<Frag>(1);
|
||||||
|
Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0));
|
||||||
|
root_ = e->start;
|
||||||
|
|
||||||
|
#if RAPIDJSON_REGEX_VERBOSE
|
||||||
|
printf("root: %d\n", root_);
|
||||||
|
for (SizeType i = 0; i < stateCount_ ; i++) {
|
||||||
|
State& s = GetState(i);
|
||||||
|
printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) {
|
||||||
|
State* s = states_.template Push<State>();
|
||||||
|
s->out = out;
|
||||||
|
s->out1 = out1;
|
||||||
|
s->codepoint = codepoint;
|
||||||
|
s->rangeStart = kRegexInvalidRange;
|
||||||
|
return stateCount_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) {
|
||||||
|
SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(s, s, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) {
|
||||||
|
if (*atomCountStack.template Top<unsigned>())
|
||||||
|
*operatorStack.template Push<Operator>() = kConcatenation;
|
||||||
|
(*atomCountStack.template Top<unsigned>())++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeType Append(SizeType l1, SizeType l2) {
|
||||||
|
SizeType old = l1;
|
||||||
|
while (GetState(l1).out != kRegexInvalidState)
|
||||||
|
l1 = GetState(l1).out;
|
||||||
|
GetState(l1).out = l2;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Patch(SizeType l, SizeType s) {
|
||||||
|
for (SizeType next; l != kRegexInvalidState; l = next) {
|
||||||
|
next = GetState(l).out;
|
||||||
|
GetState(l).out = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Eval(Stack<Allocator>& operandStack, Operator op) {
|
||||||
|
switch (op) {
|
||||||
|
case kConcatenation:
|
||||||
|
RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2);
|
||||||
|
{
|
||||||
|
Frag e2 = *operandStack.template Pop<Frag>(1);
|
||||||
|
Frag e1 = *operandStack.template Pop<Frag>(1);
|
||||||
|
Patch(e1.out, e2.start);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case kAlternation:
|
||||||
|
if (operandStack.GetSize() >= sizeof(Frag) * 2) {
|
||||||
|
Frag e2 = *operandStack.template Pop<Frag>(1);
|
||||||
|
Frag e1 = *operandStack.template Pop<Frag>(1);
|
||||||
|
SizeType s = NewState(e1.start, e2.start, 0);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case kZeroOrOne:
|
||||||
|
if (operandStack.GetSize() >= sizeof(Frag)) {
|
||||||
|
Frag e = *operandStack.template Pop<Frag>(1);
|
||||||
|
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case kZeroOrMore:
|
||||||
|
if (operandStack.GetSize() >= sizeof(Frag)) {
|
||||||
|
Frag e = *operandStack.template Pop<Frag>(1);
|
||||||
|
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
||||||
|
Patch(e.out, s);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(s, s, e.minIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
RAPIDJSON_ASSERT(op == kOneOrMore);
|
||||||
|
if (operandStack.GetSize() >= sizeof(Frag)) {
|
||||||
|
Frag e = *operandStack.template Pop<Frag>(1);
|
||||||
|
SizeType s = NewState(kRegexInvalidState, e.start, 0);
|
||||||
|
Patch(e.out, s);
|
||||||
|
*operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) {
|
||||||
|
RAPIDJSON_ASSERT(n <= m);
|
||||||
|
RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag));
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
if (m == 0) // a{0} not support
|
||||||
|
return false;
|
||||||
|
else if (m == kInfinityQuantifier)
|
||||||
|
Eval(operandStack, kZeroOrMore); // a{0,} -> a*
|
||||||
|
else {
|
||||||
|
Eval(operandStack, kZeroOrOne); // a{0,5} -> a?
|
||||||
|
for (unsigned i = 0; i < m - 1; i++)
|
||||||
|
CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a?
|
||||||
|
for (unsigned i = 0; i < m - 1; i++)
|
||||||
|
Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a?
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a
|
||||||
|
CloneTopOperand(operandStack);
|
||||||
|
|
||||||
|
if (m == kInfinityQuantifier)
|
||||||
|
Eval(operandStack, kOneOrMore); // a{3,} -> a a a+
|
||||||
|
else if (m > n) {
|
||||||
|
CloneTopOperand(operandStack); // a{3,5} -> a a a a
|
||||||
|
Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a?
|
||||||
|
for (unsigned i = n; i < m - 1; i++)
|
||||||
|
CloneTopOperand(operandStack); // a{3,5} -> a a a a? a?
|
||||||
|
for (unsigned i = n; i < m; i++)
|
||||||
|
Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a?
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < n - 1; i++)
|
||||||
|
Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a?
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; }
|
||||||
|
|
||||||
|
void CloneTopOperand(Stack<Allocator>& operandStack) {
|
||||||
|
const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation
|
||||||
|
SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_)
|
||||||
|
State* s = states_.template Push<State>(count);
|
||||||
|
memcpy(s, &GetState(src.minIndex), count * sizeof(State));
|
||||||
|
for (SizeType j = 0; j < count; j++) {
|
||||||
|
if (s[j].out != kRegexInvalidState)
|
||||||
|
s[j].out += count;
|
||||||
|
if (s[j].out1 != kRegexInvalidState)
|
||||||
|
s[j].out1 += count;
|
||||||
|
}
|
||||||
|
*operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count);
|
||||||
|
stateCount_ += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) {
|
||||||
|
unsigned r = 0;
|
||||||
|
if (ds.Peek() < '0' || ds.Peek() > '9')
|
||||||
|
return false;
|
||||||
|
while (ds.Peek() >= '0' && ds.Peek() <= '9') {
|
||||||
|
if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295
|
||||||
|
return false; // overflow
|
||||||
|
r = r * 10 + (ds.Take() - '0');
|
||||||
|
}
|
||||||
|
*u = r;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) {
|
||||||
|
bool isBegin = true;
|
||||||
|
bool negate = false;
|
||||||
|
int step = 0;
|
||||||
|
SizeType start = kRegexInvalidRange;
|
||||||
|
SizeType current = kRegexInvalidRange;
|
||||||
|
unsigned codepoint;
|
||||||
|
while ((codepoint = ds.Take()) != 0) {
|
||||||
|
if (isBegin) {
|
||||||
|
isBegin = false;
|
||||||
|
if (codepoint == '^') {
|
||||||
|
negate = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (codepoint) {
|
||||||
|
case ']':
|
||||||
|
if (start == kRegexInvalidRange)
|
||||||
|
return false; // Error: nothing inside []
|
||||||
|
if (step == 2) { // Add trailing '-'
|
||||||
|
SizeType r = NewRange('-');
|
||||||
|
RAPIDJSON_ASSERT(current != kRegexInvalidRange);
|
||||||
|
GetRange(current).next = r;
|
||||||
|
}
|
||||||
|
if (negate)
|
||||||
|
GetRange(start).start |= kRangeNegationFlag;
|
||||||
|
*range = start;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (ds.Peek() == 'b') {
|
||||||
|
ds.Take();
|
||||||
|
codepoint = 0x0008; // Escape backspace character
|
||||||
|
}
|
||||||
|
else if (!CharacterEscape(ds, &codepoint))
|
||||||
|
return false;
|
||||||
|
// fall through to default
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (step) {
|
||||||
|
case 1:
|
||||||
|
if (codepoint == '-') {
|
||||||
|
step++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through to step 0 for other characters
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
SizeType r = NewRange(codepoint);
|
||||||
|
if (current != kRegexInvalidRange)
|
||||||
|
GetRange(current).next = r;
|
||||||
|
if (start == kRegexInvalidRange)
|
||||||
|
start = r;
|
||||||
|
current = r;
|
||||||
|
}
|
||||||
|
step = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
RAPIDJSON_ASSERT(step == 2);
|
||||||
|
GetRange(current).end = codepoint;
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeType NewRange(unsigned codepoint) {
|
||||||
|
Range* r = ranges_.template Push<Range>();
|
||||||
|
r->start = r->end = codepoint;
|
||||||
|
r->next = kRegexInvalidRange;
|
||||||
|
return rangeCount_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) {
|
||||||
|
unsigned codepoint;
|
||||||
|
switch (codepoint = ds.Take()) {
|
||||||
|
case '^':
|
||||||
|
case '$':
|
||||||
|
case '|':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '?':
|
||||||
|
case '*':
|
||||||
|
case '+':
|
||||||
|
case '.':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '\\':
|
||||||
|
*escapedCodepoint = codepoint; return true;
|
||||||
|
case 'f': *escapedCodepoint = 0x000C; return true;
|
||||||
|
case 'n': *escapedCodepoint = 0x000A; return true;
|
||||||
|
case 'r': *escapedCodepoint = 0x000D; return true;
|
||||||
|
case 't': *escapedCodepoint = 0x0009; return true;
|
||||||
|
case 'v': *escapedCodepoint = 0x000B; return true;
|
||||||
|
default:
|
||||||
|
return false; // Unsupported escape character
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack<Allocator> states_;
|
||||||
|
Stack<Allocator> ranges_;
|
||||||
|
SizeType root_;
|
||||||
|
SizeType stateCount_;
|
||||||
|
SizeType rangeCount_;
|
||||||
|
|
||||||
|
static const unsigned kInfinityQuantifier = ~0u;
|
||||||
|
|
||||||
|
// For SearchWithAnchoring()
|
||||||
|
bool anchorBegin_;
|
||||||
|
bool anchorEnd_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename RegexType, typename Allocator = CrtAllocator>
|
||||||
|
class GenericRegexSearch {
|
||||||
|
public:
|
||||||
|
typedef typename RegexType::EncodingType Encoding;
|
||||||
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
|
GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) :
|
||||||
|
regex_(regex), allocator_(allocator), ownAllocator_(0),
|
||||||
|
state0_(allocator, 0), state1_(allocator, 0), stateSet_()
|
||||||
|
{
|
||||||
|
RAPIDJSON_ASSERT(regex_.IsValid());
|
||||||
|
if (!allocator_)
|
||||||
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||||
|
stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));
|
||||||
|
state0_.template Reserve<SizeType>(regex_.stateCount_);
|
||||||
|
state1_.template Reserve<SizeType>(regex_.stateCount_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~GenericRegexSearch() {
|
||||||
|
Allocator::Free(stateSet_);
|
||||||
|
RAPIDJSON_DELETE(ownAllocator_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool Match(InputStream& is) {
|
||||||
|
return SearchWithAnchoring(is, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Match(const Ch* s) {
|
||||||
|
GenericStringStream<Encoding> is(s);
|
||||||
|
return Match(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool Search(InputStream& is) {
|
||||||
|
return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Search(const Ch* s) {
|
||||||
|
GenericStringStream<Encoding> is(s);
|
||||||
|
return Search(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef typename RegexType::State State;
|
||||||
|
typedef typename RegexType::Range Range;
|
||||||
|
|
||||||
|
template <typename InputStream>
|
||||||
|
bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) {
|
||||||
|
DecodedStream<InputStream, Encoding> ds(is);
|
||||||
|
|
||||||
|
state0_.Clear();
|
||||||
|
Stack<Allocator> *current = &state0_, *next = &state1_;
|
||||||
|
const size_t stateSetSize = GetStateSetSize();
|
||||||
|
std::memset(stateSet_, 0, stateSetSize);
|
||||||
|
|
||||||
|
bool matched = AddState(*current, regex_.root_);
|
||||||
|
unsigned codepoint;
|
||||||
|
while (!current->Empty() && (codepoint = ds.Take()) != 0) {
|
||||||
|
std::memset(stateSet_, 0, stateSetSize);
|
||||||
|
next->Clear();
|
||||||
|
matched = false;
|
||||||
|
for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) {
|
||||||
|
const State& sr = regex_.GetState(*s);
|
||||||
|
if (sr.codepoint == codepoint ||
|
||||||
|
sr.codepoint == RegexType::kAnyCharacterClass ||
|
||||||
|
(sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))
|
||||||
|
{
|
||||||
|
matched = AddState(*next, sr.out) || matched;
|
||||||
|
if (!anchorEnd && matched)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!anchorBegin)
|
||||||
|
AddState(*next, regex_.root_);
|
||||||
|
}
|
||||||
|
internal::Swap(current, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetStateSetSize() const {
|
||||||
|
return (regex_.stateCount_ + 31) / 32 * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether the added states is a match state
|
||||||
|
bool AddState(Stack<Allocator>& l, SizeType index) {
|
||||||
|
RAPIDJSON_ASSERT(index != kRegexInvalidState);
|
||||||
|
|
||||||
|
const State& s = regex_.GetState(index);
|
||||||
|
if (s.out1 != kRegexInvalidState) { // Split
|
||||||
|
bool matched = AddState(l, s.out);
|
||||||
|
return AddState(l, s.out1) || matched;
|
||||||
|
}
|
||||||
|
else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) {
|
||||||
|
stateSet_[index >> 5] |= (1 << (index & 31));
|
||||||
|
*l.template PushUnsafe<SizeType>() = index;
|
||||||
|
}
|
||||||
|
return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {
|
||||||
|
bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0;
|
||||||
|
while (rangeIndex != kRegexInvalidRange) {
|
||||||
|
const Range& r = regex_.GetRange(rangeIndex);
|
||||||
|
if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end)
|
||||||
|
return yes;
|
||||||
|
rangeIndex = r.next;
|
||||||
|
}
|
||||||
|
return !yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RegexType& regex_;
|
||||||
|
Allocator* allocator_;
|
||||||
|
Allocator* ownAllocator_;
|
||||||
|
Stack<Allocator> state0_;
|
||||||
|
Stack<Allocator> state1_;
|
||||||
|
uint32_t* stateSet_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef GenericRegex<UTF8<> > Regex;
|
||||||
|
typedef GenericRegexSearch<Regex> RegexSearch;
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_INTERNAL_REGEX_H_
|
426
external/rapidjson/internal/stack.h
vendored
426
external/rapidjson/internal/stack.h
vendored
@ -1,196 +1,230 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_STACK_H_
|
#ifndef RAPIDJSON_INTERNAL_STACK_H_
|
||||||
#define RAPIDJSON_INTERNAL_STACK_H_
|
#define RAPIDJSON_INTERNAL_STACK_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../allocators.h"
|
||||||
#include "swap.h"
|
#include "swap.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
#if defined(__clang__)
|
||||||
namespace internal {
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
#endif
|
||||||
// Stack
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
//! A type-unsafe stack for storing different types of data.
|
namespace internal {
|
||||||
/*! \tparam Allocator Allocator for allocating stack memory.
|
|
||||||
*/
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename Allocator>
|
// Stack
|
||||||
class Stack {
|
|
||||||
public:
|
//! A type-unsafe stack for storing different types of data.
|
||||||
// Optimization note: Do not allocate memory for stack_ in constructor.
|
/*! \tparam Allocator Allocator for allocating stack memory.
|
||||||
// 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) {
|
template <typename Allocator>
|
||||||
RAPIDJSON_ASSERT(stackCapacity > 0);
|
class Stack {
|
||||||
}
|
public:
|
||||||
|
// Optimization note: Do not allocate memory for stack_ in constructor.
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
// Do it lazily when first Push() -> Expand() -> Resize().
|
||||||
Stack(Stack&& rhs)
|
Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
|
||||||
: allocator_(rhs.allocator_),
|
}
|
||||||
ownAllocator_(rhs.ownAllocator_),
|
|
||||||
stack_(rhs.stack_),
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
stackTop_(rhs.stackTop_),
|
Stack(Stack&& rhs)
|
||||||
stackEnd_(rhs.stackEnd_),
|
: allocator_(rhs.allocator_),
|
||||||
initialCapacity_(rhs.initialCapacity_)
|
ownAllocator_(rhs.ownAllocator_),
|
||||||
{
|
stack_(rhs.stack_),
|
||||||
rhs.allocator_ = 0;
|
stackTop_(rhs.stackTop_),
|
||||||
rhs.ownAllocator_ = 0;
|
stackEnd_(rhs.stackEnd_),
|
||||||
rhs.stack_ = 0;
|
initialCapacity_(rhs.initialCapacity_)
|
||||||
rhs.stackTop_ = 0;
|
{
|
||||||
rhs.stackEnd_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.initialCapacity_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
}
|
rhs.stack_ = 0;
|
||||||
#endif
|
rhs.stackTop_ = 0;
|
||||||
|
rhs.stackEnd_ = 0;
|
||||||
~Stack() {
|
rhs.initialCapacity_ = 0;
|
||||||
Destroy();
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
~Stack() {
|
||||||
Stack& operator=(Stack&& rhs) {
|
Destroy();
|
||||||
if (&rhs != this)
|
}
|
||||||
{
|
|
||||||
Destroy();
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
|
Stack& operator=(Stack&& rhs) {
|
||||||
allocator_ = rhs.allocator_;
|
if (&rhs != this)
|
||||||
ownAllocator_ = rhs.ownAllocator_;
|
{
|
||||||
stack_ = rhs.stack_;
|
Destroy();
|
||||||
stackTop_ = rhs.stackTop_;
|
|
||||||
stackEnd_ = rhs.stackEnd_;
|
allocator_ = rhs.allocator_;
|
||||||
initialCapacity_ = rhs.initialCapacity_;
|
ownAllocator_ = rhs.ownAllocator_;
|
||||||
|
stack_ = rhs.stack_;
|
||||||
rhs.allocator_ = 0;
|
stackTop_ = rhs.stackTop_;
|
||||||
rhs.ownAllocator_ = 0;
|
stackEnd_ = rhs.stackEnd_;
|
||||||
rhs.stack_ = 0;
|
initialCapacity_ = rhs.initialCapacity_;
|
||||||
rhs.stackTop_ = 0;
|
|
||||||
rhs.stackEnd_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.initialCapacity_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
}
|
rhs.stack_ = 0;
|
||||||
return *this;
|
rhs.stackTop_ = 0;
|
||||||
}
|
rhs.stackEnd_ = 0;
|
||||||
#endif
|
rhs.initialCapacity_ = 0;
|
||||||
|
}
|
||||||
void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
|
return *this;
|
||||||
internal::Swap(allocator_, rhs.allocator_);
|
}
|
||||||
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
#endif
|
||||||
internal::Swap(stack_, rhs.stack_);
|
|
||||||
internal::Swap(stackTop_, rhs.stackTop_);
|
void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
internal::Swap(stackEnd_, rhs.stackEnd_);
|
internal::Swap(allocator_, rhs.allocator_);
|
||||||
internal::Swap(initialCapacity_, rhs.initialCapacity_);
|
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
||||||
}
|
internal::Swap(stack_, rhs.stack_);
|
||||||
|
internal::Swap(stackTop_, rhs.stackTop_);
|
||||||
void Clear() { stackTop_ = stack_; }
|
internal::Swap(stackEnd_, rhs.stackEnd_);
|
||||||
|
internal::Swap(initialCapacity_, rhs.initialCapacity_);
|
||||||
void ShrinkToFit() {
|
}
|
||||||
if (Empty()) {
|
|
||||||
// If the stack is empty, completely deallocate the memory.
|
void Clear() { stackTop_ = stack_; }
|
||||||
Allocator::Free(stack_);
|
|
||||||
stack_ = 0;
|
void ShrinkToFit() {
|
||||||
stackTop_ = 0;
|
if (Empty()) {
|
||||||
stackEnd_ = 0;
|
// If the stack is empty, completely deallocate the memory.
|
||||||
}
|
Allocator::Free(stack_);
|
||||||
else
|
stack_ = 0;
|
||||||
Resize(GetSize());
|
stackTop_ = 0;
|
||||||
}
|
stackEnd_ = 0;
|
||||||
|
}
|
||||||
// Optimization note: try to minimize the size of this function for force inline.
|
else
|
||||||
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
|
Resize(GetSize());
|
||||||
template<typename T>
|
}
|
||||||
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
|
||||||
// Expand the stack if needed
|
// Optimization note: try to minimize the size of this function for force inline.
|
||||||
if (stackTop_ + sizeof(T) * count >= stackEnd_)
|
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
|
||||||
Expand<T>(count);
|
template<typename T>
|
||||||
|
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
||||||
T* ret = reinterpret_cast<T*>(stackTop_);
|
// Expand the stack if needed
|
||||||
stackTop_ += sizeof(T) * count;
|
if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
|
||||||
return ret;
|
Expand<T>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* Pop(size_t count) {
|
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
||||||
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
|
Reserve<T>(count);
|
||||||
stackTop_ -= count * sizeof(T);
|
return PushUnsafe<T>(count);
|
||||||
return reinterpret_cast<T*>(stackTop_);
|
}
|
||||||
}
|
|
||||||
|
template<typename T>
|
||||||
template<typename T>
|
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
||||||
T* Top() {
|
RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
|
||||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
T* ret = reinterpret_cast<T*>(stackTop_);
|
||||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
stackTop_ += sizeof(T) * count;
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
template<typename T>
|
|
||||||
T* Bottom() { return reinterpret_cast<T*>(stack_); }
|
template<typename T>
|
||||||
|
T* Pop(size_t count) {
|
||||||
bool HasAllocator() const {
|
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
|
||||||
return allocator_ != 0;
|
stackTop_ -= count * sizeof(T);
|
||||||
}
|
return reinterpret_cast<T*>(stackTop_);
|
||||||
|
}
|
||||||
Allocator& GetAllocator() {
|
|
||||||
RAPIDJSON_ASSERT(allocator_);
|
template<typename T>
|
||||||
return *allocator_;
|
T* Top() {
|
||||||
}
|
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
||||||
bool Empty() const { return stackTop_ == stack_; }
|
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
||||||
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
}
|
||||||
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
|
|
||||||
|
template<typename T>
|
||||||
private:
|
const T* Top() const {
|
||||||
template<typename T>
|
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
||||||
void Expand(size_t count) {
|
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
||||||
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
|
}
|
||||||
size_t newCapacity;
|
|
||||||
if (stack_ == 0) {
|
template<typename T>
|
||||||
if (!allocator_)
|
T* End() { return reinterpret_cast<T*>(stackTop_); }
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
|
||||||
newCapacity = initialCapacity_;
|
template<typename T>
|
||||||
} else {
|
const T* End() const { return reinterpret_cast<T*>(stackTop_); }
|
||||||
newCapacity = GetCapacity();
|
|
||||||
newCapacity += (newCapacity + 1) / 2;
|
template<typename T>
|
||||||
}
|
T* Bottom() { return reinterpret_cast<T*>(stack_); }
|
||||||
size_t newSize = GetSize() + sizeof(T) * count;
|
|
||||||
if (newCapacity < newSize)
|
template<typename T>
|
||||||
newCapacity = newSize;
|
const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
|
||||||
|
|
||||||
Resize(newCapacity);
|
bool HasAllocator() const {
|
||||||
}
|
return allocator_ != 0;
|
||||||
|
}
|
||||||
void Resize(size_t newCapacity) {
|
|
||||||
const size_t size = GetSize(); // Backup the current size
|
Allocator& GetAllocator() {
|
||||||
stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
|
RAPIDJSON_ASSERT(allocator_);
|
||||||
stackTop_ = stack_ + size;
|
return *allocator_;
|
||||||
stackEnd_ = stack_ + newCapacity;
|
}
|
||||||
}
|
|
||||||
|
bool Empty() const { return stackTop_ == stack_; }
|
||||||
void Destroy() {
|
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
||||||
Allocator::Free(stack_);
|
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
|
||||||
RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
|
|
||||||
}
|
private:
|
||||||
|
template<typename T>
|
||||||
// Prohibit copy constructor & assignment operator.
|
void Expand(size_t count) {
|
||||||
Stack(const Stack&);
|
// Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
|
||||||
Stack& operator=(const Stack&);
|
size_t newCapacity;
|
||||||
|
if (stack_ == 0) {
|
||||||
Allocator* allocator_;
|
if (!allocator_)
|
||||||
Allocator* ownAllocator_;
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||||
char *stack_;
|
newCapacity = initialCapacity_;
|
||||||
char *stackTop_;
|
} else {
|
||||||
char *stackEnd_;
|
newCapacity = GetCapacity();
|
||||||
size_t initialCapacity_;
|
newCapacity += (newCapacity + 1) / 2;
|
||||||
};
|
}
|
||||||
|
size_t newSize = GetSize() + sizeof(T) * count;
|
||||||
} // namespace internal
|
if (newCapacity < newSize)
|
||||||
RAPIDJSON_NAMESPACE_END
|
newCapacity = newSize;
|
||||||
|
|
||||||
#endif // RAPIDJSON_STACK_H_
|
Resize(newCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resize(size_t newCapacity) {
|
||||||
|
const size_t size = GetSize(); // Backup the current size
|
||||||
|
stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
|
||||||
|
stackTop_ = stack_ + size;
|
||||||
|
stackEnd_ = stack_ + newCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Destroy() {
|
||||||
|
Allocator::Free(stack_);
|
||||||
|
RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prohibit copy constructor & assignment operator.
|
||||||
|
Stack(const Stack&);
|
||||||
|
Stack& operator=(const Stack&);
|
||||||
|
|
||||||
|
Allocator* allocator_;
|
||||||
|
Allocator* ownAllocator_;
|
||||||
|
char *stack_;
|
||||||
|
char *stackTop_;
|
||||||
|
char *stackEnd_;
|
||||||
|
size_t initialCapacity_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_STACK_H_
|
||||||
|
97
external/rapidjson/internal/strfunc.h
vendored
97
external/rapidjson/internal/strfunc.h
vendored
@ -1,39 +1,58 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
|
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||||
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../stream.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
//! Custom strlen() which works on different character types.
|
//! Custom strlen() which works on different character types.
|
||||||
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
|
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
|
||||||
\param s Null-terminated input string.
|
\param s Null-terminated input string.
|
||||||
\return Number of characters in the 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.
|
\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
|
||||||
*/
|
*/
|
||||||
template <typename Ch>
|
template <typename Ch>
|
||||||
inline SizeType StrLen(const Ch* s) {
|
inline SizeType StrLen(const Ch* s) {
|
||||||
const Ch* p = s;
|
RAPIDJSON_ASSERT(s != 0);
|
||||||
while (*p) ++p;
|
const Ch* p = s;
|
||||||
return SizeType(p - s);
|
while (*p) ++p;
|
||||||
}
|
return SizeType(p - s);
|
||||||
|
}
|
||||||
} // namespace internal
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
//! Returns number of code points in a encoded string.
|
||||||
|
template<typename Encoding>
|
||||||
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
|
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
|
||||||
|
RAPIDJSON_ASSERT(s != 0);
|
||||||
|
RAPIDJSON_ASSERT(outCount != 0);
|
||||||
|
GenericStringStream<Encoding> is(s);
|
||||||
|
const typename Encoding::Ch* end = s + length;
|
||||||
|
SizeType count = 0;
|
||||||
|
while (is.src_ < end) {
|
||||||
|
unsigned codepoint;
|
||||||
|
if (!Encoding::Decode(is, &codepoint))
|
||||||
|
return false;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
*outCount = count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||||
|
3
external/rapidjson/internal/strtod.h
vendored
3
external/rapidjson/internal/strtod.h
vendored
@ -15,7 +15,6 @@
|
|||||||
#ifndef RAPIDJSON_STRTOD_
|
#ifndef RAPIDJSON_STRTOD_
|
||||||
#define RAPIDJSON_STRTOD_
|
#define RAPIDJSON_STRTOD_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
|
||||||
#include "ieee754.h"
|
#include "ieee754.h"
|
||||||
#include "biginteger.h"
|
#include "biginteger.h"
|
||||||
#include "diyfp.h"
|
#include "diyfp.h"
|
||||||
@ -143,7 +142,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||||||
size_t remaining = length - i;
|
size_t remaining = length - i;
|
||||||
const unsigned kUlpShift = 3;
|
const unsigned kUlpShift = 3;
|
||||||
const unsigned kUlp = 1 << kUlpShift;
|
const unsigned kUlp = 1 << kUlpShift;
|
||||||
int error = (remaining == 0) ? 0 : kUlp / 2;
|
int64_t error = (remaining == 0) ? 0 : kUlp / 2;
|
||||||
|
|
||||||
DiyFp v(significand, 0);
|
DiyFp v(significand, 0);
|
||||||
v = v.Normalize();
|
v = v.Normalize();
|
||||||
|
83
external/rapidjson/internal/swap.h
vendored
83
external/rapidjson/internal/swap.h
vendored
@ -1,37 +1,46 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_INTERNAL_SWAP_H_
|
#ifndef RAPIDJSON_INTERNAL_SWAP_H_
|
||||||
#define RAPIDJSON_INTERNAL_SWAP_H_
|
#define RAPIDJSON_INTERNAL_SWAP_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
#if defined(__clang__)
|
||||||
namespace internal {
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||||
//! Custom swap() to avoid dependency on C++ <algorithm> header
|
#endif
|
||||||
/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
|
|
||||||
\note This has the same semantics as std::swap().
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
*/
|
namespace internal {
|
||||||
template <typename T>
|
|
||||||
inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
|
//! Custom swap() to avoid dependency on C++ <algorithm> header
|
||||||
T tmp = a;
|
/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
|
||||||
a = b;
|
\note This has the same semantics as std::swap().
|
||||||
b = tmp;
|
*/
|
||||||
}
|
template <typename T>
|
||||||
|
inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
|
||||||
} // namespace internal
|
T tmp = a;
|
||||||
RAPIDJSON_NAMESPACE_END
|
a = b;
|
||||||
|
b = tmp;
|
||||||
#endif // RAPIDJSON_INTERNAL_SWAP_H_
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_INTERNAL_SWAP_H_
|
||||||
|
115
external/rapidjson/istreamwrapper.h
vendored
Normal file
115
external/rapidjson/istreamwrapper.h
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_ISTREAMWRAPPER_H_
|
||||||
|
#define RAPIDJSON_ISTREAMWRAPPER_H_
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept.
|
||||||
|
/*!
|
||||||
|
The classes can be wrapped including but not limited to:
|
||||||
|
|
||||||
|
- \c std::istringstream
|
||||||
|
- \c std::stringstream
|
||||||
|
- \c std::wistringstream
|
||||||
|
- \c std::wstringstream
|
||||||
|
- \c std::ifstream
|
||||||
|
- \c std::fstream
|
||||||
|
- \c std::wifstream
|
||||||
|
- \c std::wfstream
|
||||||
|
|
||||||
|
\tparam StreamType Class derived from \c std::basic_istream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename StreamType>
|
||||||
|
class BasicIStreamWrapper {
|
||||||
|
public:
|
||||||
|
typedef typename StreamType::char_type Ch;
|
||||||
|
BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}
|
||||||
|
|
||||||
|
Ch Peek() const {
|
||||||
|
typename StreamType::int_type c = stream_.peek();
|
||||||
|
return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Ch Take() {
|
||||||
|
typename StreamType::int_type c = stream_.get();
|
||||||
|
if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {
|
||||||
|
count_++;
|
||||||
|
return static_cast<Ch>(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// tellg() may return -1 when failed. So we count by ourself.
|
||||||
|
size_t Tell() const { return count_; }
|
||||||
|
|
||||||
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
|
// For encoding detection only.
|
||||||
|
const Ch* Peek4() const {
|
||||||
|
RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.
|
||||||
|
int i;
|
||||||
|
bool hasError = false;
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
typename StreamType::int_type c = stream_.get();
|
||||||
|
if (c == StreamType::traits_type::eof()) {
|
||||||
|
hasError = true;
|
||||||
|
stream_.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
peekBuffer_[i] = static_cast<Ch>(c);
|
||||||
|
}
|
||||||
|
for (--i; i >= 0; --i)
|
||||||
|
stream_.putback(peekBuffer_[i]);
|
||||||
|
return !hasError ? peekBuffer_ : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BasicIStreamWrapper(const BasicIStreamWrapper&);
|
||||||
|
BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
|
||||||
|
|
||||||
|
StreamType& stream_;
|
||||||
|
size_t count_; //!< Number of characters read. Note:
|
||||||
|
mutable Ch peekBuffer_[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
|
||||||
|
typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(_MSC_VER)
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_ISTREAMWRAPPER_H_
|
2
external/rapidjson/memorybuffer.h
vendored
2
external/rapidjson/memorybuffer.h
vendored
@ -15,7 +15,7 @@
|
|||||||
#ifndef RAPIDJSON_MEMORYBUFFER_H_
|
#ifndef RAPIDJSON_MEMORYBUFFER_H_
|
||||||
#define RAPIDJSON_MEMORYBUFFER_H_
|
#define RAPIDJSON_MEMORYBUFFER_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
#include "internal/stack.h"
|
#include "internal/stack.h"
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
6
external/rapidjson/memorystream.h
vendored
6
external/rapidjson/memorystream.h
vendored
@ -15,7 +15,7 @@
|
|||||||
#ifndef RAPIDJSON_MEMORYSTREAM_H_
|
#ifndef RAPIDJSON_MEMORYSTREAM_H_
|
||||||
#define RAPIDJSON_MEMORYSTREAM_H_
|
#define RAPIDJSON_MEMORYSTREAM_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
@ -42,8 +42,8 @@ struct MemoryStream {
|
|||||||
|
|
||||||
MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
|
MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
|
||||||
|
|
||||||
Ch Peek() const { return (src_ == end_) ? '\0' : *src_; }
|
Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; }
|
||||||
Ch Take() { return (src_ == end_) ? '\0' : *src_++; }
|
Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
|
||||||
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
|
size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
|
||||||
|
|
||||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
81
external/rapidjson/ostreamwrapper.h
vendored
Normal file
81
external/rapidjson/ostreamwrapper.h
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_OSTREAMWRAPPER_H_
|
||||||
|
#define RAPIDJSON_OSTREAMWRAPPER_H_
|
||||||
|
|
||||||
|
#include "stream.h"
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept.
|
||||||
|
/*!
|
||||||
|
The classes can be wrapped including but not limited to:
|
||||||
|
|
||||||
|
- \c std::ostringstream
|
||||||
|
- \c std::stringstream
|
||||||
|
- \c std::wpstringstream
|
||||||
|
- \c std::wstringstream
|
||||||
|
- \c std::ifstream
|
||||||
|
- \c std::fstream
|
||||||
|
- \c std::wofstream
|
||||||
|
- \c std::wfstream
|
||||||
|
|
||||||
|
\tparam StreamType Class derived from \c std::basic_ostream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename StreamType>
|
||||||
|
class BasicOStreamWrapper {
|
||||||
|
public:
|
||||||
|
typedef typename StreamType::char_type Ch;
|
||||||
|
BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}
|
||||||
|
|
||||||
|
void Put(Ch c) {
|
||||||
|
stream_.put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Flush() {
|
||||||
|
stream_.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not implemented
|
||||||
|
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BasicOStreamWrapper(const BasicOStreamWrapper&);
|
||||||
|
BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);
|
||||||
|
|
||||||
|
StreamType& stream_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BasicOStreamWrapper<std::ostream> OStreamWrapper;
|
||||||
|
typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_OSTREAMWRAPPER_H_
|
78
external/rapidjson/pointer.h
vendored
78
external/rapidjson/pointer.h
vendored
@ -23,6 +23,11 @@ RAPIDJSON_DIAG_PUSH
|
|||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
||||||
@ -101,7 +106,7 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Default constructor.
|
//! Default constructor.
|
||||||
GenericPointer() : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
||||||
|
|
||||||
//! Constructor that parses a string or URI fragment representation.
|
//! Constructor that parses a string or URI fragment representation.
|
||||||
/*!
|
/*!
|
||||||
@ -160,7 +165,7 @@ public:
|
|||||||
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
|
||||||
|
|
||||||
//! Copy constructor.
|
//! Copy constructor.
|
||||||
GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||||
*this = rhs;
|
*this = rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +310,9 @@ public:
|
|||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
//! Get the allocator of this pointer.
|
||||||
|
Allocator& GetAllocator() { return *allocator_; }
|
||||||
|
|
||||||
//!@name Tokens
|
//!@name Tokens
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
@ -457,9 +465,18 @@ public:
|
|||||||
//! Query a value in a subtree.
|
//! Query a value in a subtree.
|
||||||
/*!
|
/*!
|
||||||
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
|
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
|
||||||
|
\param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
|
||||||
\return Pointer to the value if it can be resolved. Otherwise null.
|
\return Pointer to the value if it can be resolved. Otherwise null.
|
||||||
|
|
||||||
|
\note
|
||||||
|
There are only 3 situations when a value cannot be resolved:
|
||||||
|
1. A value in the path is not an array nor object.
|
||||||
|
2. An object value does not contain the token.
|
||||||
|
3. A token is out of range of an array value.
|
||||||
|
|
||||||
|
Use unresolvedTokenIndex to retrieve the token index.
|
||||||
*/
|
*/
|
||||||
ValueType* Get(ValueType& root) const {
|
ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
|
||||||
RAPIDJSON_ASSERT(IsValid());
|
RAPIDJSON_ASSERT(IsValid());
|
||||||
ValueType* v = &root;
|
ValueType* v = &root;
|
||||||
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
||||||
@ -468,18 +485,23 @@ public:
|
|||||||
{
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
return 0;
|
break;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
}
|
}
|
||||||
break;
|
continue;
|
||||||
case kArrayType:
|
case kArrayType:
|
||||||
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
|
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
|
||||||
return 0;
|
break;
|
||||||
v = &((*v)[t->index]);
|
v = &((*v)[t->index]);
|
||||||
break;
|
continue;
|
||||||
default:
|
default:
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Error: unresolved token
|
||||||
|
if (unresolvedTokenIndex)
|
||||||
|
*unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@ -489,7 +511,9 @@ public:
|
|||||||
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
|
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
|
||||||
\return Pointer to the value if it can be resolved. Otherwise null.
|
\return Pointer to the value if it can be resolved. Otherwise null.
|
||||||
*/
|
*/
|
||||||
const ValueType* Get(const ValueType& root) const { return Get(const_cast<ValueType&>(root)); }
|
const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
|
||||||
|
return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
|
||||||
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@ -743,8 +767,12 @@ private:
|
|||||||
tokenCount_ = rhs.tokenCount_ + extraToken;
|
tokenCount_ = rhs.tokenCount_ + extraToken;
|
||||||
tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
|
tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
|
||||||
nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
|
nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
|
||||||
std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
|
if (rhs.tokenCount_ > 0) {
|
||||||
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
|
||||||
|
}
|
||||||
|
if (nameBufferSize > 0) {
|
||||||
|
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust pointers to name buffer
|
// Adjust pointers to name buffer
|
||||||
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
||||||
@ -968,11 +996,11 @@ private:
|
|||||||
src_++;
|
src_++;
|
||||||
Ch c = 0;
|
Ch c = 0;
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
c <<= 4;
|
c = static_cast<Ch>(c << 4);
|
||||||
Ch h = *src_;
|
Ch h = *src_;
|
||||||
if (h >= '0' && h <= '9') c += h - '0';
|
if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
|
||||||
else if (h >= 'A' && h <= 'F') c += h - 'A' + 10;
|
else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
|
||||||
else if (h >= 'a' && h <= 'f') c += h - 'a' + 10;
|
else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
|
||||||
else {
|
else {
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1050,23 +1078,23 @@ typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, c
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
|
typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
|
||||||
return pointer.Get(root);
|
return pointer.Get(root, unresolvedTokenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer) {
|
const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
|
||||||
return pointer.Get(root);
|
return pointer.Get(root, unresolvedTokenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename CharType, size_t N>
|
template <typename T, typename CharType, size_t N>
|
||||||
typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N]) {
|
typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
|
||||||
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
|
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename CharType, size_t N>
|
template <typename T, typename CharType, size_t N>
|
||||||
const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N]) {
|
const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
|
||||||
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
|
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1323,4 +1351,8 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // RAPIDJSON_POINTER_H_
|
#endif // RAPIDJSON_POINTER_H_
|
||||||
|
468
external/rapidjson/prettywriter.h
vendored
468
external/rapidjson/prettywriter.h
vendored
@ -1,207 +1,261 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_PRETTYWRITER_H_
|
#ifndef RAPIDJSON_PRETTYWRITER_H_
|
||||||
#define RAPIDJSON_PRETTYWRITER_H_
|
#define RAPIDJSON_PRETTYWRITER_H_
|
||||||
|
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
//! Writer with indentation and spacing.
|
//! Combination of PrettyWriter format flags.
|
||||||
/*!
|
/*! \see PrettyWriter::SetFormatOptions
|
||||||
\tparam OutputStream Type of ouptut os.
|
*/
|
||||||
\tparam SourceEncoding Encoding of source string.
|
enum PrettyFormatOptions {
|
||||||
\tparam TargetEncoding Encoding of output stream.
|
kFormatDefault = 0, //!< Default pretty formatting.
|
||||||
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
kFormatSingleLineArray = 1 //!< Format arrays on a single line.
|
||||||
*/
|
};
|
||||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator>
|
|
||||||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> {
|
//! Writer with indentation and spacing.
|
||||||
public:
|
/*!
|
||||||
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
|
\tparam OutputStream Type of ouptut os.
|
||||||
typedef typename Base::Ch Ch;
|
\tparam SourceEncoding Encoding of source string.
|
||||||
|
\tparam TargetEncoding Encoding of output stream.
|
||||||
//! Constructor
|
\tparam StackAllocator Type of allocator for allocating memory of stack.
|
||||||
/*! \param os Output stream.
|
*/
|
||||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
|
||||||
\param levelDepth Initial capacity of stack.
|
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
|
||||||
*/
|
public:
|
||||||
PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
|
||||||
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
typedef typename Base::Ch Ch;
|
||||||
|
|
||||||
//! Set custom indentation.
|
//! Constructor
|
||||||
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
|
/*! \param os Output stream.
|
||||||
\param indentCharCount Number of indent characters for each indentation level.
|
\param allocator User supplied allocator. If it is null, it will create a private one.
|
||||||
\note The default indentation is 4 spaces.
|
\param levelDepth Initial capacity of stack.
|
||||||
*/
|
*/
|
||||||
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
|
explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
|
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
||||||
indentChar_ = indentChar;
|
|
||||||
indentCharCount_ = indentCharCount;
|
|
||||||
return *this;
|
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
}
|
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
||||||
|
|
||||||
/*! @name Implementation of Handler
|
//! Set custom indentation.
|
||||||
\see Handler
|
/*! \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.
|
||||||
|
*/
|
||||||
bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
|
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
|
||||||
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
|
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
|
||||||
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
|
indentChar_ = indentChar;
|
||||||
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
|
indentCharCount_ = indentCharCount;
|
||||||
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
|
return *this;
|
||||||
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
|
}
|
||||||
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
|
|
||||||
|
//! Set pretty writer formatting options.
|
||||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
/*! \param options Formatting options.
|
||||||
(void)copy;
|
*/
|
||||||
PrettyPrefix(kStringType);
|
PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
|
||||||
return Base::WriteString(str, length);
|
formatOptions_ = options;
|
||||||
}
|
return *this;
|
||||||
|
}
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
bool String(const std::basic_string<Ch>& str) {
|
/*! @name Implementation of Handler
|
||||||
return String(str.data(), SizeType(str.size()));
|
\see Handler
|
||||||
}
|
*/
|
||||||
#endif
|
//@{
|
||||||
|
|
||||||
bool StartObject() {
|
bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
|
||||||
PrettyPrefix(kObjectType);
|
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
|
||||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
|
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
|
||||||
return Base::WriteStartObject();
|
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 Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
|
||||||
|
|
||||||
bool EndObject(SizeType memberCount = 0) {
|
bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
|
||||||
(void)memberCount;
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
(void)copy;
|
||||||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
PrettyPrefix(kNumberType);
|
||||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
return Base::WriteString(str, length);
|
||||||
|
}
|
||||||
if (!empty) {
|
|
||||||
Base::os_->Put('\n');
|
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||||
WriteIndent();
|
RAPIDJSON_ASSERT(str != 0);
|
||||||
}
|
(void)copy;
|
||||||
bool ret = Base::WriteEndObject();
|
PrettyPrefix(kStringType);
|
||||||
(void)ret;
|
return Base::WriteString(str, length);
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
}
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
|
||||||
Base::os_->Flush();
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
return true;
|
bool String(const std::basic_string<Ch>& str) {
|
||||||
}
|
return String(str.data(), SizeType(str.size()));
|
||||||
|
}
|
||||||
bool StartArray() {
|
#endif
|
||||||
PrettyPrefix(kArrayType);
|
|
||||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
|
bool StartObject() {
|
||||||
return Base::WriteStartArray();
|
PrettyPrefix(kObjectType);
|
||||||
}
|
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
|
||||||
|
return Base::WriteStartObject();
|
||||||
bool EndArray(SizeType memberCount = 0) {
|
}
|
||||||
(void)memberCount;
|
|
||||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
|
||||||
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 RAPIDJSON_HAS_STDSTRING
|
||||||
|
bool Key(const std::basic_string<Ch>& str) {
|
||||||
if (!empty) {
|
return Key(str.data(), SizeType(str.size()));
|
||||||
Base::os_->Put('\n');
|
}
|
||||||
WriteIndent();
|
#endif
|
||||||
}
|
|
||||||
bool ret = Base::WriteEndArray();
|
bool EndObject(SizeType memberCount = 0) {
|
||||||
(void)ret;
|
(void)memberCount;
|
||||||
RAPIDJSON_ASSERT(ret == true);
|
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||||
if (Base::level_stack_.Empty()) // end of json text
|
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||||
Base::os_->Flush();
|
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
||||||
return true;
|
|
||||||
}
|
if (!empty) {
|
||||||
|
Base::os_->Put('\n');
|
||||||
//@}
|
WriteIndent();
|
||||||
|
}
|
||||||
/*! @name Convenience extensions */
|
bool ret = Base::WriteEndObject();
|
||||||
//@{
|
(void)ret;
|
||||||
|
RAPIDJSON_ASSERT(ret == true);
|
||||||
//! Simpler but slower overload.
|
if (Base::level_stack_.Empty()) // end of json text
|
||||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
Base::os_->Flush();
|
||||||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
|
return true;
|
||||||
|
}
|
||||||
//@}
|
|
||||||
protected:
|
bool StartArray() {
|
||||||
void PrettyPrefix(Type type) {
|
PrettyPrefix(kArrayType);
|
||||||
(void)type;
|
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
|
||||||
if (Base::level_stack_.GetSize() != 0) { // this value is not at root
|
return Base::WriteStartArray();
|
||||||
typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
|
}
|
||||||
|
|
||||||
if (level->inArray) {
|
bool EndArray(SizeType memberCount = 0) {
|
||||||
if (level->valueCount > 0) {
|
(void)memberCount;
|
||||||
Base::os_->Put(','); // add comma if it is not the first element in array
|
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||||
Base::os_->Put('\n');
|
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||||
}
|
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
||||||
else
|
|
||||||
Base::os_->Put('\n');
|
if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
|
||||||
WriteIndent();
|
Base::os_->Put('\n');
|
||||||
}
|
WriteIndent();
|
||||||
else { // in object
|
}
|
||||||
if (level->valueCount > 0) {
|
bool ret = Base::WriteEndArray();
|
||||||
if (level->valueCount % 2 == 0) {
|
(void)ret;
|
||||||
Base::os_->Put(',');
|
RAPIDJSON_ASSERT(ret == true);
|
||||||
Base::os_->Put('\n');
|
if (Base::level_stack_.Empty()) // end of json text
|
||||||
}
|
Base::os_->Flush();
|
||||||
else {
|
return true;
|
||||||
Base::os_->Put(':');
|
}
|
||||||
Base::os_->Put(' ');
|
|
||||||
}
|
//@}
|
||||||
}
|
|
||||||
else
|
/*! @name Convenience extensions */
|
||||||
Base::os_->Put('\n');
|
//@{
|
||||||
|
|
||||||
if (level->valueCount % 2 == 0)
|
//! Simpler but slower overload.
|
||||||
WriteIndent();
|
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
||||||
}
|
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
|
||||||
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++;
|
|
||||||
}
|
//! Write a raw JSON value.
|
||||||
else {
|
/*!
|
||||||
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
|
For user to write a stringified JSON as a value.
|
||||||
Base::hasRoot_ = true;
|
|
||||||
}
|
\param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
|
||||||
}
|
\param length Length of the json.
|
||||||
|
\param type Type of the root of json.
|
||||||
void WriteIndent() {
|
\note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
|
||||||
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
|
*/
|
||||||
PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
|
bool RawValue(const Ch* json, size_t length, Type type) {
|
||||||
}
|
RAPIDJSON_ASSERT(json != 0);
|
||||||
|
PrettyPrefix(type);
|
||||||
Ch indentChar_;
|
return Base::WriteRawValue(json, length);
|
||||||
unsigned indentCharCount_;
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
// Prohibit copy constructor & assignment operator.
|
void PrettyPrefix(Type type) {
|
||||||
PrettyWriter(const PrettyWriter&);
|
(void)type;
|
||||||
PrettyWriter& operator=(const PrettyWriter&);
|
if (Base::level_stack_.GetSize() != 0) { // this value is not at root
|
||||||
};
|
typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
if (level->inArray) {
|
||||||
|
if (level->valueCount > 0) {
|
||||||
#ifdef __GNUC__
|
Base::os_->Put(','); // add comma if it is not the first element in array
|
||||||
RAPIDJSON_DIAG_POP
|
if (formatOptions_ & kFormatSingleLineArray)
|
||||||
#endif
|
Base::os_->Put(' ');
|
||||||
|
}
|
||||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
|
||||||
|
if (!(formatOptions_ & kFormatSingleLineArray)) {
|
||||||
|
Base::os_->Put('\n');
|
||||||
|
WriteIndent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // in object
|
||||||
|
if (level->valueCount > 0) {
|
||||||
|
if (level->valueCount % 2 == 0) {
|
||||||
|
Base::os_->Put(',');
|
||||||
|
Base::os_->Put('\n');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Base::os_->Put(':');
|
||||||
|
Base::os_->Put(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Base::os_->Put('\n');
|
||||||
|
|
||||||
|
if (level->valueCount % 2 == 0)
|
||||||
|
WriteIndent();
|
||||||
|
}
|
||||||
|
if (!level->inArray && level->valueCount % 2 == 0)
|
||||||
|
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
||||||
|
level->valueCount++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
|
||||||
|
Base::hasRoot_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteIndent() {
|
||||||
|
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
|
||||||
|
PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ch indentChar_;
|
||||||
|
unsigned indentCharCount_;
|
||||||
|
PrettyFormatOptions formatOptions_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Prohibit copy constructor & assignment operator.
|
||||||
|
PrettyWriter(const PrettyWriter&);
|
||||||
|
PrettyWriter& operator=(const PrettyWriter&);
|
||||||
|
};
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_RAPIDJSON_H_
|
||||||
|
1300
external/rapidjson/rapidjson.h
vendored
1300
external/rapidjson/rapidjson.h
vendored
File diff suppressed because it is too large
Load Diff
3399
external/rapidjson/reader.h
vendored
3399
external/rapidjson/reader.h
vendored
File diff suppressed because it is too large
Load Diff
2007
external/rapidjson/schema.h
vendored
Normal file
2007
external/rapidjson/schema.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
179
external/rapidjson/stream.h
vendored
Normal file
179
external/rapidjson/stream.h
vendored
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://opensource.org/licenses/MIT
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#include "rapidjson.h"
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_STREAM_H_
|
||||||
|
#define RAPIDJSON_STREAM_H_
|
||||||
|
|
||||||
|
#include "encodings.h"
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Stream
|
||||||
|
|
||||||
|
/*! \class rapidjson::Stream
|
||||||
|
\brief Concept for reading and writing characters.
|
||||||
|
|
||||||
|
For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
|
||||||
|
|
||||||
|
For write-only stream, only need to implement Put() and Flush().
|
||||||
|
|
||||||
|
\code
|
||||||
|
concept Stream {
|
||||||
|
typename Ch; //!< Character type of the stream.
|
||||||
|
|
||||||
|
//! Read the current character from stream without moving the read cursor.
|
||||||
|
Ch Peek() const;
|
||||||
|
|
||||||
|
//! Read the current character from stream and moving the read cursor to next character.
|
||||||
|
Ch Take();
|
||||||
|
|
||||||
|
//! Get the current read cursor.
|
||||||
|
//! \return Number of characters read from start.
|
||||||
|
size_t Tell();
|
||||||
|
|
||||||
|
//! Begin writing operation at the current read pointer.
|
||||||
|
//! \return The begin writer pointer.
|
||||||
|
Ch* PutBegin();
|
||||||
|
|
||||||
|
//! Write a character.
|
||||||
|
void Put(Ch c);
|
||||||
|
|
||||||
|
//! Flush the buffer.
|
||||||
|
void Flush();
|
||||||
|
|
||||||
|
//! End the writing operation.
|
||||||
|
//! \param begin The begin write pointer returned by PutBegin().
|
||||||
|
//! \return Number of characters written.
|
||||||
|
size_t PutEnd(Ch* begin);
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Provides additional information for stream.
|
||||||
|
/*!
|
||||||
|
By using traits pattern, this type provides a default configuration for stream.
|
||||||
|
For custom stream, this type can be specialized for other configuration.
|
||||||
|
See TEST(Reader, CustomStringStream) in readertest.cpp for example.
|
||||||
|
*/
|
||||||
|
template<typename Stream>
|
||||||
|
struct StreamTraits {
|
||||||
|
//! Whether to make local copy of stream for optimization during parsing.
|
||||||
|
/*!
|
||||||
|
By default, for safety, streams do not use local copy optimization.
|
||||||
|
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
|
||||||
|
*/
|
||||||
|
enum { copyOptimization = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Reserve n characters for writing to a stream.
|
||||||
|
template<typename Stream>
|
||||||
|
inline void PutReserve(Stream& stream, size_t count) {
|
||||||
|
(void)stream;
|
||||||
|
(void)count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Write character to a stream, presuming buffer is reserved.
|
||||||
|
template<typename Stream>
|
||||||
|
inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
|
||||||
|
stream.Put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Put N copies of a character to a stream.
|
||||||
|
template<typename Stream, typename Ch>
|
||||||
|
inline void PutN(Stream& stream, Ch c, size_t n) {
|
||||||
|
PutReserve(stream, n);
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
PutUnsafe(stream, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// StringStream
|
||||||
|
|
||||||
|
//! Read-only string stream.
|
||||||
|
/*! \note implements Stream concept
|
||||||
|
*/
|
||||||
|
template <typename Encoding>
|
||||||
|
struct GenericStringStream {
|
||||||
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
|
GenericStringStream(const Ch *src) : src_(src), head_(src) {}
|
||||||
|
|
||||||
|
Ch Peek() const { return *src_; }
|
||||||
|
Ch Take() { return *src_++; }
|
||||||
|
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
||||||
|
|
||||||
|
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||||
|
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||||
|
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||||
|
|
||||||
|
const Ch* src_; //!< Current read position.
|
||||||
|
const Ch* head_; //!< Original head of the string.
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Encoding>
|
||||||
|
struct StreamTraits<GenericStringStream<Encoding> > {
|
||||||
|
enum { copyOptimization = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
//! String stream with UTF8 encoding.
|
||||||
|
typedef GenericStringStream<UTF8<> > StringStream;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// InsituStringStream
|
||||||
|
|
||||||
|
//! A read-write string stream.
|
||||||
|
/*! This string stream is particularly designed for in-situ parsing.
|
||||||
|
\note implements Stream concept
|
||||||
|
*/
|
||||||
|
template <typename Encoding>
|
||||||
|
struct GenericInsituStringStream {
|
||||||
|
typedef typename Encoding::Ch Ch;
|
||||||
|
|
||||||
|
GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
|
||||||
|
|
||||||
|
// Read
|
||||||
|
Ch Peek() { return *src_; }
|
||||||
|
Ch Take() { return *src_++; }
|
||||||
|
size_t Tell() { return static_cast<size_t>(src_ - head_); }
|
||||||
|
|
||||||
|
// Write
|
||||||
|
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
|
||||||
|
|
||||||
|
Ch* PutBegin() { return dst_ = src_; }
|
||||||
|
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
|
||||||
|
void Flush() {}
|
||||||
|
|
||||||
|
Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
|
||||||
|
void Pop(size_t count) { dst_ -= count; }
|
||||||
|
|
||||||
|
Ch* src_;
|
||||||
|
Ch* dst_;
|
||||||
|
Ch* head_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Encoding>
|
||||||
|
struct StreamTraits<GenericInsituStringStream<Encoding> > {
|
||||||
|
enum { copyOptimization = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Insitu string stream with UTF8 encoding.
|
||||||
|
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_STREAM_H_
|
210
external/rapidjson/stringbuffer.h
vendored
210
external/rapidjson/stringbuffer.h
vendored
@ -1,93 +1,117 @@
|
|||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
// in compliance with the License. You may obtain a copy of the License at
|
// in compliance with the License. You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_STRINGBUFFER_H_
|
#ifndef RAPIDJSON_STRINGBUFFER_H_
|
||||||
#define RAPIDJSON_STRINGBUFFER_H_
|
#define RAPIDJSON_STRINGBUFFER_H_
|
||||||
|
|
||||||
#include "rapidjson.h"
|
#include "stream.h"
|
||||||
|
#include "internal/stack.h"
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
|
||||||
#include <utility> // std::move
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
#endif
|
#include <utility> // std::move
|
||||||
|
#endif
|
||||||
#include "internal/stack.h"
|
|
||||||
|
#include "internal/stack.h"
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
|
||||||
|
#if defined(__clang__)
|
||||||
//! Represents an in-memory output stream.
|
RAPIDJSON_DIAG_PUSH
|
||||||
/*!
|
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||||
\tparam Encoding Encoding of the stream.
|
#endif
|
||||||
\tparam Allocator type for allocating memory buffer.
|
|
||||||
\note implements Stream concept
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
*/
|
|
||||||
template <typename Encoding, typename Allocator = CrtAllocator>
|
//! Represents an in-memory output stream.
|
||||||
class GenericStringBuffer {
|
/*!
|
||||||
public:
|
\tparam Encoding Encoding of the stream.
|
||||||
typedef typename Encoding::Ch Ch;
|
\tparam Allocator type for allocating memory buffer.
|
||||||
|
\note implements Stream concept
|
||||||
GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
|
*/
|
||||||
|
template <typename Encoding, typename Allocator = CrtAllocator>
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
class GenericStringBuffer {
|
||||||
GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
|
public:
|
||||||
GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
|
typedef typename Encoding::Ch Ch;
|
||||||
if (&rhs != this)
|
|
||||||
stack_ = std::move(rhs.stack_);
|
GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
|
||||||
return *this;
|
|
||||||
}
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
#endif
|
GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
|
||||||
|
GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
|
||||||
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
if (&rhs != this)
|
||||||
void Flush() {}
|
stack_ = std::move(rhs.stack_);
|
||||||
|
return *this;
|
||||||
void Clear() { stack_.Clear(); }
|
}
|
||||||
void ShrinkToFit() {
|
#endif
|
||||||
// Push and pop a null terminator. This is safe.
|
|
||||||
*stack_.template Push<Ch>() = '\0';
|
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
||||||
stack_.ShrinkToFit();
|
void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
|
||||||
stack_.template Pop<Ch>(1);
|
void Flush() {}
|
||||||
}
|
|
||||||
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
|
void Clear() { stack_.Clear(); }
|
||||||
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
|
void ShrinkToFit() {
|
||||||
|
// Push and pop a null terminator. This is safe.
|
||||||
const Ch* GetString() const {
|
*stack_.template Push<Ch>() = '\0';
|
||||||
// Push and pop a null terminator. This is safe.
|
stack_.ShrinkToFit();
|
||||||
*stack_.template Push<Ch>() = '\0';
|
stack_.template Pop<Ch>(1);
|
||||||
stack_.template Pop<Ch>(1);
|
}
|
||||||
|
|
||||||
return stack_.template Bottom<Ch>();
|
void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
|
||||||
}
|
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
|
||||||
|
Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }
|
||||||
size_t GetSize() const { return stack_.GetSize(); }
|
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
|
||||||
|
|
||||||
static const size_t kDefaultCapacity = 256;
|
const Ch* GetString() const {
|
||||||
mutable internal::Stack<Allocator> stack_;
|
// Push and pop a null terminator. This is safe.
|
||||||
|
*stack_.template Push<Ch>() = '\0';
|
||||||
private:
|
stack_.template Pop<Ch>(1);
|
||||||
// Prohibit copy constructor & assignment operator.
|
|
||||||
GenericStringBuffer(const GenericStringBuffer&);
|
return stack_.template Bottom<Ch>();
|
||||||
GenericStringBuffer& operator=(const GenericStringBuffer&);
|
}
|
||||||
};
|
|
||||||
|
size_t GetSize() const { return stack_.GetSize(); }
|
||||||
//! String buffer with UTF8 encoding
|
|
||||||
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
static const size_t kDefaultCapacity = 256;
|
||||||
|
mutable internal::Stack<Allocator> stack_;
|
||||||
//! Implement specialized version of PutN() with memset() for better performance.
|
|
||||||
template<>
|
private:
|
||||||
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
// Prohibit copy constructor & assignment operator.
|
||||||
std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
|
GenericStringBuffer(const GenericStringBuffer&);
|
||||||
}
|
GenericStringBuffer& operator=(const GenericStringBuffer&);
|
||||||
|
};
|
||||||
RAPIDJSON_NAMESPACE_END
|
|
||||||
|
//! String buffer with UTF8 encoding
|
||||||
#endif // RAPIDJSON_STRINGBUFFER_H_
|
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
||||||
|
|
||||||
|
template<typename Encoding, typename Allocator>
|
||||||
|
inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
|
||||||
|
stream.Reserve(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Encoding, typename Allocator>
|
||||||
|
inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
|
||||||
|
stream.PutUnsafe(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Implement specialized version of PutN() with memset() for better performance.
|
||||||
|
template<>
|
||||||
|
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
||||||
|
std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
RAPIDJSON_DIAG_POP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_STRINGBUFFER_H_
|
||||||
|
1016
external/rapidjson/writer.h
vendored
1016
external/rapidjson/writer.h
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user