@@ -1,22 +1,8 @@
/* lzoconf.h -- configuration for the LZO real-time data compression library
/* lzoconf.h -- configuration of the LZO data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -43,9 +29,9 @@
#ifndef __LZOCONF_H_INCLUDED
#define __LZOCONF_H_INCLUDED 1

#define LZO_VERSION 0x2040
#define LZO_VERSION_STRING "2.04"
#define LZO_VERSION_DATE "Oct 31 2010"
#define LZO_VERSION 0x20a0 /* 2.10 */
#define LZO_VERSION_STRING "2.10"
#define LZO_VERSION_DATE "Mar 01 2017"

/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
@@ -62,7 +48,7 @@
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
# error "invalid CHAR_BIT"
#endif
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
# error "check your compiler installation"
#endif
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
@@ -71,7 +57,7 @@

/* get OS and architecture defines */
#ifndef __LZODEFS_H_INCLUDED
#include "lzodefs.h"
#include <lzo/lzodefs.h>
#endif


@@ -84,14 +70,6 @@ extern "C" {
// some core defines
************************************************************************/

#if !defined(LZO_UINT32_C)
# if (UINT_MAX < LZO_0xffffffffL)
# define LZO_UINT32_C(c) c ## UL
# else
# define LZO_UINT32_C(c) ((c) + 0U)
# endif
#endif

/* memory checkers */
#if !defined(__LZO_CHECKER)
# if defined(__BOUNDS_CHECKING_ON)
@@ -110,28 +88,35 @@ extern "C" {
// integral and pointer types
************************************************************************/

/* lzo_uint should match size_t */
/* lzo_uint must match size_t */
#if !defined(LZO_UINT_MAX)
# if defined(LZO_ABI_LLP64) /* WIN64 */
# if defined(LZO_OS_WIN64)
# if (LZO_ABI_LLP64)
# if (LZO_OS_WIN64)
typedef unsigned __int64 lzo_uint;
typedef __int64 lzo_int;
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF___INT64
# else
typedef unsigned long long lzo_uint;
typedef long long lzo_int;
typedef lzo_ullong_t lzo_uint;
typedef lzo_llong_t lzo_int;
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG_LONG
# endif
# define LZO_SIZEOF_LZO_INT 8
# define LZO_UINT_MAX 0xffffffffffffffffull
# define LZO_INT_MAX 9223372036854775807LL
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
# elif (LZO_ABI_IP32L64) /* MIPS R5900 */
typedef unsigned int lzo_uint;
typedef int lzo_int;
# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_INT
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_INT
# define LZO_UINT_MAX UINT_MAX
# define LZO_INT_MAX INT_MAX
# define LZO_INT_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint;
typedef long lzo_int;
# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_LONG
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG
# define LZO_UINT_MAX ULONG_MAX
# define LZO_INT_MAX LONG_MAX
# define LZO_INT_MIN LONG_MIN
@@ -140,42 +125,23 @@ extern "C" {
# endif
#endif

/* Integral types with 32 bits or more. */
#if !defined(LZO_UINT32_MAX)
# if (UINT_MAX >= LZO_0xffffffffL)
typedef unsigned int lzo_uint32;
typedef int lzo_int32;
# define LZO_UINT32_MAX UINT_MAX
# define LZO_INT32_MAX INT_MAX
# define LZO_INT32_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint32;
typedef long lzo_int32;
# define LZO_UINT32_MAX ULONG_MAX
# define LZO_INT32_MAX LONG_MAX
# define LZO_INT32_MIN LONG_MIN
# else
# error "lzo_uint32"
# endif
#endif

/* The larger type of lzo_uint and lzo_uint32. */
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
/* The larger type of lzo_uint and lzo_uint32_t. */
#if (LZO_SIZEOF_LZO_INT >= 4)
# define lzo_xint lzo_uint
#else
# define lzo_xint lzo_uint32
# define lzo_xint lzo_uint32_t
#endif

/* Memory model that allows to access memory at offsets of lzo_uint. */
#if !defined(__LZO_MMODEL)
# if (LZO_UINT_MAX <= UINT_MAX)
# define __LZO_MMODEL /*empty*/
# elif defined(LZO_HAVE_MM_HUGE_PTR)
# define __LZO_MMODEL_HUGE 1
# define __LZO_MMODEL __huge
# else
# define __LZO_MMODEL /*empty*/
# endif
typedef int lzo_bool;

/* sanity checks */
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int) == LZO_SIZEOF_LZO_INT)
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_INT)
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t))

#ifndef __LZO_MMODEL
#define __LZO_MMODEL /*empty*/
#endif

/* no typedef here because of const-pointer issues */
@@ -184,17 +150,52 @@ extern "C" {
#define lzo_voidp void __LZO_MMODEL *
#define lzo_shortp short __LZO_MMODEL *
#define lzo_ushortp unsigned short __LZO_MMODEL *
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
#define lzo_int32p lzo_int32 __LZO_MMODEL *
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_xintp lzo_xint __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
#define lzo_byte unsigned char __LZO_MMODEL

typedef int lzo_bool;
#define lzo_int8_tp lzo_int8_t __LZO_MMODEL *
#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL *
#define lzo_int16_tp lzo_int16_t __LZO_MMODEL *
#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL *
#define lzo_int32_tp lzo_int32_t __LZO_MMODEL *
#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL *
#if defined(lzo_int64_t)
#define lzo_int64_tp lzo_int64_t __LZO_MMODEL *
#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL *
#endif

/* Older LZO versions used to support ancient systems and memory models
* such as 16-bit MSDOS with __huge pointers or Cray PVP, but these
* obsolete configurations are not supported any longer.
*/
#if defined(__LZO_MMODEL_HUGE)
#error "__LZO_MMODEL_HUGE memory model is unsupported"
#endif
#if (LZO_MM_PVP)
#error "LZO_MM_PVP memory model is unsupported"
#endif
#if (LZO_SIZEOF_INT < 4)
#error "LZO_SIZEOF_INT < 4 is unsupported"
#endif
#if (__LZO_UINTPTR_T_IS_POINTER)
#error "__LZO_UINTPTR_T_IS_POINTER is unsupported"
#endif
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4)
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4)
/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should
* work but have not received much testing lately, so be strict here.
*/
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp))
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep))


/***********************************************************************
@@ -225,13 +226,13 @@ typedef int lzo_bool;

/* __cdecl calling convention for public C and assembly functions */
#if !defined(LZO_PUBLIC)
# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL
#endif
#if !defined(LZO_EXTERN)
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r)
#endif
#if !defined(LZO_PRIVATE)
# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
# define LZO_PRIVATE(r) static r __LZO_CDECL
#endif

/* function types */
@@ -289,7 +290,7 @@ struct lzo_callback_t
/* a progress indicator callback function (set to 0 to disable) */
lzo_progress_func_t nprogress;

/* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
/* INFO: the first parameter "self" of the nalloc/nfree/nprogress
* callbacks points back to this struct, so you are free to store
* some extra info in the following variables. */
lzo_voidp user1;
@@ -308,14 +309,18 @@ struct lzo_callback_t
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
#define LZO_E_INVALID_ARGUMENT (-10)
#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */
#define LZO_E_OUTPUT_NOT_CONSUMED (-12)
#define LZO_E_INTERNAL_ERROR (-99)


#ifndef lzo_sizeof_dict_t
@@ -329,7 +334,7 @@ struct lzo_callback_t
* compiler's view of various types are consistent.
*/
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
(int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
(int)sizeof(lzo_callback_t))
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
@@ -352,18 +357,22 @@ LZO_EXTERN(lzo_voidp)
lzo_memset(lzo_voidp buf, int c, lzo_uint len);

