Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
spectrum2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Steve Wills
spectrum2
Commits
b48628d3
Commit
b48628d3
authored
Mar 20, 2018
by
Vitaly Takmazov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upgrade to rapidjson 1.1.0
parent
a6cee457
Changes
38
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
16019 additions
and
2335 deletions
+16019
-2335
include/rapidjson/allocators.h
include/rapidjson/allocators.h
+271
-0
include/rapidjson/cursorstreamwrapper.h
include/rapidjson/cursorstreamwrapper.h
+78
-0
include/rapidjson/document.h
include/rapidjson/document.h
+2609
-770
include/rapidjson/encodedstream.h
include/rapidjson/encodedstream.h
+299
-0
include/rapidjson/encodings.h
include/rapidjson/encodings.h
+716
-0
include/rapidjson/error/en.h
include/rapidjson/error/en.h
+74
-0
include/rapidjson/error/error.h
include/rapidjson/error/error.h
+161
-0
include/rapidjson/filereadstream.h
include/rapidjson/filereadstream.h
+99
-0
include/rapidjson/filestream.h
include/rapidjson/filestream.h
+0
-46
include/rapidjson/filewritestream.h
include/rapidjson/filewritestream.h
+104
-0
include/rapidjson/fwd.h
include/rapidjson/fwd.h
+151
-0
include/rapidjson/internal/biginteger.h
include/rapidjson/internal/biginteger.h
+290
-0
include/rapidjson/internal/diyfp.h
include/rapidjson/internal/diyfp.h
+258
-0
include/rapidjson/internal/dtoa.h
include/rapidjson/internal/dtoa.h
+245
-0
include/rapidjson/internal/ieee754.h
include/rapidjson/internal/ieee754.h
+78
-0
include/rapidjson/internal/itoa.h
include/rapidjson/internal/itoa.h
+309
-0
include/rapidjson/internal/meta.h
include/rapidjson/internal/meta.h
+181
-0
include/rapidjson/internal/pow10.h
include/rapidjson/internal/pow10.h
+41
-40
include/rapidjson/internal/regex.h
include/rapidjson/internal/regex.h
+734
-0
include/rapidjson/internal/stack.h
include/rapidjson/internal/stack.h
+210
-61
include/rapidjson/internal/strfunc.h
include/rapidjson/internal/strfunc.h
+55
-10
include/rapidjson/internal/strtod.h
include/rapidjson/internal/strtod.h
+269
-0
include/rapidjson/internal/swap.h
include/rapidjson/internal/swap.h
+46
-0
include/rapidjson/istreamwrapper.h
include/rapidjson/istreamwrapper.h
+115
-0
include/rapidjson/memorybuffer.h
include/rapidjson/memorybuffer.h
+70
-0
include/rapidjson/memorystream.h
include/rapidjson/memorystream.h
+71
-0
include/rapidjson/msinttypes/inttypes.h
include/rapidjson/msinttypes/inttypes.h
+316
-0
include/rapidjson/msinttypes/stdint.h
include/rapidjson/msinttypes/stdint.h
+300
-0
include/rapidjson/ostreamwrapper.h
include/rapidjson/ostreamwrapper.h
+81
-0
include/rapidjson/pointer.h
include/rapidjson/pointer.h
+1363
-0
include/rapidjson/prettywriter.h
include/rapidjson/prettywriter.h
+261
-140
include/rapidjson/rapidjson.h
include/rapidjson/rapidjson.h
+529
-426
include/rapidjson/reader.h
include/rapidjson/reader.h
+2120
-581
include/rapidjson/schema.h
include/rapidjson/schema.h
+2484
-0
include/rapidjson/stream.h
include/rapidjson/stream.h
+223
-0
include/rapidjson/stringbuffer.h
include/rapidjson/stringbuffer.h
+93
-21
include/rapidjson/writer.h
include/rapidjson/writer.h
+684
-209
spectrum_manager/src/APIServer.cpp
spectrum_manager/src/APIServer.cpp
+31
-31
No files found.
include/rapidjson/allocators.h
0 → 100644
View file @
b48628d3
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ALLOCATORS_H_
#define RAPIDJSON_ALLOCATORS_H_
#include "rapidjson.h"
RAPIDJSON_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// Allocator
/*! \class rapidjson::Allocator
\brief Concept for allocating, resizing and freeing memory block.
Note that Malloc() and Realloc() are non-static but Free() is static.
So if an allocator need to support Free(), it needs to put its pointer in
the header of memory block.
\code
concept Allocator {
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
// Allocate a memory block.
// \param size of the memory block in bytes.
// \returns pointer to the memory block.
void* Malloc(size_t size);
// Resize a memory block.
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
// \param newSize the new size in bytes.
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
// Free a memory block.
// \param pointer to the memory block. Null pointer is permitted.
static void Free(void *ptr);
};
\endcode
*/
///////////////////////////////////////////////////////////////////////////////
// CrtAllocator
//! C-runtime library allocator.
/*! This class is just wrapper for standard C library memory routines.
\note implements Allocator concept
*/
class
CrtAllocator
{
public:
static
const
bool
kNeedFree
=
true
;
void
*
Malloc
(
size_t
size
)
{
if
(
size
)
// behavior of malloc(0) is implementation defined.
return
std
::
malloc
(
size
);
else
return
NULL
;
// standardize to returning NULL.
}
void
*
Realloc
(
void
*
originalPtr
,
size_t
originalSize
,
size_t
newSize
)
{
(
void
)
originalSize
;
if
(
newSize
==
0
)
{
std
::
free
(
originalPtr
);
return
NULL
;
}
return
std
::
realloc
(
originalPtr
,
newSize
);
}
static
void
Free
(
void
*
ptr
)
{
std
::
free
(
ptr
);
}
};
///////////////////////////////////////////////////////////////////////////////
// MemoryPoolAllocator
//! Default memory allocator used by the parser and DOM.
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
It does not free memory blocks. And Realloc() only allocate new memory.
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
User may also supply a buffer as the first chunk.
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
The user-buffer is not deallocated by this allocator.
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
\note implements Allocator concept
*/
template
<
typename
BaseAllocator
=
CrtAllocator
>
class
MemoryPoolAllocator
{
public:
static
const
bool
kNeedFree
=
false
;
//!< Tell users that no need to call Free() with this allocator. (concept Allocator)
//! Constructor with chunkSize.
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
\param baseAllocator The allocator for allocating memory chunks.
*/
MemoryPoolAllocator
(
size_t
chunkSize
=
kDefaultChunkCapacity
,
BaseAllocator
*
baseAllocator
=
0
)
:
chunkHead_
(
0
),
chunk_capacity_
(
chunkSize
),
userBuffer_
(
0
),
baseAllocator_
(
baseAllocator
),
ownBaseAllocator_
(
0
)
{
}
//! Constructor with user-supplied buffer.
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
The user buffer will not be deallocated when this allocator is destructed.
\param buffer User supplied buffer.
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
\param baseAllocator The allocator for allocating memory chunks.
*/
MemoryPoolAllocator
(
void
*
buffer
,
size_t
size
,
size_t
chunkSize
=
kDefaultChunkCapacity
,
BaseAllocator
*
baseAllocator
=
0
)
:
chunkHead_
(
0
),
chunk_capacity_
(
chunkSize
),
userBuffer_
(
buffer
),
baseAllocator_
(
baseAllocator
),
ownBaseAllocator_
(
0
)
{
RAPIDJSON_ASSERT
(
buffer
!=
0
);
RAPIDJSON_ASSERT
(
size
>
sizeof
(
ChunkHeader
));
chunkHead_
=
reinterpret_cast
<
ChunkHeader
*>
(
buffer
);
chunkHead_
->
capacity
=
size
-
sizeof
(
ChunkHeader
);
chunkHead_
->
size
=
0
;
chunkHead_
->
next
=
0
;
}
//! Destructor.
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
*/
~
MemoryPoolAllocator
()
{
Clear
();
RAPIDJSON_DELETE
(
ownBaseAllocator_
);
}
//! Deallocates all memory chunks, excluding the user-supplied buffer.
void
Clear
()
{
while
(
chunkHead_
&&
chunkHead_
!=
userBuffer_
)
{
ChunkHeader
*
next
=
chunkHead_
->
next
;
baseAllocator_
->
Free
(
chunkHead_
);
chunkHead_
=
next
;
}
if
(
chunkHead_
&&
chunkHead_
==
userBuffer_
)
chunkHead_
->
size
=
0
;
// Clear user buffer
}
//! Computes the total capacity of allocated memory chunks.
/*! \return total capacity in bytes.
*/
size_t
Capacity
()
const
{
size_t
capacity
=
0
;
for
(
ChunkHeader
*
c
=
chunkHead_
;
c
!=
0
;
c
=
c
->
next
)
capacity
+=
c
->
capacity
;
return
capacity
;
}
//! Computes the memory blocks allocated.
/*! \return total used bytes.
*/
size_t
Size
()
const
{
size_t
size
=
0
;
for
(
ChunkHeader
*
c
=
chunkHead_
;
c
!=
0
;
c
=
c
->
next
)
size
+=
c
->
size
;
return
size
;
}
//! Allocates a memory block. (concept Allocator)
void
*
Malloc
(
size_t
size
)
{
if
(
!
size
)
return
NULL
;
size
=
RAPIDJSON_ALIGN
(
size
);
if
(
chunkHead_
==
0
||
chunkHead_
->
size
+
size
>
chunkHead_
->
capacity
)
if
(
!
AddChunk
(
chunk_capacity_
>
size
?
chunk_capacity_
:
size
))
return
NULL
;
void
*
buffer
=
reinterpret_cast
<
char
*>
(
chunkHead_
)
+
RAPIDJSON_ALIGN
(
sizeof
(
ChunkHeader
))
+
chunkHead_
->
size
;
chunkHead_
->
size
+=
size
;
return
buffer
;
}
//! Resizes a memory block (concept Allocator)
void
*
Realloc
(
void
*
originalPtr
,
size_t
originalSize
,
size_t
newSize
)
{
if
(
originalPtr
==
0
)
return
Malloc
(
newSize
);
if
(
newSize
==
0
)
return
NULL
;
originalSize
=
RAPIDJSON_ALIGN
(
originalSize
);
newSize
=
RAPIDJSON_ALIGN
(
newSize
);
// Do not shrink if new size is smaller than original
if
(
originalSize
>=
newSize
)
return
originalPtr
;
// Simply expand it if it is the last allocation and there is sufficient space
if
(
originalPtr
==
reinterpret_cast
<
char
*>
(
chunkHead_
)
+
RAPIDJSON_ALIGN
(
sizeof
(
ChunkHeader
))
+
chunkHead_
->
size
-
originalSize
)
{
size_t
increment
=
static_cast
<
size_t
>
(
newSize
-
originalSize
);
if
(
chunkHead_
->
size
+
increment
<=
chunkHead_
->
capacity
)
{
chunkHead_
->
size
+=
increment
;
return
originalPtr
;
}
}
// Realloc process: allocate and copy memory, do not free original buffer.
if
(
void
*
newBuffer
=
Malloc
(
newSize
))
{
if
(
originalSize
)
std
::
memcpy
(
newBuffer
,
originalPtr
,
originalSize
);
return
newBuffer
;
}
else
return
NULL
;
}
//! Frees a memory block (concept Allocator)
static
void
Free
(
void
*
ptr
)
{
(
void
)
ptr
;
}
// Do nothing
private:
//! Copy constructor is not permitted.
MemoryPoolAllocator
(
const
MemoryPoolAllocator
&
rhs
)
/* = delete */
;
//! Copy assignment operator is not permitted.
MemoryPoolAllocator
&
operator
=
(
const
MemoryPoolAllocator
&
rhs
)
/* = delete */
;
//! Creates a new chunk.
/*! \param capacity Capacity of the chunk in bytes.
\return true if success.
*/
bool
AddChunk
(
size_t
capacity
)
{
if
(
!
baseAllocator_
)
ownBaseAllocator_
=
baseAllocator_
=
RAPIDJSON_NEW
(
BaseAllocator
)();
if
(
ChunkHeader
*
chunk
=
reinterpret_cast
<
ChunkHeader
*>
(
baseAllocator_
->
Malloc
(
RAPIDJSON_ALIGN
(
sizeof
(
ChunkHeader
))
+
capacity
)))
{
chunk
->
capacity
=
capacity
;
chunk
->
size
=
0
;
chunk
->
next
=
chunkHead_
;
chunkHead_
=
chunk
;
return
true
;
}
else
return
false
;
}
static
const
int
kDefaultChunkCapacity
=
64
*
1024
;
//!< Default chunk capacity.
//! Chunk header for perpending to each chunk.
/*! Chunks are stored as a singly linked list.
*/
struct
ChunkHeader
{
size_t
capacity
;
//!< Capacity of the chunk in bytes (excluding the header itself).
size_t
size
;
//!< Current size of allocated memory in bytes.
ChunkHeader
*
next
;
//!< Next chunk in the linked list.
};
ChunkHeader
*
chunkHead_
;
//!< Head of the chunk linked-list. Only the head chunk serves allocation.
size_t
chunk_capacity_
;
//!< The minimum capacity of chunk when they are allocated.
void
*
userBuffer_
;
//!< User supplied buffer.
BaseAllocator
*
baseAllocator_
;
//!< base allocator for allocating memory chunks.
BaseAllocator
*
ownBaseAllocator_
;
//!< base allocator created by this object.
};
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_ENCODINGS_H_
include/rapidjson/cursorstreamwrapper.h
0 → 100644
View file @
b48628d3
// 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_
include/rapidjson/document.h
View file @
b48628d3
This diff is collapsed.
Click to expand it.
include/rapidjson/encodedstream.h
0 → 100644
View file @
b48628d3
// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
#define RAPIDJSON_ENCODEDSTREAM_H_
#include "stream.h"
#include "memorystream.h"
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
effc
++
)
#endif
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF
(
padded
)
#endif
RAPIDJSON_NAMESPACE_BEGIN
//! Input byte stream wrapper with a statically bound encoding.
/*!
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
\tparam InputByteStream Type of input byte stream. For example, FileReadStream.
*/
template
<
typename
Encoding
,
typename
InputByteStream
>
class
EncodedInputStream
{
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
typename
InputByteStream
::
Ch
)
==
1
);
public
:
typedef
typename
Encoding
::
Ch
Ch
;
EncodedInputStream
(
InputByteStream
&
is
)
:
is_
(
is
)
{
current_
=
Encoding
::
TakeBOM
(
is_
);
}
Ch
Peek
()
const
{
return
current_
;
}
Ch
Take
()
{
Ch
c
=
current_
;
current_
=
Encoding
::
Take
(
is_
);
return
c
;
}
size_t
Tell
()
const
{
return
is_
.
Tell
();
}
// Not implemented
void
Put
(
Ch
)
{
RAPIDJSON_ASSERT
(
false
);
}
void
Flush
()
{
RAPIDJSON_ASSERT
(
false
);
}
Ch
*
PutBegin
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
size_t
PutEnd
(
Ch
*
)
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
private
:
EncodedInputStream
(
const
EncodedInputStream
&
);
EncodedInputStream
&
operator
=
(
const
EncodedInputStream
&
);
InputByteStream
&
is_
;
Ch
current_
;
}
;
//! Specialized for UTF8 MemoryStream.
template
<
>
class
EncodedInputStream
<
UTF8
<>
,
MemoryStream
>
{
public:
typedef
UTF8
<>::
Ch
Ch
;
EncodedInputStream
(
MemoryStream
&
is
)
:
is_
(
is
)
{
if
(
static_cast
<
unsigned
char
>
(
is_
.
Peek
())
==
0xEFu
)
is_
.
Take
();
if
(
static_cast
<
unsigned
char
>
(
is_
.
Peek
())
==
0xBBu
)
is_
.
Take
();
if
(
static_cast
<
unsigned
char
>
(
is_
.
Peek
())
==
0xBFu
)
is_
.
Take
();
}
Ch
Peek
()
const
{
return
is_
.
Peek
();
}
Ch
Take
()
{
return
is_
.
Take
();
}
size_t
Tell
()
const
{
return
is_
.
Tell
();
}
// Not implemented
void
Put
(
Ch
)
{}
void
Flush
()
{}
Ch
*
PutBegin
()
{
return
0
;
}
size_t
PutEnd
(
Ch
*
)
{
return
0
;
}
MemoryStream
&
is_
;
private:
EncodedInputStream
(
const
EncodedInputStream
&
);
EncodedInputStream
&
operator
=
(
const
EncodedInputStream
&
);
};
//! Output byte stream wrapper with statically bound encoding.
/*!
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
*/
template
<
typename
Encoding
,
typename
OutputByteStream
>
class
EncodedOutputStream
{
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
typename
OutputByteStream
::
Ch
)
==
1
);
public:
typedef
typename
Encoding
::
Ch
Ch
;
EncodedOutputStream
(
OutputByteStream
&
os
,
bool
putBOM
=
true
)
:
os_
(
os
)
{
if
(
putBOM
)
Encoding
::
PutBOM
(
os_
);
}
void
Put
(
Ch
c
)
{
Encoding
::
Put
(
os_
,
c
);
}
void
Flush
()
{
os_
.
Flush
();
}
// Not implemented
Ch
Peek
()
const
{
RAPIDJSON_ASSERT
(
false
);
return
0
;}
Ch
Take
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;}
size_t
Tell
()
const
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
Ch
*
PutBegin
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
size_t
PutEnd
(
Ch
*
)
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
private:
EncodedOutputStream
(
const
EncodedOutputStream
&
);
EncodedOutputStream
&
operator
=
(
const
EncodedOutputStream
&
);
OutputByteStream
&
os_
;
};
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
/*!
\tparam CharType Type of character for reading.
\tparam InputByteStream type of input byte stream to be wrapped.
*/
template
<
typename
CharType
,
typename
InputByteStream
>
class
AutoUTFInputStream
{
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
typename
InputByteStream
::
Ch
)
==
1
);
public:
typedef
CharType
Ch
;
//! Constructor.
/*!
\param is input stream to be wrapped.
\param type UTF encoding type if it is not detected from the stream.
*/
AutoUTFInputStream
(
InputByteStream
&
is
,
UTFType
type
=
kUTF8
)
:
is_
(
&
is
),
type_
(
type
),
hasBOM_
(
false
)
{
RAPIDJSON_ASSERT
(
type
>=
kUTF8
&&
type
<=
kUTF32BE
);
DetectType
();
static
const
TakeFunc
f
[]
=
{
RAPIDJSON_ENCODINGS_FUNC
(
Take
)
};
takeFunc_
=
f
[
type_
];
current_
=
takeFunc_
(
*
is_
);
}
UTFType
GetType
()
const
{
return
type_
;
}
bool
HasBOM
()
const
{
return
hasBOM_
;
}
Ch
Peek
()
const
{
return
current_
;
}
Ch
Take
()
{
Ch
c
=
current_
;
current_
=
takeFunc_
(
*
is_
);
return
c
;
}
size_t
Tell
()
const
{
return
is_
->
Tell
();
}
// Not implemented
void
Put
(
Ch
)
{
RAPIDJSON_ASSERT
(
false
);
}
void
Flush
()
{
RAPIDJSON_ASSERT
(
false
);
}
Ch
*
PutBegin
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
size_t
PutEnd
(
Ch
*
)
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
private:
AutoUTFInputStream
(
const
AutoUTFInputStream
&
);
AutoUTFInputStream
&
operator
=
(
const
AutoUTFInputStream
&
);
// Detect encoding type with BOM or RFC 4627
void
DetectType
()
{
// BOM (Byte Order Mark):
// 00 00 FE FF UTF-32BE
// FF FE 00 00 UTF-32LE
// FE FF UTF-16BE
// FF FE UTF-16LE
// EF BB BF UTF-8
const
unsigned
char
*
c
=
reinterpret_cast
<
const
unsigned
char
*>
(
is_
->
Peek4
());
if
(
!
c
)
return
;
unsigned
bom
=
static_cast
<
unsigned
>
(
c
[
0
]
|
(
c
[
1
]
<<
8
)
|
(
c
[
2
]
<<
16
)
|
(
c
[
3
]
<<
24
));
hasBOM_
=
false
;
if
(
bom
==
0xFFFE0000
)
{
type_
=
kUTF32BE
;
hasBOM_
=
true
;
is_
->
Take
();
is_
->
Take
();
is_
->
Take
();
is_
->
Take
();
}
else
if
(
bom
==
0x0000FEFF
)
{
type_
=
kUTF32LE
;
hasBOM_
=
true
;
is_
->
Take
();
is_
->
Take
();
is_
->
Take
();
is_
->
Take
();
}
else
if
((
bom
&
0xFFFF
)
==
0xFFFE
)
{
type_
=
kUTF16BE
;
hasBOM_
=
true
;
is_
->
Take
();
is_
->
Take
();
}
else
if
((
bom
&
0xFFFF
)
==
0xFEFF
)
{
type_
=
kUTF16LE
;
hasBOM_
=
true
;
is_
->
Take
();
is_
->
Take
();
}
else
if
((
bom
&
0xFFFFFF
)
==
0xBFBBEF
)
{
type_
=
kUTF8
;
hasBOM_
=
true
;
is_
->
Take
();
is_
->
Take
();
is_
->
Take
();
}
// RFC 4627: Section 3
// "Since the first two characters of a JSON text will always be ASCII
// characters [RFC0020], it is possible to determine whether an octet
// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
// at the pattern of nulls in the first four octets."
// 00 00 00 xx UTF-32BE
// 00 xx 00 xx UTF-16BE
// xx 00 00 00 UTF-32LE
// xx 00 xx 00 UTF-16LE
// xx xx xx xx UTF-8
if
(
!
hasBOM_
)
{
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
;
case
0x01
:
type_
=
kUTF32LE
;
break
;
case
0x05
:
type_
=
kUTF16LE
;
break
;
case
0x0F
:
type_
=
kUTF8
;
break
;
default:
break
;
// Use type defined by user.
}
}
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
if
(
type_
==
kUTF16LE
||
type_
==
kUTF16BE
)
RAPIDJSON_ASSERT
(
sizeof
(
Ch
)
>=
2
);
if
(
type_
==
kUTF32LE
||
type_
==
kUTF32BE
)
RAPIDJSON_ASSERT
(
sizeof
(
Ch
)
>=
4
);
}
typedef
Ch
(
*
TakeFunc
)(
InputByteStream
&
is
);
InputByteStream
*
is_
;
UTFType
type_
;
Ch
current_
;
TakeFunc
takeFunc_
;
bool
hasBOM_
;
};
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
/*!
\tparam CharType Type of character for writing.
\tparam OutputByteStream type of output byte stream to be wrapped.
*/
template
<
typename
CharType
,
typename
OutputByteStream
>
class
AutoUTFOutputStream
{
RAPIDJSON_STATIC_ASSERT
(
sizeof
(
typename
OutputByteStream
::
Ch
)
==
1
);
public:
typedef
CharType
Ch
;
//! Constructor.
/*!
\param os output stream to be wrapped.
\param type UTF encoding type.
\param putBOM Whether to write BOM at the beginning of the stream.
*/
AutoUTFOutputStream
(
OutputByteStream
&
os
,
UTFType
type
,
bool
putBOM
)
:
os_
(
&
os
),
type_
(
type
)
{
RAPIDJSON_ASSERT
(
type
>=
kUTF8
&&
type
<=
kUTF32BE
);
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
if
(
type_
==
kUTF16LE
||
type_
==
kUTF16BE
)
RAPIDJSON_ASSERT
(
sizeof
(
Ch
)
>=
2
);
if
(
type_
==
kUTF32LE
||
type_
==
kUTF32BE
)
RAPIDJSON_ASSERT
(
sizeof
(
Ch
)
>=
4
);
static
const
PutFunc
f
[]
=
{
RAPIDJSON_ENCODINGS_FUNC
(
Put
)
};
putFunc_
=
f
[
type_
];
if
(
putBOM
)
PutBOM
();
}
UTFType
GetType
()
const
{
return
type_
;
}
void
Put
(
Ch
c
)
{
putFunc_
(
*
os_
,
c
);
}
void
Flush
()
{
os_
->
Flush
();
}
// Not implemented
Ch
Peek
()
const
{
RAPIDJSON_ASSERT
(
false
);
return
0
;}
Ch
Take
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;}
size_t
Tell
()
const
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
Ch
*
PutBegin
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
size_t
PutEnd
(
Ch
*
)
{
RAPIDJSON_ASSERT