/* checksum functions */
LZO_EXTERN(lzo_uint32)
lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(lzo_uint32)
lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(const lzo_uint32p)
LZO_EXTERN(lzo_uint32_t)
lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(lzo_uint32_t)
lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(const lzo_uint32_tp)
lzo_get_crc32_table(void);

/* misc. */
LZO_EXTERN(int) _lzo_config_check(void);
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
typedef union {
lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04;
void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09;
#if defined(lzo_int64_t)
lzo_uint64_t a10;
#endif
} lzo_align_t;

/* align a char pointer on a boundary that is a multiple of 'size' */
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
@@ -372,9 +381,34 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);


/***********************************************************************
// deprecated macros - only for backward compatibility with LZO v1.xx
// deprecated macros - only for backward compatibility
************************************************************************/

/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
#define lzo_byte unsigned char
/* deprecated type names */
#define lzo_int32 lzo_int32_t
#define lzo_uint32 lzo_uint32_t
#define lzo_int32p lzo_int32_t __LZO_MMODEL *
#define lzo_uint32p lzo_uint32_t __LZO_MMODEL *
#define LZO_INT32_MAX LZO_INT32_C(2147483647)
#define LZO_UINT32_MAX LZO_UINT32_C(4294967295)
#if defined(lzo_int64_t)
#define lzo_int64 lzo_int64_t
#define lzo_uint64 lzo_uint64_t
#define lzo_int64p lzo_int64_t __LZO_MMODEL *
#define lzo_uint64p lzo_uint64_t __LZO_MMODEL *
#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807)
#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615)
#endif
/* deprecated types */
typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u;
typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u;
/* deprecated defines */
#if !defined(LZO_SIZEOF_LZO_UINT)
# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LZO_INT
#endif

#if defined(LZO_CFG_COMPAT)

#define __LZOCONF_H 1
@@ -416,4 +450,4 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
#endif /* already included */


/* vim:set ts=4 et: */
/* vim:set ts=4 sw=4 et: */

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -2,21 +2,7 @@
This file is part of the LZO real-time data compression library.
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -46,15 +32,25 @@
*/


#ifndef __MINILZO_H
#define __MINILZO_H 1
#ifndef __MINILZO_H_INCLUDED
#define __MINILZO_H_INCLUDED 1

#define MINILZO_VERSION 0x2040
#define MINILZO_VERSION 0x20a0 /* 2.10 */

#ifdef __LZOCONF_H
#if defined(__LZOCONF_H_INCLUDED)
# error "you cannot use both LZO and miniLZO"
#endif

/* internal Autoconf configuration file - only used when building miniLZO */
#ifdef MINILZO_HAVE_CONFIG_H
# include <config.h>
#endif
#include <limits.h>
#include <stddef.h>

#ifndef __LZODEFS_H_INCLUDED
#include "lzodefs.h"
#endif
#undef LZO_HAVE_CONFIG_H
#include "lzoconf.h"

@@ -77,7 +73,7 @@ extern "C" {
*/

#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t))
#define LZO1X_MEM_DECOMPRESS (0)


@@ -106,3 +102,5 @@ lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,

#endif /* already included */


/* vim:set ts=4 sw=4 et: */
@@ -0,0 +1,148 @@
/* testmini.c -- very simple test program for the miniLZO library
This file is part of the LZO real-time data compression library.
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/


#include <stdio.h>
#include <stdlib.h>


/*************************************************************************
// This program shows the basic usage of the LZO library.
// We will compress a block of data and decompress again.
//
// For more information, documentation, example programs and other support
// files (like Makefiles and build scripts) please download the full LZO
// package from
// http://www.oberhumer.com/opensource/lzo/
**************************************************************************/

/* First let's include "minizo.h". */

#include "minilzo.h"


/* We want to compress the data block at 'in' with length 'IN_LEN' to
* the block at 'out'. Because the input block may be incompressible,
* we must provide a little more output space in case that compression
* is not possible.
*/

#define IN_LEN (128*1024ul)
#define OUT_LEN (IN_LEN + IN_LEN / 16 + 64 + 3)

static unsigned char __LZO_MMODEL in [ IN_LEN ];
static unsigned char __LZO_MMODEL out [ OUT_LEN ];


/* Work-memory needed for compression. Allocate memory in units
* of 'lzo_align_t' (instead of 'char') to make sure it is properly aligned.
*/

#define HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]

static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);


/*************************************************************************
//
**************************************************************************/

int main(int argc, char *argv[])
{
int r;
lzo_uint in_len;
lzo_uint out_len;
lzo_uint new_len;

if (argc < 0 && argv == NULL) /* avoid warning about unused args */
return 0;

printf("\nLZO real-time data compression library (v%s, %s).\n",
lzo_version_string(), lzo_version_date());
printf("Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");


/*
* Step 1: initialize the LZO library
*/
if (lzo_init() != LZO_E_OK)
{
printf("internal error - lzo_init() failed !!!\n");
printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");
return 3;
}

/*
* Step 2: prepare the input block that will get compressed.
* We just fill it with zeros in this example program,
* but you would use your real-world data here.
*/
in_len = IN_LEN;
lzo_memset(in,0,in_len);

/*
* Step 3: compress from 'in' to 'out' with LZO1X-1
*/
r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem);
if (r == LZO_E_OK)
printf("compressed %lu bytes into %lu bytes\n",
(unsigned long) in_len, (unsigned long) out_len);
else
{
/* this should NEVER happen */
printf("internal error - compression failed: %d\n", r);
return 2;
}
/* check for an incompressible block */
if (out_len >= in_len)
{
printf("This block contains incompressible data.\n");
return 0;
}

/*
* Step 4: decompress again, now going from 'out' to 'in'
*/
new_len = in_len;
r = lzo1x_decompress(out,out_len,in,&new_len,NULL);
if (r == LZO_E_OK && new_len == in_len)
printf("decompressed %lu bytes back into %lu bytes\n",
(unsigned long) out_len, (unsigned long) in_len);
else
{
/* this should NEVER happen */
printf("internal error - decompression failed: %d\n", r);
return 1;
}

printf("\nminiLZO simple compression test passed.\n");
return 0;
}


/* vim:set ts=4 sw=4 et: */
@@ -52,6 +52,19 @@ concept Allocator {
\endcode
*/


/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
\ingroup RAPIDJSON_CONFIG
\brief User-defined kDefaultChunkCapacity definition.
User can define this as any \c size that is a power of 2.
*/

#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
#endif


///////////////////////////////////////////////////////////////////////////////
// CrtAllocator

@@ -236,7 +249,7 @@ class MemoryPoolAllocator {
*/
bool AddChunk(size_t capacity) {
if (!baseAllocator_)
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
chunk->capacity = capacity;
chunk->size = 0;
@@ -248,7 +261,7 @@ class MemoryPoolAllocator {
return false;
}

static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.

//! Chunk header for perpending to each chunk.
/*! Chunks are stored as a singly linked list.
@@ -0,0 +1,78 @@
// 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_CURSORSTREAMWRAPPER_H_
#define RAPIDJSON_CURSORSTREAMWRAPPER_H_

#include "stream.h"

#if defined(__GNUC__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif

#if defined(_MSC_VER) && _MSC_VER <= 1800
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4702) // unreachable code
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
#endif

RAPIDJSON_NAMESPACE_BEGIN


//! Cursor stream wrapper for counting line and column number if error exists.
/*!
\tparam InputStream Any stream that implements Stream Concept
*/
template <typename InputStream, typename Encoding = UTF8<> >
class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
public:
typedef typename Encoding::Ch Ch;

CursorStreamWrapper(InputStream& is):
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}

// counting line and column number
Ch Take() {
Ch ch = this->is_.Take();
if(ch == '\n') {
line_ ++;
col_ = 0;
} else {
col_ ++;
}
return ch;
}

//! Get the error line number, if error exists.
size_t GetLine() const { return line_; }
//! Get the error column number, if error exists.
size_t GetColumn() const { return col_; }

private:
size_t line_; //!< Current Line
size_t col_; //!< Current Column
};

#if defined(_MSC_VER) && _MSC_VER <= 1800
RAPIDJSON_DIAG_POP
#endif

#if defined(__GNUC__)
RAPIDJSON_DIAG_POP
#endif

RAPIDJSON_NAMESPACE_END

#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_

Large diffs are not rendered by default.

@@ -200,7 +200,7 @@ class AutoUTFInputStream {
// xx xx xx xx UTF-8

if (!hasBOM_) {
unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
switch (pattern) {
case 0x08: type_ = kUTF32BE; break;
case 0x0A: type_ = kUTF16BE; break;
@@ -17,7 +17,7 @@

#include "rapidjson.h"

#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
RAPIDJSON_DIAG_OFF(4702) // unreachable code
@@ -144,9 +144,9 @@ struct UTF8 {

template <typename InputStream>
static bool Decode(InputStream& is, unsigned* codepoint) {
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70)
#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
typename InputStream::Ch c = is.Take();
if (!(c & 0x80)) {
*codepoint = static_cast<unsigned char>(c);
@@ -157,48 +157,48 @@ struct UTF8 {
if (type >= 32) {
*codepoint = 0;
} else {
*codepoint = (0xFF >> type) & static_cast<unsigned char>(c);
*codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
}
bool result = true;
switch (type) {
case 2: TAIL(); return result;
case 3: TAIL(); TAIL(); return result;
case 4: COPY(); TRANS(0x50); TAIL(); return result;
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
case 6: TAIL(); TAIL(); TAIL(); return result;
case 10: COPY(); TRANS(0x20); TAIL(); return result;
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
case 2: RAPIDJSON_TAIL(); return result;
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
default: return false;
}
#undef COPY
#undef TRANS
#undef TAIL
#undef RAPIDJSON_COPY
#undef RAPIDJSON_TRANS
#undef RAPIDJSON_TAIL
}

template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
#define COPY() os.Put(c = is.Take())
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define TAIL() COPY(); TRANS(0x70)
#define RAPIDJSON_COPY() os.Put(c = is.Take())
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
Ch c;
COPY();
RAPIDJSON_COPY();
if (!(c & 0x80))
return true;

bool result = true;
switch (GetRange(static_cast<unsigned char>(c))) {
case 2: TAIL(); return result;
case 3: TAIL(); TAIL(); return result;
case 4: COPY(); TRANS(0x50); TAIL(); return result;
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
case 6: TAIL(); TAIL(); TAIL(); return result;
case 10: COPY(); TRANS(0x20); TAIL(); return result;
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
case 2: RAPIDJSON_TAIL(); return result;
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result;
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result;
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result;
default: return false;
}
#undef COPY
#undef TRANS
#undef TAIL
#undef RAPIDJSON_COPY
#undef RAPIDJSON_TRANS
#undef RAPIDJSON_TAIL
}

static unsigned char GetRange(unsigned char c) {
@@ -283,7 +283,7 @@ struct UTF16 {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
unsigned v = codepoint - 0x10000;
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
os.Put((v & 0x3FF) | 0xDC00);
os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
}
}

@@ -299,7 +299,7 @@ struct UTF16 {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
unsigned v = codepoint - 0x10000;
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
PutUnsafe(os, (v & 0x3FF) | 0xDC00);
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
}
}

@@ -384,7 +384,7 @@ struct UTF16BE : UTF16<CharType> {
static CharType Take(InputByteStream& is) {
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
c |= static_cast<uint8_t>(is.Take());
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
return static_cast<CharType>(c);
}

@@ -620,28 +620,28 @@ struct AutoUTF {
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x

template<typename OutputStream>
RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {
static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {
typedef void (*EncodeFunc)(OutputStream&, unsigned);
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
(*f[os.GetType()])(os, codepoint);
}

template<typename OutputStream>
RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
typedef void (*EncodeFunc)(OutputStream&, unsigned);
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
(*f[os.GetType()])(os, codepoint);
}

template <typename InputStream>
RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {
typedef bool (*DecodeFunc)(InputStream&, unsigned*);
static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
return (*f[is.GetType()])(is, codepoint);
}

template <typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
return (*f[is.GetType()])(is, os);
@@ -658,7 +658,7 @@ template<typename SourceEncoding, typename TargetEncoding>
struct Transcoder {
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
unsigned codepoint;
if (!SourceEncoding::Decode(is, &codepoint))
return false;
@@ -667,7 +667,7 @@ struct Transcoder {
}

template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
unsigned codepoint;
if (!SourceEncoding::Decode(is, &codepoint))
return false;
@@ -677,7 +677,7 @@ struct Transcoder {

//! Validate one Unicode codepoint from an encoded stream.
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
return Transcode(is, os); // Since source/target encoding is different, must transcode.
}
};
@@ -690,26 +690,26 @@ inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
template<typename Encoding>
struct Transcoder<Encoding, Encoding> {
template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class.
return true;
}

template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class.
return true;
}

template<typename InputStream, typename OutputStream>
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
return Encoding::Validate(is, os); // source/target encoding are the same
}
};

RAPIDJSON_NAMESPACE_END

#if defined(__GNUC__) || defined(_MSC_VER)
#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__))
RAPIDJSON_DIAG_POP
#endif

@@ -104,6 +104,8 @@ enum ParseErrorCode {
\see GenericReader::Parse, GenericDocument::Parse
*/
struct ParseResult {
//!! Unspecified boolean type
typedef bool (ParseResult::*BooleanType)() const;
public:
//! Default constructor, no error.
ParseResult() : code_(kParseErrorNone), offset_(0) {}
@@ -115,15 +117,19 @@ struct ParseResult {
//! Get the error offset, if \ref IsError(), 0 otherwise.
size_t Offset() const { return offset_; }

//! Conversion to \c bool, returns \c true, iff !\ref IsError().
operator bool() const { return !IsError(); }
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
//! Whether the result is an error.
bool IsError() const { return code_ != kParseErrorNone; }

bool operator==(const ParseResult& that) const { return code_ == that.code_; }
bool operator==(ParseErrorCode code) const { return code_ == code; }
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }

bool operator!=(const ParseResult& that) const { return !(*this == that); }
bool operator!=(ParseErrorCode code) const { return !(*this == code); }
friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }

//! Reset error code.
void Clear() { Set(kParseErrorNone); }
//! Update error code and offset.
@@ -59,7 +59,7 @@ class FileReadStream {

// For encoding detection only.
const Ch* Peek4() const {
return (current_ + 4 <= bufferLast_) ? current_ : 0;
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
}

private:
@@ -68,7 +68,7 @@ class FileReadStream {
++current_;
else if (!eof_) {
count_ += readCount_;
readCount_ = fread(buffer_, 1, bufferSize_, fp_);
readCount_ = std::fread(buffer_, 1, bufferSize_, fp_);
bufferLast_ = buffer_ + readCount_ - 1;
current_ = buffer_;

@@ -25,7 +25,7 @@ RAPIDJSON_DIAG_OFF(unreachable-code)

RAPIDJSON_NAMESPACE_BEGIN

//! Wrapper of C file stream for input using fread().
//! Wrapper of C file stream for output using fwrite().
/*!
\note implements Stream concept
*/
@@ -62,7 +62,7 @@ class FileWriteStream {

void Flush() {
if (current_ != buffer_) {
size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
size_t result = std::fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
if (result < static_cast<size_t>(current_ - buffer_)) {
// failure deliberately ignored at this time
// added to avoid warn_unused_result build errors
@@ -102,7 +102,7 @@ class PrettyWriter;
// document.h

template <typename Encoding, typename Allocator>
struct GenericMember;
class GenericMember;

template <bool Const, typename Encoding, typename Allocator>
class GenericMemberIterator;
@@ -17,7 +17,7 @@

#include "../rapidjson.h"

#if defined(_MSC_VER) && defined(_M_AMD64)
#if defined(_MSC_VER) && !__INTEL_COMPILER && defined(_M_AMD64)
#include <intrin.h> // for _umul128
#pragma intrinsic(_umul128)
#endif
@@ -133,7 +133,7 @@ class BigInteger {
RAPIDJSON_ASSERT(count_ + offset <= kCapacity);

if (interShift == 0) {
std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
std::memmove(digits_ + offset, digits_, count_ * sizeof(Type));
count_ += offset;
}
else {
@@ -0,0 +1,72 @@
// 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_CLZLL_H_
#define RAPIDJSON_CLZLL_H_

#include "../rapidjson.h"

#if defined(_MSC_VER)
#include <intrin.h>
#if defined(_WIN64)
#pragma intrinsic(_BitScanReverse64)
#else
#pragma intrinsic(_BitScanReverse)
#endif
#endif

RAPIDJSON_NAMESPACE_BEGIN
namespace internal {

#if (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
#define RAPIDJSON_CLZLL __builtin_clzll
#else

inline uint32_t clzll(uint64_t x) {
// Passing 0 to __builtin_clzll is UB in GCC and results in an
// infinite loop in the software implementation.
RAPIDJSON_ASSERT(x != 0);

#if defined(_MSC_VER)
unsigned long r = 0;
#if defined(_WIN64)
_BitScanReverse64(&r, x);
#else
// Scan the high 32 bits.
if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
return 63 - (r + 32);

// Scan the low 32 bits.
_BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF));
#endif // _WIN64

return 63 - r;
#else
uint32_t r;
while (!(x & (static_cast<uint64_t>(1) << 63))) {
x <<= 1;
++r;
}

return r;
#endif // _MSC_VER
}

#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
#endif // (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)

} // namespace internal
RAPIDJSON_NAMESPACE_END

#endif // RAPIDJSON_CLZLL_H_
@@ -1,15 +1,15 @@
// 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
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
@@ -20,10 +20,11 @@
#define RAPIDJSON_DIYFP_H_

#include "../rapidjson.h"
#include "clzll.h"
#include <limits>

#if defined(_MSC_VER) && defined(_M_AMD64)
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
#include <intrin.h>
#pragma intrinsic(_BitScanReverse64)
#pragma intrinsic(_umul128)
#endif

@@ -56,7 +57,7 @@ struct DiyFp {
if (biased_e != 0) {
f = significand + kDpHiddenBit;
e = biased_e - kDpExponentBias;
}
}
else {
f = significand;
e = kDpMinExponent + 1;
@@ -99,21 +100,8 @@ struct DiyFp {
}

DiyFp Normalize() const {
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long index;
_BitScanReverse64(&index, f);
return DiyFp(f << (63 - index), e - (63 - index));
#elif defined(__GNUC__) && __GNUC__ >= 4
int s = __builtin_clzll(f);
int s = static_cast<int>(RAPIDJSON_CLZLL(f));
return DiyFp(f << s, e - s);
#else
DiyFp res = *this;
while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
res.f <<= 1;
res.e--;
}
return res;
#endif
}

DiyFp NormalizeBoundary() const {
@@ -141,7 +129,16 @@ struct DiyFp {
double d;
uint64_t u64;
}u;
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
RAPIDJSON_ASSERT(f <= kDpHiddenBit + kDpSignificandMask);
if (e < kDpDenormalExponent) {
// Underflow.
return 0.0;
}
if (e >= kDpMaxExponent) {
// Overflow.
return std::numeric_limits<double>::infinity();
}
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
static_cast<uint64_t>(e + kDpExponentBias);
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
return u.d;
@@ -220,9 +217,10 @@ inline DiyFp GetCachedPowerByIndex(size_t index) {
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
907, 933, 960, 986, 1013, 1039, 1066
};
RAPIDJSON_ASSERT(index < 87);
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
}

inline DiyFp GetCachedPower(int e, int* K) {

//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
@@ -238,10 +236,11 @@ inline DiyFp GetCachedPower(int e, int* K) {
}

inline DiyFp GetCachedPower10(int exp, int *outExp) {
unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
*outExp = -348 + static_cast<int>(index) * 8;
return GetCachedPowerByIndex(index);
}
RAPIDJSON_ASSERT(exp >= -348);
unsigned index = static_cast<unsigned>(exp + 348) / 8u;
*outExp = -348 + static_cast<int>(index) * 8;
return GetCachedPowerByIndex(index);
}

#ifdef __GNUC__
RAPIDJSON_DIAG_POP
@@ -41,7 +41,7 @@ inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uin
}
}

inline unsigned CountDecimalDigit32(uint32_t n) {
inline int CountDecimalDigit32(uint32_t n) {
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
if (n < 10) return 1;
if (n < 100) return 2;
@@ -63,7 +63,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
const DiyFp wp_w = Mp - W;
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
uint64_t p2 = Mp.f & (one.f - 1);
unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
*len = 0;

while (kappa > 0) {
@@ -102,8 +102,8 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
kappa--;
if (p2 < delta) {
*K += kappa;
int index = -static_cast<int>(kappa);
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast<int>(kappa)] : 0));
int index = -kappa;
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
return;
}
}
@@ -48,13 +48,13 @@ class Double {
int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }

static unsigned EffectiveSignificandSize(int order) {
static int EffectiveSignificandSize(int order) {
if (order >= -1021)
return 53;
else if (order <= -1074)
return 0;
else
return static_cast<unsigned>(order) + 1074;
return order + 1074;
}

private:
@@ -1,15 +1,15 @@
// 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
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#ifndef RAPIDJSON_ITOA_
@@ -37,12 +37,14 @@ inline const char* GetDigitsLut() {
}

inline char* u32toa(uint32_t value, char* buffer) {
RAPIDJSON_ASSERT(buffer != 0);

const char* cDigitsLut = GetDigitsLut();

if (value < 10000) {
const uint32_t d1 = (value / 100) << 1;
const uint32_t d2 = (value % 100) << 1;

if (value >= 1000)
*buffer++ = cDigitsLut[d1];
if (value >= 100)
@@ -55,32 +57,32 @@ inline char* u32toa(uint32_t value, char* buffer) {
// value = bbbbcccc
const uint32_t b = value / 10000;
const uint32_t c = value % 10000;

const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;

const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;

if (value >= 10000000)
*buffer++ = cDigitsLut[d1];
if (value >= 1000000)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= 100000)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];

*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
*buffer++ = cDigitsLut[d4 + 1];
}
else {
// value = aabbbbcccc in decimal

const uint32_t a = value / 100000000; // 1 to 42
value %= 100000000;

if (a >= 10) {
const unsigned i = a << 1;
*buffer++ = cDigitsLut[i];
@@ -91,13 +93,13 @@ inline char* u32toa(uint32_t value, char* buffer) {

const uint32_t b = value / 10000; // 0 to 9999
const uint32_t c = value % 10000; // 0 to 9999

const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;

const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;

*buffer++ = cDigitsLut[d1];
*buffer++ = cDigitsLut[d1 + 1];
*buffer++ = cDigitsLut[d2];
@@ -111,6 +113,7 @@ inline char* u32toa(uint32_t value, char* buffer) {
}

inline char* i32toa(int32_t value, char* buffer) {
RAPIDJSON_ASSERT(buffer != 0);
uint32_t u = static_cast<uint32_t>(value);
if (value < 0) {
*buffer++ = '-';
@@ -121,6 +124,7 @@ inline char* i32toa(int32_t value, char* buffer) {
}

inline char* u64toa(uint64_t value, char* buffer) {
RAPIDJSON_ASSERT(buffer != 0);
const char* cDigitsLut = GetDigitsLut();
const uint64_t kTen8 = 100000000;
const uint64_t kTen9 = kTen8 * 10;
@@ -131,13 +135,13 @@ inline char* u64toa(uint64_t value, char* buffer) {
const uint64_t kTen14 = kTen8 * 1000000;
const uint64_t kTen15 = kTen8 * 10000000;
const uint64_t kTen16 = kTen8 * kTen8;

if (value < kTen8) {
uint32_t v = static_cast<uint32_t>(value);
if (v < 10000) {
const uint32_t d1 = (v / 100) << 1;
const uint32_t d2 = (v % 100) << 1;

if (v >= 1000)
*buffer++ = cDigitsLut[d1];
if (v >= 100)
@@ -150,21 +154,21 @@ inline char* u64toa(uint64_t value, char* buffer) {
// value = bbbbcccc
const uint32_t b = v / 10000;
const uint32_t c = v % 10000;

const uint32_t d1 = (b / 100) << 1;
const uint32_t d2 = (b % 100) << 1;

const uint32_t d3 = (c / 100) << 1;
const uint32_t d4 = (c % 100) << 1;

if (value >= 10000000)
*buffer++ = cDigitsLut[d1];
if (value >= 1000000)
*buffer++ = cDigitsLut[d1 + 1];
if (value >= 100000)
*buffer++ = cDigitsLut[d2];
*buffer++ = cDigitsLut[d2 + 1];

*buffer++ = cDigitsLut[d3];
*buffer++ = cDigitsLut[d3 + 1];
*buffer++ = cDigitsLut[d4];
@@ -174,22 +178,22 @@ inline char* u64toa(uint64_t value, char* buffer) {
else if (value < kTen16) {
const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);

const uint32_t b0 = v0 / 10000;
const uint32_t c0 = v0 % 10000;

const uint32_t d1 = (b0 / 100) << 1;
const uint32_t d2 = (b0 % 100) << 1;

const uint32_t d3 = (c0 / 100) << 1;
const uint32_t d4 = (c0 % 100) << 1;

const uint32_t b1 = v1 / 10000;
const uint32_t c1 = v1 % 10000;

const uint32_t d5 = (b1 / 100) << 1;
const uint32_t d6 = (b1 % 100) << 1;

const uint32_t d7 = (c1 / 100) << 1;
const uint32_t d8 = (c1 % 100) << 1;

@@ -207,9 +211,8 @@ inline char* u64toa(uint64_t value, char* buffer) {
*buffer++ = cDigitsLut[d3 + 1];
if (value >= kTen9)
*buffer++ = cDigitsLut[d4];
if (value >= kTen8)
*buffer++ = cDigitsLut[d4 + 1];


*buffer++ = cDigitsLut[d4 + 1];
*buffer++ = cDigitsLut[d5];
*buffer++ = cDigitsLut[d5 + 1];
*buffer++ = cDigitsLut[d6];
@@ -222,7 +225,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
else {
const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
value %= kTen16;

if (a < 10)
*buffer++ = static_cast<char>('0' + static_cast<char>(a));
else if (a < 100) {
@@ -232,7 +235,7 @@ inline char* u64toa(uint64_t value, char* buffer) {
}
else if (a < 1000) {
*buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));

const uint32_t i = (a % 100) << 1;
*buffer++ = cDigitsLut[i];
*buffer++ = cDigitsLut[i + 1];
@@ -245,28 +248,28 @@ inline char* u64toa(uint64_t value, char* buffer) {
*buffer++ = cDigitsLut[j];
*buffer++ = cDigitsLut[j + 1];
}

const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
const uint32_t v1 = static_cast<uint32_t>(value % kTen8);

const uint32_t b0 = v0 / 10000;
const uint32_t c0 = v0 % 10000;

const uint32_t d1 = (b0 / 100) << 1;
const uint32_t d2 = (b0 % 100) << 1;

const uint32_t d3 = (c0 / 100) << 1;
const uint32_t d4 = (c0 % 100) << 1;

const uint32_t b1 = v1 / 10000;
const uint32_t c1 = v1 % 10000;

const uint32_t d5 = (b1 / 100) << 1;
const uint32_t d6 = (b1 % 100) << 1;

const uint32_t d7 = (c1 / 100) << 1;
const uint32_t d8 = (c1 % 100) << 1;

*buffer++ = cDigitsLut[d1];
*buffer++ = cDigitsLut[d1 + 1];
*buffer++ = cDigitsLut[d2];
@@ -284,11 +287,12 @@ inline char* u64toa(uint64_t value, char* buffer) {
*buffer++ = cDigitsLut[d8];
*buffer++ = cDigitsLut[d8 + 1];
}

return buffer;
}

inline char* i64toa(int64_t value, char* buffer) {
RAPIDJSON_ASSERT(buffer != 0);
uint64_t u = static_cast<uint64_t>(value);
if (value < 0) {
*buffer++ = '-';
@@ -21,7 +21,8 @@
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
#if defined(_MSC_VER)

#if defined(_MSC_VER) && !defined(__clang__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(6334)
#endif
@@ -174,7 +175,11 @@ template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type;
RAPIDJSON_NAMESPACE_END
//@endcond

#if defined(__GNUC__) || defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
RAPIDJSON_DIAG_POP
#endif

#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif

Large diffs are not rendered by default.

@@ -17,6 +17,7 @@

#include "../allocators.h"
#include "swap.h"
#include <cstddef>

#if defined(__clang__)
RAPIDJSON_DIAG_PUSH
@@ -100,7 +101,7 @@ class Stack {
void ShrinkToFit() {
if (Empty()) {
// If the stack is empty, completely deallocate the memory.
Allocator::Free(stack_);
Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
stack_ = 0;
stackTop_ = 0;
stackEnd_ = 0;
@@ -114,7 +115,7 @@ class Stack {
template<typename T>
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
// Expand the stack if needed
if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
Expand<T>(count);
}

@@ -126,7 +127,8 @@ class Stack {

template<typename T>
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
RAPIDJSON_ASSERT(stackTop_);
RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
T* ret = reinterpret_cast<T*>(stackTop_);
stackTop_ += sizeof(T) * count;
return ret;
@@ -183,7 +185,7 @@ class Stack {
size_t newCapacity;
if (stack_ == 0) {
if (!allocator_)
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
newCapacity = initialCapacity_;
} else {
newCapacity = GetCapacity();
@@ -16,6 +16,7 @@
#define RAPIDJSON_INTERNAL_STRFUNC_H_

#include "../stream.h"
#include <cwchar>

RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
@@ -28,14 +29,27 @@ namespace internal {
*/
template <typename Ch>
inline SizeType StrLen(const Ch* s) {
RAPIDJSON_ASSERT(s != 0);
const Ch* p = s;
while (*p) ++p;
return SizeType(p - s);
}

template <>
inline SizeType StrLen(const char* s) {
return SizeType(std::strlen(s));
}

template <>
inline SizeType StrLen(const wchar_t* s) {
return SizeType(std::wcslen(s));
}

//! Returns number of code points in a encoded string.
template<typename Encoding>
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
RAPIDJSON_ASSERT(s != 0);
RAPIDJSON_ASSERT(outCount != 0);
GenericStringStream<Encoding> is(s);
const typename Encoding::Ch* end = s + length;
SizeType count = 0;
@@ -19,6 +19,8 @@
#include "biginteger.h"
#include "diyfp.h"
#include "pow10.h"
#include <climits>
#include <limits>

RAPIDJSON_NAMESPACE_BEGIN
namespace internal {
@@ -126,46 +128,46 @@ inline bool StrtodFast(double d, int p, double* result) {
}

// Compute an approximation and see if it is within 1/2 ULP
inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result) {
uint64_t significand = 0;
size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
for (; i < length; i++) {
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
for (; i < dLen; i++) {
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
break;
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
}

if (i < length && decimals[i] >= '5') // Rounding
if (i < dLen && decimals[i] >= '5') // Rounding
significand++;

size_t remaining = length - i;
const unsigned kUlpShift = 3;
const unsigned kUlp = 1 << kUlpShift;
int remaining = dLen - i;
const int kUlpShift = 3;
const int kUlp = 1 << kUlpShift;
int64_t error = (remaining == 0) ? 0 : kUlp / 2;

DiyFp v(significand, 0);
v = v.Normalize();
error <<= -v.e;

const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
dExp += remaining;

int actualExp;
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
if (actualExp != dExp) {
static const DiyFp kPow10[] = {
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 0x00000000), -60), // 10^1
DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 0x00000000), -57), // 10^2
DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 0x00000000), -54), // 10^3
DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), -50), // 10^4
DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 0x00000000), -47), // 10^5
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 0x00000000), -44), // 10^6
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 0x00000000), -40) // 10^7
};
int adjustment = dExp - actualExp - 1;
RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
v = v * kPow10[adjustment];
if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
int adjustment = dExp - actualExp;
RAPIDJSON_ASSERT(adjustment >= 1 && adjustment < 8);
v = v * kPow10[adjustment - 1];
if (dLen + adjustment > 19) // has more digits than decimal digits in 64-bit
error += kUlp / 2;
}

@@ -177,17 +179,17 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
v = v.Normalize();
error <<= oldExp - v.e;

const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
unsigned precisionSize = 64 - effectiveSignificandSize;
const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
int precisionSize = 64 - effectiveSignificandSize;
if (precisionSize + kUlpShift >= 64) {
unsigned scaleExp = (precisionSize + kUlpShift) - 63;
int scaleExp = (precisionSize + kUlpShift) - 63;
v.f >>= scaleExp;
v.e += scaleExp;
error = (error >> scaleExp) + 1 + static_cast<int>(kUlp);
error = (error >> scaleExp) + 1 + kUlp;
precisionSize -= scaleExp;
}

DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize));
DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
@@ -203,9 +205,9 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
}

inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
const BigInteger dInt(decimals, length);
const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) {
RAPIDJSON_ASSERT(dLen >= 0);
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
Double a(approx);
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
if (cmp < 0)
@@ -225,42 +227,61 @@ inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t
RAPIDJSON_ASSERT(d >= 0.0);
RAPIDJSON_ASSERT(length >= 1);

double result;
double result = 0.0;
if (StrtodFast(d, p, &result))
return result;

RAPIDJSON_ASSERT(length <= INT_MAX);
int dLen = static_cast<int>(length);

RAPIDJSON_ASSERT(length >= decimalPosition);
RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX);
int dExpAdjust = static_cast<int>(length - decimalPosition);

RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust);
int dExp = exp - dExpAdjust;

// Make sure length+dExp does not overflow
RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen);

// Trim leading zeros
while (*decimals == '0' && length > 1) {
length--;
while (dLen > 0 && *decimals == '0') {
dLen--;
decimals++;
decimalPosition--;
}

// Trim trailing zeros
while (decimals[length - 1] == '0' && length > 1) {
length--;
decimalPosition--;
exp++;
while (dLen > 0 && decimals[dLen - 1] == '0') {
dLen--;
dExp++;
}

if (dLen == 0) { // Buffer only contains zeros.
return 0.0;
}

// Trim right-most digits
const int kMaxDecimalDigit = 780;
if (static_cast<int>(length) > kMaxDecimalDigit) {
int delta = (static_cast<int>(length) - kMaxDecimalDigit);
exp += delta;
decimalPosition -= static_cast<unsigned>(delta);
length = kMaxDecimalDigit;
const int kMaxDecimalDigit = 767 + 1;
if (dLen > kMaxDecimalDigit) {
dExp += dLen - kMaxDecimalDigit;
dLen = kMaxDecimalDigit;
}

// If too small, underflow to zero
if (int(length) + exp < -324)
// If too small, underflow to zero.
// Any x <= 10^-324 is interpreted as zero.
if (dLen + dExp <= -324)
return 0.0;

if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
// If too large, overflow to infinity.
// Any x >= 10^309 is interpreted as +infinity.
if (dLen + dExp > 309)
return std::numeric_limits<double>::infinity();

if (StrtodDiyFp(decimals, dLen, dExp, &result))
return result;

// Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
return StrtodBigInteger(result, decimals, dLen, dExp);
}

} // namespace internal
@@ -17,13 +17,12 @@

#include "stream.h"
#include <iosfwd>
#include <ios>

#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(padded)
#endif

#ifdef _MSC_VER
#elif defined(_MSC_VER)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
#endif
@@ -50,57 +49,71 @@ 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';
//! Constructor.
/*!
\param stream stream opened for read.
*/
BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
Read();
}

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';
//! Constructor.
/*!
\param stream stream opened for read.
\param buffer user-supplied buffer.
\param bufferSize size of buffer in bytes. Must >=4 bytes.
*/
BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
RAPIDJSON_ASSERT(bufferSize >= 4);
Read();
}

// tellg() may return -1 when failed. So we count by ourself.
size_t Tell() const { return count_; }
Ch Peek() const { return *current_; }
Ch Take() { Ch c = *current_; Read(); return c; }
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }

Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
// Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }

// For encoding detection only.
const Ch* Peek4() const {
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;
return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
}

private:
BasicIStreamWrapper();
BasicIStreamWrapper(const BasicIStreamWrapper&);
BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);

StreamType& stream_;
size_t count_; //!< Number of characters read. Note:
mutable Ch peekBuffer_[4];
void Read() {
if (current_ < bufferLast_)
++current_;
else if (!eof_) {
count_ += readCount_;
readCount_ = bufferSize_;
bufferLast_ = buffer_ + readCount_ - 1;
current_ = buffer_;

if (!stream_.read(buffer_, static_cast<std::streamsize>(bufferSize_))) {
readCount_ = static_cast<size_t>(stream_.gcount());
*(bufferLast_ = buffer_ + readCount_) = '\0';
eof_ = true;
}
}
}

StreamType &stream_;
Ch peekBuffer_[4], *buffer_;
size_t bufferSize_;
Ch *bufferLast_;
Ch *current_;
size_t readCount_;
size_t count_; //!< Number of characters read
bool eof_;
};

typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
@@ -21,9 +21,7 @@
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(switch-enum)
#endif

#ifdef _MSC_VER
#elif defined(_MSC_VER)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
#endif
@@ -165,7 +163,12 @@ class GenericPointer {
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}

//! Copy constructor.
GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
*this = rhs;
}

//! Copy constructor.
GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
*this = rhs;
}

@@ -197,6 +200,36 @@ class GenericPointer {
return *this;
}

//! Swap the content of this pointer with an other.
/*!
\param other The pointer to swap with.
\note Constant complexity.
*/
GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
internal::Swap(allocator_, other.allocator_);
internal::Swap(ownAllocator_, other.ownAllocator_);
internal::Swap(nameBuffer_, other.nameBuffer_);
internal::Swap(tokens_, other.tokens_);
internal::Swap(tokenCount_, other.tokenCount_);
internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
internal::Swap(parseErrorCode_, other.parseErrorCode_);
return *this;
}

//! free-standing swap function helper
/*!
Helper function to enable support for common swap implementation pattern based on \c std::swap:
\code
void swap(MyClass& a, MyClass& b) {
using std::swap;
swap(a.pointer, b.pointer);
// ...
}
\endcode
\see Swap()
*/
friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }

//@}

//!@name Append token
@@ -240,7 +273,7 @@ class GenericPointer {
template <typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
Append(T* name, Allocator* allocator = 0) const {
return Append(name, StrLen(name), allocator);
return Append(name, internal::StrLen(name), allocator);
}

#if RAPIDJSON_HAS_STDSTRING
@@ -274,7 +307,7 @@ class GenericPointer {
else {
Ch name[21];
for (size_t i = 0; i <= length; i++)
name[i] = buffer[i];
name[i] = static_cast<Ch>(buffer[i]);
Token token = { name, length, index };
return Append(token, allocator);
}
@@ -353,6 +386,33 @@ class GenericPointer {
*/
bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }

//! Less than operator.
/*!
\note Invalid pointers are always greater than valid ones.
*/
bool operator<(const GenericPointer& rhs) const {
if (!IsValid())
return false;
if (!rhs.IsValid())
return true;

if (tokenCount_ != rhs.tokenCount_)
return tokenCount_ < rhs.tokenCount_;

for (size_t i = 0; i < tokenCount_; i++) {
if (tokens_[i].index != rhs.tokens_[i].index)
return tokens_[i].index < rhs.tokens_[i].index;

if (tokens_[i].length != rhs.tokens_[i].length)
return tokens_[i].length < rhs.tokens_[i].length;

if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
return cmp < 0;
}

return false;
}

//@}

//!@name Stringify
@@ -428,10 +488,11 @@ class GenericPointer {
v = &((*v)[t->index]);
}
else {
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
if (m == v->MemberEnd()) {
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
m = v->MemberEnd();
v = &(--m)->value; // Assumes AddMember() appends at the end
exist = false;
}
else
@@ -483,7 +544,7 @@ class GenericPointer {
switch (v->GetType()) {
case kObjectType:
{
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
if (m == v->MemberEnd())
break;
v = &m->value;
@@ -532,22 +593,22 @@ class GenericPointer {
*/
ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
bool alreadyExist;
Value& v = Create(root, allocator, &alreadyExist);
ValueType& v = Create(root, allocator, &alreadyExist);
return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
}

//! Query a value in a subtree with default null-terminated string.
ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
bool alreadyExist;
Value& v = Create(root, allocator, &alreadyExist);
ValueType& v = Create(root, allocator, &alreadyExist);
return alreadyExist ? v : v.SetString(defaultValue, allocator);
}

#if RAPIDJSON_HAS_STDSTRING
//! Query a value in a subtree with default std::basic_string.
ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
bool alreadyExist;
Value& v = Create(root, allocator, &alreadyExist);
ValueType& v = Create(root, allocator, &alreadyExist);
return alreadyExist ? v : v.SetString(defaultValue, allocator);
}
#endif
@@ -719,7 +780,7 @@ class GenericPointer {
switch (v->GetType()) {
case kObjectType:
{
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
if (m == v->MemberEnd())
return false;
v = &m->value;
@@ -758,7 +819,7 @@ class GenericPointer {
*/
Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
if (!allocator_) // allocator is independently owned.
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();

size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
@@ -806,7 +867,7 @@ class GenericPointer {

// Create own allocator if user did not supply.
if (!allocator_)
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();

// Count number of '/' as tokenCount
tokenCount_ = 0;
@@ -1029,8 +1090,8 @@ class GenericPointer {
unsigned char u = static_cast<unsigned char>(c);
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
os_.Put('%');
os_.Put(hexDigits[u >> 4]);
os_.Put(hexDigits[u & 15]);
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
}
private:
OutputStream& os_;
@@ -1347,11 +1408,7 @@ bool EraseValueByPointer(T& root, const CharType(&source)[N]) {

RAPIDJSON_NAMESPACE_END

#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif

#ifdef _MSC_VER
#if defined(__clang__) || defined(_MSC_VER)
RAPIDJSON_DIAG_POP
#endif

@@ -22,6 +22,11 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif

#if defined(__clang__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(c++98-compat)
#endif

RAPIDJSON_NAMESPACE_BEGIN

//! Combination of PrettyWriter format flags.
@@ -34,15 +39,15 @@ enum PrettyFormatOptions {

//! Writer with indentation and spacing.
/*!
\tparam OutputStream Type of ouptut os.
\tparam OutputStream Type of output os.
\tparam SourceEncoding Encoding of source string.
\tparam TargetEncoding Encoding of output stream.
\tparam StackAllocator Type of allocator for allocating memory of stack.
*/
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
public:
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base;
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;
typedef typename Base::Ch Ch;

//! Constructor
@@ -57,6 +62,11 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}

#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
PrettyWriter(PrettyWriter&& rhs) :
Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
#endif

//! Set custom indentation.
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
\param indentCharCount Number of indent characters for each indentation level.
@@ -82,24 +92,26 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
*/
//@{

bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
bool Null() { PrettyPrefix(kNullType); return Base::EndValue(Base::WriteNull()); }
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::EndValue(Base::WriteBool(b)); }
bool Int(int i) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt(i)); }
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint(u)); }
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteInt64(i64)); }
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteUint64(u64)); }
bool Double(double d) { PrettyPrefix(kNumberType); return Base::EndValue(Base::WriteDouble(d)); }

bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
RAPIDJSON_ASSERT(str != 0);
(void)copy;
PrettyPrefix(kNumberType);
return Base::WriteString(str, length);
return Base::EndValue(Base::WriteString(str, length));
}

bool String(const Ch* str, SizeType length, bool copy = false) {
RAPIDJSON_ASSERT(str != 0);
(void)copy;
PrettyPrefix(kStringType);
return Base::WriteString(str, length);
return Base::EndValue(Base::WriteString(str, length));
}

#if RAPIDJSON_HAS_STDSTRING
@@ -124,19 +136,21 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,

bool EndObject(SizeType memberCount = 0) {
(void)memberCount;
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value

bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;

if (!empty) {
Base::os_->Put('\n');
WriteIndent();
}
bool ret = Base::WriteEndObject();
bool ret = Base::EndValue(Base::WriteEndObject());
(void)ret;
RAPIDJSON_ASSERT(ret == true);
if (Base::level_stack_.Empty()) // end of json text
Base::os_->Flush();
Base::Flush();
return true;
}

@@ -156,11 +170,11 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
Base::os_->Put('\n');
WriteIndent();
}
bool ret = Base::WriteEndArray();
bool ret = Base::EndValue(Base::WriteEndArray());
(void)ret;
RAPIDJSON_ASSERT(ret == true);
if (Base::level_stack_.Empty()) // end of json text
Base::os_->Flush();
Base::Flush();
return true;
}

@@ -184,7 +198,11 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,
\param type Type of the root of json.
\note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
*/
bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type); return Base::WriteRawValue(json, length); }
bool RawValue(const Ch* json, size_t length, Type type) {
RAPIDJSON_ASSERT(json != 0);
PrettyPrefix(type);
return Base::EndValue(Base::WriteRawValue(json, length));
}

protected:
void PrettyPrefix(Type type) {
@@ -233,7 +251,7 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,

void WriteIndent() {
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
}

Ch indentChar_;
@@ -248,6 +266,10 @@ class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding,

RAPIDJSON_NAMESPACE_END

#if defined(__clang__)
RAPIDJSON_DIAG_POP
#endif

#ifdef __GNUC__
RAPIDJSON_DIAG_POP
#endif
@@ -26,7 +26,7 @@
Some RapidJSON features are configurable to adapt the library to a wide
variety of platforms, environments and usage scenarios. Most of the
features can be configured in terms of overriden or predefined
features can be configured in terms of overridden or predefined
preprocessor macros at compile-time.
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
@@ -49,6 +49,11 @@
// token stringification
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
#define RAPIDJSON_DO_STRINGIFY(x) #x

// token concatenation
#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
//!@endcond

/*! \def RAPIDJSON_MAJOR_VERSION
@@ -214,7 +219,7 @@
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
# endif // __BYTE_ORDER__
// Detect with GLIBC's endian.h
# elif defined(__GLIBC__)
@@ -224,7 +229,7 @@
# elif (__BYTE_ORDER == __BIG_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
# endif // __GLIBC__
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
@@ -236,12 +241,12 @@
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(_MSC_VER) && defined(_M_ARM)
# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
# define RAPIDJSON_ENDIAN
# else
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
# endif
#endif // RAPIDJSON_ENDIAN

@@ -264,16 +269,11 @@
/*! \ingroup RAPIDJSON_CONFIG
\param x pointer to align
Some machines require strict data alignment. Currently the default uses 4 bytes
alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.
Some machines require strict data alignment. The default is 8 bytes.
User can customize by defining the RAPIDJSON_ALIGN function macro.
*/
#ifndef RAPIDJSON_ALIGN
#if RAPIDJSON_64BIT == 1
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
#else
#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
#endif
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
#endif

///////////////////////////////////////////////////////////////////////////////
@@ -320,17 +320,17 @@
#endif

///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD

/*! \def RAPIDJSON_SIMD
\ingroup RAPIDJSON_CONFIG
\brief Enable SSE2/SSE4.2 optimization.
\brief Enable SSE2/SSE4.2/Neon optimization.
RapidJSON supports optimized implementations for some parsing operations
based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible
processors.
based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel
or ARM compatible processors.
To enable these optimizations, two different symbols can be defined;
To enable these optimizations, three different symbols can be defined;
\code
// Enable SSE2 optimization.
#define RAPIDJSON_SSE2
@@ -339,13 +339,17 @@
#define RAPIDJSON_SSE42
\endcode
\c RAPIDJSON_SSE42 takes precedence, if both are defined.
// Enable ARM Neon optimization.
#define RAPIDJSON_NEON
\endcode
\c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined.
If any of these symbols is defined, RapidJSON defines the macro
\c RAPIDJSON_SIMD to indicate the availability of the optimized code.
*/
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
|| defined(RAPIDJSON_DOXYGEN_RUNNING)
|| defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
#define RAPIDJSON_SIMD
#endif

@@ -405,22 +409,26 @@ RAPIDJSON_NAMESPACE_END
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_STATIC_ASSERT

// Adopt from boost
// Prefer C++11 static_assert, if available
#ifndef RAPIDJSON_STATIC_ASSERT
#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
#define RAPIDJSON_STATIC_ASSERT(x) \
static_assert(x, RAPIDJSON_STRINGIFY(x))
#endif // C++11
#endif // RAPIDJSON_STATIC_ASSERT

// Adopt C++03 implementation from boost
#ifndef RAPIDJSON_STATIC_ASSERT
#ifndef __clang__
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#endif
RAPIDJSON_NAMESPACE_BEGIN
template <bool x> struct STATIC_ASSERTION_FAILURE;
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
template<int x> struct StaticAssertTest {};
template <size_t x> struct StaticAssertTest {};
RAPIDJSON_NAMESPACE_END

#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
#define RAPIDJSON_DO_JOIN2(X, Y) X##Y

#if defined(__GNUC__)
#if defined(__GNUC__) || defined(__clang__)
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
#else
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
@@ -438,7 +446,7 @@ RAPIDJSON_NAMESPACE_END
typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif
#endif // RAPIDJSON_STATIC_ASSERT

///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY
@@ -482,6 +490,12 @@ RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_VERSION_CODE(x,y,z) \
(((x)*100000) + ((y)*100) + (z))

#if defined(__has_builtin)
#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x)
#else
#define RAPIDJSON_HAS_BUILTIN(x) 0
#endif

///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF

@@ -530,13 +544,14 @@ RAPIDJSON_NAMESPACE_END
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if defined(__clang__)
#if __has_feature(cxx_rvalue_references) && \
(defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
#else
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
#endif
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1600)
(defined(_MSC_VER) && _MSC_VER >= 1600) || \
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))

#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
#else
@@ -547,8 +562,9 @@ RAPIDJSON_NAMESPACE_END
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1900) || \
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
#else
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
@@ -562,28 +578,73 @@ RAPIDJSON_NAMESPACE_END

// no automatic detection, yet
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
#if (defined(_MSC_VER) && _MSC_VER >= 1700)
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1
#else
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
#endif
#endif

#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
#if defined(__clang__)
#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700)
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
(defined(_MSC_VER) && _MSC_VER >= 1700) || \
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__))
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
#else
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
#endif
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR

///////////////////////////////////////////////////////////////////////////////
// C++17 features

#if defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough)
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
# else
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
# endif
#else
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
#endif

//!@endcond

//! Assertion (in non-throwing contexts).
/*! \ingroup RAPIDJSON_CONFIG
Some functions provide a \c noexcept guarantee, if the compiler supports it.
In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to
throw an exception. This macro adds a separate customization point for
such cases.
Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is
supported, and to \ref RAPIDJSON_ASSERT otherwise.
*/

///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_NOEXCEPT_ASSERT

#ifndef RAPIDJSON_NOEXCEPT_ASSERT
#ifdef RAPIDJSON_ASSERT_THROWS
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
#else
#include <cassert>
#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
#else
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
#endif // RAPIDJSON_ASSERT_THROWS
#endif // RAPIDJSON_NOEXCEPT_ASSERT

///////////////////////////////////////////////////////////////////////////////
// new/delete

#ifndef RAPIDJSON_NEW
///! customization point for global \c new
#define RAPIDJSON_NEW(x) new x
#define RAPIDJSON_NEW(TypeName) new TypeName
#endif
#ifndef RAPIDJSON_DELETE
///! customization point for global \c delete