Merge branch 'assimp:master' into updatedSTBIMAGE
commit
67a60893f8
|
@ -38,9 +38,9 @@ SET(CMAKE_POLICY_DEFAULT_CMP0012 NEW)
|
|||
SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
|
||||
SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
|
||||
|
||||
# Disabled importers: m3d for 5.1
|
||||
# Disabled importers: m3d for 5.1 or later
|
||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
|
||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||
# Toggles the use of the hunter package manager
|
||||
|
@ -49,13 +49,13 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
|||
IF(ASSIMP_HUNTER_ENABLED)
|
||||
include("cmake-modules/HunterGate.cmake")
|
||||
HunterGate(
|
||||
URL "https://github.com/cpp-pm/hunter/archive/v0.25.3.tar.gz"
|
||||
SHA1 "3319fe6a3b08090df7df98dee75134d68e2ef5a3"
|
||||
URL "https://github.com/cpp-pm/hunter/archive/v0.25.5.tar.gz"
|
||||
SHA1 "a20151e4c0740ee7d0f9994476856d813cdead29"
|
||||
)
|
||||
add_definitions(-DASSIMP_USE_HUNTER)
|
||||
ENDIF()
|
||||
|
||||
PROJECT(Assimp VERSION 5.3.0)
|
||||
PROJECT(Assimp VERSION 5.4.0)
|
||||
|
||||
# All supported options ###############################################
|
||||
|
||||
|
@ -131,18 +131,18 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
|
|||
|
||||
IF (WIN32)
|
||||
OPTION( ASSIMP_BUILD_ZLIB
|
||||
"Build your own zlib"
|
||||
"Build your zlib"
|
||||
ON
|
||||
)
|
||||
ELSE()
|
||||
OPTION( ASSIMP_BUILD_ZLIB
|
||||
"Build your own zlib"
|
||||
"Build your zlib"
|
||||
OFF
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32)
|
||||
# Use subset of Windows.h
|
||||
# Use a subset of Windows.h
|
||||
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
||||
|
||||
IF(MSVC)
|
||||
|
@ -150,16 +150,16 @@ IF (WIN32)
|
|||
"Install MSVC debug files."
|
||||
ON )
|
||||
IF(NOT (MSVC_VERSION LESS 1900))
|
||||
# Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
|
||||
# Multibyte character set has been deprecated since at least MSVC2015 (possibly earlier)
|
||||
ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
|
||||
ENDIF()
|
||||
|
||||
# Link statically against c/c++ lib to avoid missing redistriburable such as
|
||||
# Link statically against c/c++ lib to avoid missing redistributable such as
|
||||
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
|
||||
# a choice to opt for the shared runtime if they want.
|
||||
option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
|
||||
|
||||
# The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
|
||||
# The CMAKE_CXX_FLAGS vars can be overridden by some Visual Studio generators, so we use an alternative
|
||||
# global method here:
|
||||
if (${USE_STATIC_CRT})
|
||||
add_compile_options(
|
||||
|
@ -249,9 +249,9 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
|||
IF( UNIX )
|
||||
# Use GNUInstallDirs for Unix predefined directories
|
||||
INCLUDE(GNUInstallDirs)
|
||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit Linux
|
||||
IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
|
||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit Linux
|
||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
@ -289,7 +289,7 @@ ELSEIF(MSVC)
|
|||
IF(MSVC12)
|
||||
ADD_COMPILE_OPTIONS(/wd4351)
|
||||
ENDIF()
|
||||
# supress warning for double to float conversion if Double precission is activated
|
||||
# supress warning for double to float conversion if Double precision is activated
|
||||
ADD_COMPILE_OPTIONS(/wd4244)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
|
@ -621,6 +621,10 @@ ELSE ()
|
|||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||
ENDIF ()
|
||||
|
||||
if(ASSIMP_BUILD_DRACO_STATIC)
|
||||
set(ASSIMP_BUILD_DRACO ON)
|
||||
endif()
|
||||
|
||||
# Draco requires cmake 3.12
|
||||
IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "3.12")
|
||||
message(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
|
||||
|
@ -656,22 +660,29 @@ ELSE()
|
|||
"-Wno-sign-compare"
|
||||
"-Wno-unused-local-typedefs"
|
||||
)
|
||||
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang
|
||||
list(APPEND DRACO_CXX_FLAGS
|
||||
"-fvisibility=default"
|
||||
)
|
||||
|
||||
if(NOT ASSIMP_BUILD_DRACO_STATIC)
|
||||
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang
|
||||
list(APPEND DRACO_CXX_FLAGS
|
||||
"-fvisibility=default"
|
||||
)
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
# Don't build or install all of Draco by default
|
||||
ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
|
||||
|
||||
if(ASSIMP_BUILD_DRACO_STATIC)
|
||||
set_property(DIRECTORY "contrib/draco" PROPERTY BUILD_SHARED_LIBS OFF)
|
||||
endif()
|
||||
|
||||
if(MSVC OR WIN32)
|
||||
set(draco_LIBRARIES "draco")
|
||||
else()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(draco_LIBRARIES "draco_shared")
|
||||
else()
|
||||
if(ASSIMP_BUILD_DRACO_STATIC)
|
||||
set(draco_LIBRARIES "draco_static")
|
||||
else()
|
||||
set(draco_LIBRARIES "draco_shared")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
# 3) Add libassimp using the file lists (eliminates duplication of file names between
|
||||
# source groups and library command)
|
||||
#
|
||||
cmake_minimum_required( VERSION 3.10 )
|
||||
cmake_minimum_required( VERSION 3.22 )
|
||||
SET( HEADER_PATH ../include/assimp )
|
||||
|
||||
if(NOT ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
|
@ -1286,7 +1286,7 @@ IF(ASSIMP_HUNTER_ENABLED)
|
|||
endif()
|
||||
|
||||
if (ASSIMP_BUILD_DRACO)
|
||||
target_link_libraries(assimp PUBLIC ${draco_LIBRARIES})
|
||||
target_link_libraries(assimp PRIVATE ${draco_LIBRARIES})
|
||||
endif()
|
||||
ELSE()
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES})
|
||||
|
|
|
@ -93,10 +93,6 @@ BaseImporter::BaseImporter() AI_NO_EXCEPT
|
|||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
BaseImporter::~BaseImporter() = default;
|
||||
|
||||
void BaseImporter::UpdateImporterScale(Importer *pImp) {
|
||||
ai_assert(pImp != nullptr);
|
||||
ai_assert(importerScale != 0.0);
|
||||
|
|
|
@ -57,10 +57,6 @@ BaseProcess::BaseProcess() AI_NO_EXCEPT
|
|||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
BaseProcess::~BaseProcess() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BaseProcess::ExecuteOnScene(Importer *pImp) {
|
||||
ai_assert( nullptr != pImp );
|
||||
|
|
|
@ -179,11 +179,11 @@ class ASSIMP_API BaseProcess {
|
|||
friend class Importer;
|
||||
|
||||
public:
|
||||
/** @brief onstructor to be privately used by Importer */
|
||||
/** @brief Constructor to be privately used by Importer */
|
||||
BaseProcess() AI_NO_EXCEPT;
|
||||
|
||||
/** @brief Destructor, private as well */
|
||||
virtual ~BaseProcess();
|
||||
/** @brief Destructor */
|
||||
virtual ~BaseProcess() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/**
|
||||
|
|
|
@ -74,11 +74,11 @@ public:
|
|||
typedef unsigned int KeyType;
|
||||
|
||||
// typedefs for our configuration maps.
|
||||
typedef std::map<KeyType, int> IntPropertyMap;
|
||||
typedef std::map<KeyType, ai_real> FloatPropertyMap;
|
||||
typedef std::map<KeyType, std::string> StringPropertyMap;
|
||||
typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
|
||||
typedef std::map<KeyType, void*> PointerPropertyMap;
|
||||
using IntPropertyMap = std::map<KeyType, int>;
|
||||
using FloatPropertyMap = std::map<KeyType, ai_real>;
|
||||
using StringPropertyMap = std::map<KeyType, std::string>;
|
||||
using MatrixPropertyMap = std::map<KeyType, aiMatrix4x4>;
|
||||
using PointerPropertyMap = std::map<KeyType, void*>;
|
||||
|
||||
/** IO handler to use for all file accesses. */
|
||||
IOSystem* mIOHandler;
|
||||
|
@ -128,10 +128,12 @@ public:
|
|||
|
||||
/// The default class constructor.
|
||||
ImporterPimpl() AI_NO_EXCEPT;
|
||||
|
||||
/// The class destructor.
|
||||
~ImporterPimpl() = default;
|
||||
};
|
||||
|
||||
inline
|
||||
ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT :
|
||||
inline ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT :
|
||||
mIOHandler( nullptr ),
|
||||
mIsDefaultHandler( false ),
|
||||
mProgressHandler( nullptr ),
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -50,16 +48,13 @@ the 3ds loader handling smooth groups correctly */
|
|||
using namespace Assimp;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SGSpatialSort::SGSpatialSort()
|
||||
{
|
||||
SGSpatialSort::SGSpatialSort() {
|
||||
// define the reference plane. We choose some arbitrary vector away from all basic axes
|
||||
// in the hope that no model spreads all its vertices along this plane.
|
||||
mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f);
|
||||
mPlaneNormal.Normalize();
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor
|
||||
SGSpatialSort::~SGSpatialSort() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SGSpatialSort::Add(const aiVector3D& vPosition, unsigned int index,
|
||||
unsigned int smoothingGroup)
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -56,7 +55,7 @@ class ScenePreprocessorTest;
|
|||
namespace Assimp {
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
/** ScenePreprocessor: Preprocess a scene before any post-processing
|
||||
/** ScenePreprocessor: Pre-process a scene before any post-processing
|
||||
* steps are executed.
|
||||
*
|
||||
* The step computes data that needn't necessarily be provided by the
|
||||
|
@ -79,6 +78,9 @@ public:
|
|||
ScenePreprocessor(aiScene *_scene) :
|
||||
scene(_scene) {}
|
||||
|
||||
/// @brief The class destructor.
|
||||
~ScenePreprocessor() = default;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Assign a (new) scene to the object.
|
||||
*
|
||||
|
|
|
@ -61,9 +61,10 @@ namespace Assimp {
|
|||
class StackAllocator {
|
||||
public:
|
||||
/// @brief Constructs the allocator
|
||||
inline StackAllocator();
|
||||
StackAllocator();
|
||||
|
||||
/// @brief Destructs the allocator and frees all memory
|
||||
inline ~StackAllocator();
|
||||
~StackAllocator();
|
||||
|
||||
// non copyable
|
||||
StackAllocator(const StackAllocator &) = delete;
|
||||
|
|
|
@ -45,8 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
inline StackAllocator::StackAllocator() {
|
||||
}
|
||||
inline StackAllocator::StackAllocator() : m_storageBlocks() {}
|
||||
|
||||
inline StackAllocator::~StackAllocator() {
|
||||
FreeAll();
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -119,12 +118,16 @@ private:
|
|||
* look-at target */
|
||||
class TargetAnimationHelper {
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
TargetAnimationHelper() :
|
||||
targetPositions(nullptr),
|
||||
objectPositions(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/// @brief The class destructor.
|
||||
~TargetAnimationHelper() = default;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
/** Sets the target animation channel
|
||||
*
|
||||
|
|
|
@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
static constexpr char LEGAL_INFORMATION[] =
|
||||
"Open Asset Import Library (Assimp).\n"
|
||||
"A free C/C++ library to import various 3D file formats into applications\n\n"
|
||||
"(c) 2006-2023, Assimp team\n"
|
||||
"(c) 2006-2024, Assimp team\n"
|
||||
"License under the terms and conditions of the 3-clause BSD license\n"
|
||||
"https://www.assimp.org\n";
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -62,13 +62,13 @@ namespace Assimp {
|
|||
// ----------------------------------------------------------------
|
||||
// A read-only file inside a ZIP
|
||||
|
||||
class ZipFile : public IOStream {
|
||||
class ZipFile final : public IOStream {
|
||||
friend class ZipFileInfo;
|
||||
explicit ZipFile(std::string &filename, size_t size);
|
||||
|
||||
public:
|
||||
std::string m_Filename;
|
||||
virtual ~ZipFile() override;
|
||||
~ZipFile() override = default;
|
||||
|
||||
// IOStream interface
|
||||
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
||||
|
@ -89,6 +89,8 @@ private:
|
|||
// Wraps an existing Assimp::IOSystem for unzip
|
||||
class IOSystem2Unzip {
|
||||
public:
|
||||
IOSystem2Unzip() = default;
|
||||
~IOSystem2Unzip() = default;
|
||||
static voidpf open(voidpf opaque, const char *filename, int mode);
|
||||
static voidpf opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode);
|
||||
static uLong read(voidpf opaque, voidpf stream, void *buf, uLong size);
|
||||
|
@ -100,6 +102,7 @@ public:
|
|||
static zlib_filefunc_def get(IOSystem *pIOHandler);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
voidpf IOSystem2Unzip::open(voidpf opaque, const char *filename, int mode) {
|
||||
IOSystem *io_system = reinterpret_cast<IOSystem *>(opaque);
|
||||
|
||||
|
@ -119,6 +122,7 @@ voidpf IOSystem2Unzip::open(voidpf opaque, const char *filename, int mode) {
|
|||
return (voidpf)io_system->Open(filename, mode_fopen);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
voidpf IOSystem2Unzip::opendisk(voidpf opaque, voidpf stream, uint32_t number_disk, int mode) {
|
||||
ZipFile *io_stream = (ZipFile *)stream;
|
||||
voidpf ret = nullptr;
|
||||
|
@ -141,24 +145,28 @@ voidpf IOSystem2Unzip::opendisk(voidpf opaque, voidpf stream, uint32_t number_di
|
|||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void *buf, uLong size) {
|
||||
IOStream *io_stream = (IOStream *)stream;
|
||||
|
||||
return static_cast<uLong>(io_stream->Read(buf, 1, size));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void *buf, uLong size) {
|
||||
IOStream *io_stream = (IOStream *)stream;
|
||||
|
||||
return static_cast<uLong>(io_stream->Write(buf, 1, size));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
|
||||
IOStream *io_stream = (IOStream *)stream;
|
||||
|
||||
return static_cast<long>(io_stream->Tell());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) {
|
||||
IOStream *io_stream = (IOStream *)stream;
|
||||
|
||||
|
@ -179,6 +187,7 @@ long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int or
|
|||
return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
|
||||
IOSystem *io_system = (IOSystem *)opaque;
|
||||
IOStream *io_stream = (IOStream *)stream;
|
||||
|
@ -188,10 +197,12 @@ int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
|
||||
zlib_filefunc_def mapping;
|
||||
|
||||
|
@ -213,9 +224,10 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem *pIOHandler) {
|
|||
|
||||
// ----------------------------------------------------------------
|
||||
// Info about a read-only file inside a ZIP
|
||||
class ZipFileInfo {
|
||||
class ZipFileInfo final {
|
||||
public:
|
||||
explicit ZipFileInfo(unzFile zip_handle, size_t size);
|
||||
~ZipFileInfo() = default;
|
||||
|
||||
// Allocate and Extract data from the ZIP
|
||||
ZipFile *Extract(std::string &filename, unzFile zip_handle) const;
|
||||
|
@ -225,6 +237,7 @@ private:
|
|||
unz_file_pos_s m_ZipFilePos;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
|
||||
m_Size(size) {
|
||||
ai_assert(m_Size != 0);
|
||||
|
@ -234,6 +247,7 @@ ZipFileInfo::ZipFileInfo(unzFile zip_handle, size_t size) :
|
|||
unzGetFilePos(zip_handle, &(m_ZipFilePos));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipFile *ZipFileInfo::Extract(std::string &filename, unzFile zip_handle) const {
|
||||
// Find in the ZIP. This cannot fail
|
||||
unz_file_pos_s *filepos = const_cast<unz_file_pos_s *>(&(m_ZipFilePos));
|
||||
|
@ -273,14 +287,14 @@ ZipFile *ZipFileInfo::Extract(std::string &filename, unzFile zip_handle) const {
|
|||
return zip_file;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipFile::ZipFile(std::string &filename, size_t size) :
|
||||
m_Filename(filename), m_Size(size) {
|
||||
ai_assert(m_Size != 0);
|
||||
m_Buffer = std::unique_ptr<uint8_t[]>(new uint8_t[m_Size]);
|
||||
}
|
||||
|
||||
ZipFile::~ZipFile() = default;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
size_t ZipFile::Read(void *pvBuffer, size_t pSize, size_t pCount) {
|
||||
// Should be impossible
|
||||
ai_assert(m_Buffer != nullptr);
|
||||
|
@ -305,10 +319,12 @@ size_t ZipFile::Read(void *pvBuffer, size_t pSize, size_t pCount) {
|
|||
return pCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
size_t ZipFile::FileSize() const {
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) {
|
||||
switch (pOrigin) {
|
||||
case aiOrigin_SET: {
|
||||
|
@ -334,6 +350,7 @@ aiReturn ZipFile::Seek(size_t pOffset, aiOrigin pOrigin) {
|
|||
return aiReturn_FAILURE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
size_t ZipFile::Tell() const {
|
||||
return m_SeekPtr;
|
||||
}
|
||||
|
@ -365,6 +382,7 @@ private:
|
|||
ZipFileInfoMap m_ArchiveMap;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFilename, const char *pMode) {
|
||||
ai_assert(strcmp(pMode, "r") == 0);
|
||||
ai_assert(pFilename != nullptr);
|
||||
|
@ -376,12 +394,14 @@ ZipArchiveIOSystem::Implement::Implement(IOSystem *pIOHandler, const char *pFile
|
|||
m_ZipFileHandle = unzOpen2(pFilename, &mapping);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipArchiveIOSystem::Implement::~Implement() {
|
||||
if (m_ZipFileHandle != nullptr) {
|
||||
unzClose(m_ZipFileHandle);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::Implement::MapArchive() {
|
||||
if (m_ZipFileHandle == nullptr)
|
||||
return;
|
||||
|
@ -408,10 +428,12 @@ void ZipArchiveIOSystem::Implement::MapArchive() {
|
|||
} while (unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
bool ZipArchiveIOSystem::Implement::isOpen() const {
|
||||
return (m_ZipFileHandle != nullptr);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::Implement::getFileList(std::vector<std::string> &rFileList) {
|
||||
MapArchive();
|
||||
rFileList.clear();
|
||||
|
@ -421,6 +443,7 @@ void ZipArchiveIOSystem::Implement::getFileList(std::vector<std::string> &rFileL
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::Implement::getFileListExtension(std::vector<std::string> &rFileList, const std::string &extension) {
|
||||
MapArchive();
|
||||
rFileList.clear();
|
||||
|
@ -431,6 +454,7 @@ void ZipArchiveIOSystem::Implement::getFileListExtension(std::vector<std::string
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
bool ZipArchiveIOSystem::Implement::Exists(std::string &filename) {
|
||||
MapArchive();
|
||||
|
||||
|
@ -438,6 +462,7 @@ bool ZipArchiveIOSystem::Implement::Exists(std::string &filename) {
|
|||
return (it != m_ArchiveMap.end());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
IOStream *ZipArchiveIOSystem::Implement::OpenFile(std::string &filename) {
|
||||
MapArchive();
|
||||
|
||||
|
@ -452,6 +477,7 @@ IOStream *ZipArchiveIOSystem::Implement::OpenFile(std::string &filename) {
|
|||
return zip_file.Extract(filename, m_ZipFileHandle);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
inline void ReplaceAll(std::string &data, const std::string &before, const std::string &after) {
|
||||
size_t pos = data.find(before);
|
||||
while (pos != std::string::npos) {
|
||||
|
@ -460,6 +486,7 @@ inline void ReplaceAll(std::string &data, const std::string &before, const std::
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
inline void ReplaceAllChar(std::string &data, const char before, const char after) {
|
||||
size_t pos = data.find(before);
|
||||
while (pos != std::string::npos) {
|
||||
|
@ -468,6 +495,7 @@ inline void ReplaceAllChar(std::string &data, const char before, const char afte
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string &filename) {
|
||||
ReplaceAllChar(filename, '\\', '/');
|
||||
|
||||
|
@ -492,6 +520,7 @@ void ZipArchiveIOSystem::Implement::SimplifyFilename(std::string &filename) {
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const char *pFilename, const char *pMode) :
|
||||
pImpl(new Implement(pIOHandler, pFilename, pMode)) {
|
||||
}
|
||||
|
@ -502,10 +531,12 @@ ZipArchiveIOSystem::ZipArchiveIOSystem(IOSystem *pIOHandler, const std::string &
|
|||
pImpl(new Implement(pIOHandler, rFilename.c_str(), pMode)) {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ZipArchiveIOSystem::~ZipArchiveIOSystem() {
|
||||
delete pImpl;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
bool ZipArchiveIOSystem::Exists(const char *pFilename) const {
|
||||
ai_assert(pFilename != nullptr);
|
||||
|
||||
|
@ -517,11 +548,13 @@ bool ZipArchiveIOSystem::Exists(const char *pFilename) const {
|
|||
return pImpl->Exists(filename);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// This is always '/' in a ZIP
|
||||
char ZipArchiveIOSystem::getOsSeparator() const {
|
||||
return '/';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Only supports Reading
|
||||
IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) {
|
||||
ai_assert(pFilename != nullptr);
|
||||
|
@ -536,22 +569,27 @@ IOStream *ZipArchiveIOSystem::Open(const char *pFilename, const char *pMode) {
|
|||
return pImpl->OpenFile(filename);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::Close(IOStream *pFile) {
|
||||
delete pFile;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
bool ZipArchiveIOSystem::isOpen() const {
|
||||
return (pImpl->isOpen());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::getFileList(std::vector<std::string> &rFileList) const {
|
||||
return pImpl->getFileList(rFileList);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void ZipArchiveIOSystem::getFileListExtension(std::vector<std::string> &rFileList, const std::string &extension) const {
|
||||
return pImpl->getFileListExtension(rFileList, extension);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
bool ZipArchiveIOSystem::isZipArchive(IOSystem *pIOHandler, const char *pFilename) {
|
||||
Implement tmp(pIOHandler, pFilename, "r");
|
||||
return tmp.isOpen();
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
#define RAPIDJSON_ALLOCATORS_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/meta.h"
|
||||
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -89,7 +97,14 @@ public:
|
|||
}
|
||||
return RAPIDJSON_REALLOC(originalPtr, newSize);
|
||||
}
|
||||
static void Free(void *ptr) { RAPIDJSON_FREE(ptr); }
|
||||
static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
|
||||
|
||||
bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -113,16 +128,64 @@ public:
|
|||
*/
|
||||
template <typename BaseAllocator = CrtAllocator>
|
||||
class MemoryPoolAllocator {
|
||||
//! 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.
|
||||
};
|
||||
|
||||
struct SharedData {
|
||||
ChunkHeader *chunkHead; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
||||
BaseAllocator* ownBaseAllocator; //!< base allocator created by this object.
|
||||
size_t refcount;
|
||||
bool ownBuffer;
|
||||
};
|
||||
|
||||
static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
|
||||
static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
|
||||
|
||||
static inline ChunkHeader *GetChunkHead(SharedData *shared)
|
||||
{
|
||||
return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
|
||||
}
|
||||
static inline uint8_t *GetChunkBuffer(SharedData *shared)
|
||||
{
|
||||
return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
|
||||
}
|
||||
|
||||
static const size_t kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
|
||||
|
||||
public:
|
||||
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
||||
static const bool kRefCounted = true; //!< Tell users that this allocator is reference counted on copy
|
||||
|
||||
//! Constructor with chunkSize.
|
||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||
\param baseAllocator The allocator for allocating memory chunks.
|
||||
*/
|
||||
explicit
|
||||
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||
chunk_capacity_(chunkSize),
|
||||
baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
|
||||
shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
|
||||
{
|
||||
RAPIDJSON_ASSERT(baseAllocator_ != 0);
|
||||
RAPIDJSON_ASSERT(shared_ != 0);
|
||||
if (baseAllocator) {
|
||||
shared_->ownBaseAllocator = 0;
|
||||
}
|
||||
else {
|
||||
shared_->ownBaseAllocator = baseAllocator_;
|
||||
}
|
||||
shared_->chunkHead = GetChunkHead(shared_);
|
||||
shared_->chunkHead->capacity = 0;
|
||||
shared_->chunkHead->size = 0;
|
||||
shared_->chunkHead->next = 0;
|
||||
shared_->ownBuffer = true;
|
||||
shared_->refcount = 1;
|
||||
}
|
||||
|
||||
//! Constructor with user-supplied buffer.
|
||||
|
@ -136,41 +199,101 @@ public:
|
|||
\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)
|
||||
chunk_capacity_(chunkSize),
|
||||
baseAllocator_(baseAllocator),
|
||||
shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
|
||||
{
|
||||
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;
|
||||
RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
|
||||
shared_->chunkHead = GetChunkHead(shared_);
|
||||
shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
|
||||
shared_->chunkHead->size = 0;
|
||||
shared_->chunkHead->next = 0;
|
||||
shared_->ownBaseAllocator = 0;
|
||||
shared_->ownBuffer = false;
|
||||
shared_->refcount = 1;
|
||||
}
|
||||
|
||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
chunk_capacity_(rhs.chunk_capacity_),
|
||||
baseAllocator_(rhs.baseAllocator_),
|
||||
shared_(rhs.shared_)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
++shared_->refcount;
|
||||
}
|
||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
++rhs.shared_->refcount;
|
||||
this->~MemoryPoolAllocator();
|
||||
baseAllocator_ = rhs.baseAllocator_;
|
||||
chunk_capacity_ = rhs.chunk_capacity_;
|
||||
shared_ = rhs.shared_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||
chunk_capacity_(rhs.chunk_capacity_),
|
||||
baseAllocator_(rhs.baseAllocator_),
|
||||
shared_(rhs.shared_)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
rhs.shared_ = 0;
|
||||
}
|
||||
MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
this->~MemoryPoolAllocator();
|
||||
baseAllocator_ = rhs.baseAllocator_;
|
||||
chunk_capacity_ = rhs.chunk_capacity_;
|
||||
shared_ = rhs.shared_;
|
||||
rhs.shared_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Destructor.
|
||||
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
*/
|
||||
~MemoryPoolAllocator() {
|
||||
~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
|
||||
if (!shared_) {
|
||||
// do nothing if moved
|
||||
return;
|
||||
}
|
||||
if (shared_->refcount > 1) {
|
||||
--shared_->refcount;
|
||||
return;
|
||||
}
|
||||
Clear();
|
||||
RAPIDJSON_DELETE(ownBaseAllocator_);
|
||||
BaseAllocator *a = shared_->ownBaseAllocator;
|
||||
if (shared_->ownBuffer) {
|
||||
baseAllocator_->Free(shared_);
|
||||
}
|
||||
RAPIDJSON_DELETE(a);
|
||||
}
|
||||
|
||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
void Clear() {
|
||||
while (chunkHead_ && chunkHead_ != userBuffer_) {
|
||||
ChunkHeader* next = chunkHead_->next;
|
||||
baseAllocator_->Free(chunkHead_);
|
||||
chunkHead_ = next;
|
||||
//! Deallocates all memory chunks, excluding the first/user one.
|
||||
void Clear() RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
for (;;) {
|
||||
ChunkHeader* c = shared_->chunkHead;
|
||||
if (!c->next) {
|
||||
break;
|
||||
}
|
||||
shared_->chunkHead = c->next;
|
||||
baseAllocator_->Free(c);
|
||||
}
|
||||
if (chunkHead_ && chunkHead_ == userBuffer_)
|
||||
chunkHead_->size = 0; // Clear user buffer
|
||||
shared_->chunkHead->size = 0;
|
||||
}
|
||||
|
||||
//! Computes the total capacity of allocated memory chunks.
|
||||
/*! \return total capacity in bytes.
|
||||
*/
|
||||
size_t Capacity() const {
|
||||
size_t Capacity() const RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
size_t capacity = 0;
|
||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||
for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
|
||||
capacity += c->capacity;
|
||||
return capacity;
|
||||
}
|
||||
|
@ -178,25 +301,35 @@ public:
|
|||
//! Computes the memory blocks allocated.
|
||||
/*! \return total used bytes.
|
||||
*/
|
||||
size_t Size() const {
|
||||
size_t Size() const RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
size_t size = 0;
|
||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||
for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
|
||||
size += c->size;
|
||||
return size;
|
||||
}
|
||||
|
||||
//! Whether the allocator is shared.
|
||||
/*! \return true or false.
|
||||
*/
|
||||
bool Shared() const RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
return shared_->refcount > 1;
|
||||
}
|
||||
|
||||
//! Allocates a memory block. (concept Allocator)
|
||||
void* Malloc(size_t size) {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
size = RAPIDJSON_ALIGN(size);
|
||||
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
||||
if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->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;
|
||||
void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
|
||||
shared_->chunkHead->size += size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -205,6 +338,7 @@ public:
|
|||
if (originalPtr == 0)
|
||||
return Malloc(newSize);
|
||||
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
if (newSize == 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -216,10 +350,10 @@ public:
|
|||
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) {
|
||||
if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) {
|
||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
chunkHead_->size += increment;
|
||||
if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
|
||||
shared_->chunkHead->size += increment;
|
||||
return originalPtr;
|
||||
}
|
||||
}
|
||||
|
@ -235,50 +369,325 @@ public:
|
|||
}
|
||||
|
||||
//! Frees a memory block (concept Allocator)
|
||||
static void Free(void *ptr) { (void)ptr; } // Do nothing
|
||||
static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing
|
||||
|
||||
//! Compare (equality) with another MemoryPoolAllocator
|
||||
bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
|
||||
return shared_ == rhs.shared_;
|
||||
}
|
||||
//! Compare (inequality) with another MemoryPoolAllocator
|
||||
bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
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))) {
|
||||
shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
|
||||
if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
|
||||
chunk->capacity = capacity;
|
||||
chunk->size = 0;
|
||||
chunk->next = chunkHead_;
|
||||
chunkHead_ = chunk;
|
||||
chunk->next = shared_->chunkHead;
|
||||
shared_->chunkHead = chunk;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity.
|
||||
static inline void* AlignBuffer(void* buf, size_t &size)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(buf != 0);
|
||||
const uintptr_t mask = sizeof(void*) - 1;
|
||||
const uintptr_t ubuf = reinterpret_cast<uintptr_t>(buf);
|
||||
if (RAPIDJSON_UNLIKELY(ubuf & mask)) {
|
||||
const uintptr_t abuf = (ubuf + mask) & ~mask;
|
||||
RAPIDJSON_ASSERT(size >= abuf - ubuf);
|
||||
buf = reinterpret_cast<void*>(abuf);
|
||||
size -= abuf - ubuf;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
//! 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.
|
||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||
SharedData *shared_; //!< The shared data of the allocator
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
template<typename, typename = void>
|
||||
struct IsRefCounted :
|
||||
public FalseType
|
||||
{ };
|
||||
template<typename T>
|
||||
struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> :
|
||||
public TrueType
|
||||
{ };
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
|
||||
{
|
||||
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
|
||||
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline T *Malloc(A& a, size_t n = 1)
|
||||
{
|
||||
return Realloc<T, A>(a, NULL, 0, n);
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
inline void Free(A& a, T *p, size_t n = 1)
|
||||
{
|
||||
static_cast<void>(Realloc<T, A>(a, p, n, 0));
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
|
||||
#endif
|
||||
|
||||
template <typename T, typename BaseAllocator = CrtAllocator>
|
||||
class StdAllocator :
|
||||
public std::allocator<T>
|
||||
{
|
||||
typedef std::allocator<T> allocator_type;
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
typedef std::allocator_traits<allocator_type> traits_type;
|
||||
#else
|
||||
typedef allocator_type traits_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef BaseAllocator BaseAllocatorType;
|
||||
|
||||
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_()
|
||||
{ }
|
||||
|
||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(std::move(rhs)),
|
||||
baseAllocator_(std::move(rhs.baseAllocator_))
|
||||
{ }
|
||||
#endif
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
using propagate_on_container_swap = std::true_type;
|
||||
#endif
|
||||
|
||||
/* implicit */
|
||||
StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_(baseAllocator)
|
||||
{ }
|
||||
|
||||
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef StdAllocator<U, BaseAllocator> other;
|
||||
};
|
||||
|
||||
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.
|
||||
typedef typename traits_type::size_type size_type;
|
||||
typedef typename traits_type::difference_type difference_type;
|
||||
|
||||
typedef typename traits_type::value_type value_type;
|
||||
typedef typename traits_type::pointer pointer;
|
||||
typedef typename traits_type::const_pointer const_pointer;
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
|
||||
typedef typename std::add_lvalue_reference<value_type>::type &reference;
|
||||
typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
|
||||
|
||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return std::addressof(r);
|
||||
}
|
||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return std::addressof(r);
|
||||
}
|
||||
|
||||
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return traits_type::max_size(*this);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
void construct(pointer p, Args&&... args)
|
||||
{
|
||||
traits_type::construct(*this, p, std::forward<Args>(args)...);
|
||||
}
|
||||
void destroy(pointer p)
|
||||
{
|
||||
traits_type::destroy(*this, p);
|
||||
}
|
||||
|
||||
#else // !RAPIDJSON_HAS_CXX11
|
||||
|
||||
typedef typename allocator_type::reference reference;
|
||||
typedef typename allocator_type::const_reference const_reference;
|
||||
|
||||
pointer address(reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::address(r);
|
||||
}
|
||||
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::address(r);
|
||||
}
|
||||
|
||||
size_type max_size() const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return allocator_type::max_size();
|
||||
}
|
||||
|
||||
void construct(pointer p, const_reference r)
|
||||
{
|
||||
allocator_type::construct(p, r);
|
||||
}
|
||||
void destroy(pointer p)
|
||||
{
|
||||
allocator_type::destroy(p);
|
||||
}
|
||||
|
||||
#endif // !RAPIDJSON_HAS_CXX11
|
||||
|
||||
template <typename U>
|
||||
U* allocate(size_type n = 1, const void* = 0)
|
||||
{
|
||||
return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
|
||||
}
|
||||
template <typename U>
|
||||
void deallocate(U* p, size_type n = 1)
|
||||
{
|
||||
RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n = 1, const void* = 0)
|
||||
{
|
||||
return allocate<value_type>(n);
|
||||
}
|
||||
void deallocate(pointer p, size_type n = 1)
|
||||
{
|
||||
deallocate<value_type>(p, n);
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
using is_always_equal = std::is_empty<BaseAllocator>;
|
||||
#endif
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return baseAllocator_ == rhs.baseAllocator_;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
//! rapidjson Allocator concept
|
||||
static const bool kNeedFree = BaseAllocator::kNeedFree;
|
||||
static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
|
||||
void* Malloc(size_t size)
|
||||
{
|
||||
return baseAllocator_.Malloc(size);
|
||||
}
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
|
||||
{
|
||||
return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
|
||||
}
|
||||
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
|
||||
{
|
||||
BaseAllocator::Free(ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename, typename>
|
||||
friend class StdAllocator; // access to StdAllocator<!T>.*
|
||||
|
||||
BaseAllocator baseAllocator_;
|
||||
};
|
||||
|
||||
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
|
||||
template <typename BaseAllocator>
|
||||
class StdAllocator<void, BaseAllocator> :
|
||||
public std::allocator<void>
|
||||
{
|
||||
typedef std::allocator<void> allocator_type;
|
||||
|
||||
public:
|
||||
typedef BaseAllocator BaseAllocatorType;
|
||||
|
||||
StdAllocator() RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_()
|
||||
{ }
|
||||
|
||||
StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(rhs),
|
||||
baseAllocator_(rhs.baseAllocator_)
|
||||
{ }
|
||||
|
||||
/* implicit */
|
||||
StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
|
||||
allocator_type(),
|
||||
baseAllocator_(baseAllocator)
|
||||
{ }
|
||||
|
||||
~StdAllocator() RAPIDJSON_NOEXCEPT
|
||||
{ }
|
||||
|
||||
template<typename U>
|
||||
struct rebind {
|
||||
typedef StdAllocator<U, BaseAllocator> other;
|
||||
};
|
||||
|
||||
typedef typename allocator_type::value_type value_type;
|
||||
|
||||
private:
|
||||
template <typename, typename>
|
||||
friend class StdAllocator; // access to StdAllocator<!T>.*
|
||||
|
||||
BaseAllocator baseAllocator_;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#endif // RAPIDJSON_ENCODINGS_H_
|
||||
|
|
|
@ -42,12 +42,21 @@ RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible lo
|
|||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif // __GNUC__
|
||||
|
||||
#ifdef GetObject
|
||||
// see https://github.com/Tencent/rapidjson/issues/1448
|
||||
// a former included windows.h might have defined a macro called GetObject, which affects
|
||||
// GetObject defined here. This ensures the macro does not get applied
|
||||
#pragma push_macro("GetObject")
|
||||
#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||
#undef GetObject
|
||||
#endif
|
||||
|
||||
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||
#include <iterator> // std::random_access_iterator_tag
|
||||
#endif
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
#include <utility> // std::move
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
#include <map> // std::multimap
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -66,7 +75,7 @@ class GenericDocument;
|
|||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||
*/
|
||||
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
||||
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
|
||||
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
|
||||
#endif
|
||||
|
||||
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||
|
@ -76,7 +85,7 @@ class GenericDocument;
|
|||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||
*/
|
||||
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
|
||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
|
||||
#endif
|
||||
|
||||
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||
|
@ -732,18 +741,8 @@ public:
|
|||
template <typename SourceAllocator>
|
||||
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
|
||||
switch (rhs.GetType()) {
|
||||
case kObjectType: {
|
||||
SizeType count = rhs.data_.o.size;
|
||||
Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
||||
const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
|
||||
for (SizeType i = 0; i < count; i++) {
|
||||
new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
|
||||
new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
|
||||
}
|
||||
data_.f.flags = kObjectFlag;
|
||||
data_.o.size = data_.o.capacity = count;
|
||||
SetMembersPointer(lm);
|
||||
}
|
||||
case kObjectType:
|
||||
DoCopyMembers(rhs, allocator, copyConstStrings);
|
||||
break;
|
||||
case kArrayType: {
|
||||
SizeType count = rhs.data_.a.size;
|
||||
|
@ -879,25 +878,30 @@ public:
|
|||
/*! Need to destruct elements of array, members of object, or copy-string.
|
||||
*/
|
||||
~GenericValue() {
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
// With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
|
||||
// their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
|
||||
if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
|
||||
internal::IsRefCounted<Allocator>::Value)) {
|
||||
switch(data_.f.flags) {
|
||||
case kArrayFlag:
|
||||
{
|
||||
GenericValue* e = GetElementsPointer();
|
||||
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
||||
v->~GenericValue();
|
||||
Allocator::Free(e);
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
Allocator::Free(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kObjectFlag:
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
Allocator::Free(GetMembersPointer());
|
||||
DoFreeMembers();
|
||||
break;
|
||||
|
||||
case kCopyStringFlag:
|
||||
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -916,8 +920,13 @@ public:
|
|||
*/
|
||||
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
||||
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||
// Can't destroy "this" before assigning "rhs", otherwise "rhs"
|
||||
// could be used after free if it's an sub-Value of "this",
|
||||
// hence the temporary danse.
|
||||
GenericValue temp;
|
||||
temp.RawAssign(rhs);
|
||||
this->~GenericValue();
|
||||
RawAssign(rhs);
|
||||
RawAssign(temp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -1024,7 +1033,7 @@ public:
|
|||
return false;
|
||||
for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
|
||||
typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
|
||||
if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
|
||||
if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1033,7 +1042,7 @@ public:
|
|||
if (data_.a.size != rhs.data_.a.size)
|
||||
return false;
|
||||
for (SizeType i = 0; i < data_.a.size; i++)
|
||||
if ((*this)[i] != rhs[i])
|
||||
if (!((*this)[i] == rhs[i]))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
|
@ -1069,6 +1078,7 @@ public:
|
|||
*/
|
||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
||||
|
||||
#ifndef __cpp_impl_three_way_comparison
|
||||
//! Not-equal-to operator
|
||||
/*! \return !(*this == rhs)
|
||||
*/
|
||||
|
@ -1093,6 +1103,7 @@ public:
|
|||
*/
|
||||
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
||||
//@}
|
||||
#endif
|
||||
|
||||
//!@name Type
|
||||
//@{
|
||||
|
@ -1219,13 +1230,28 @@ public:
|
|||
else {
|
||||
RAPIDJSON_ASSERT(false); // see above note
|
||||
|
||||
// This will generate -Wexit-time-destructors in clang
|
||||
// static GenericValue NullValue;
|
||||
// return NullValue;
|
||||
|
||||
// Use static buffer and placement-new to prevent destruction
|
||||
static char buffer[sizeof(GenericValue)];
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
// Use thread-local storage to prevent races between threads.
|
||||
// Use static buffer and placement-new to prevent destruction, with
|
||||
// alignas() to ensure proper alignment.
|
||||
alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
|
||||
return *new (buffer) GenericValue();
|
||||
#elif defined(_MSC_VER) && _MSC_VER < 1900
|
||||
// There's no way to solve both thread locality and proper alignment
|
||||
// simultaneously.
|
||||
__declspec(thread) static char buffer[sizeof(GenericValue)];
|
||||
return *new (buffer) GenericValue();
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
// This will generate -Wexit-time-destructors in clang, but that's
|
||||
// better than having under-alignment.
|
||||
__thread static GenericValue buffer;
|
||||
return buffer;
|
||||
#else
|
||||
// Don't know what compiler this is, so don't know how to ensure
|
||||
// thread-locality.
|
||||
static GenericValue buffer;
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
template <typename SourceAllocator>
|
||||
|
@ -1258,10 +1284,7 @@ public:
|
|||
*/
|
||||
GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
if (newCapacity > data_.o.capacity) {
|
||||
SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
|
||||
data_.o.capacity = newCapacity;
|
||||
}
|
||||
DoReserveMembers(newCapacity, allocator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1335,11 +1358,7 @@ public:
|
|||
MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
RAPIDJSON_ASSERT(name.IsString());
|
||||
MemberIterator member = MemberBegin();
|
||||
for ( ; member != MemberEnd(); ++member)
|
||||
if (name.StringEqual(member->name))
|
||||
break;
|
||||
return member;
|
||||
return DoFindMember(name);
|
||||
}
|
||||
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
||||
|
||||
|
@ -1368,14 +1387,7 @@ public:
|
|||
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
RAPIDJSON_ASSERT(name.IsString());
|
||||
|
||||
ObjectData& o = data_.o;
|
||||
if (o.size >= o.capacity)
|
||||
MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
|
||||
Member* members = GetMembersPointer();
|
||||
members[o.size].name.RawAssign(name);
|
||||
members[o.size].value.RawAssign(value);
|
||||
o.size++;
|
||||
DoAddMember(name, value, allocator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1509,9 +1521,7 @@ public:
|
|||
*/
|
||||
void RemoveAllMembers() {
|
||||
RAPIDJSON_ASSERT(IsObject());
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
data_.o.size = 0;
|
||||
DoClearMembers();
|
||||
}
|
||||
|
||||
//! Remove a member in object by its name.
|
||||
|
@ -1555,14 +1565,7 @@ public:
|
|||
RAPIDJSON_ASSERT(data_.o.size > 0);
|
||||
RAPIDJSON_ASSERT(GetMembersPointer() != 0);
|
||||
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
|
||||
|
||||
MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
|
||||
if (data_.o.size > 1 && m != last)
|
||||
*m = *last; // Move the last one to this place
|
||||
else
|
||||
m->~Member(); // Only one left, just destroy
|
||||
--data_.o.size;
|
||||
return m;
|
||||
return DoRemoveMember(m);
|
||||
}
|
||||
|
||||
//! Remove a member from an object by iterator.
|
||||
|
@ -1594,13 +1597,7 @@ public:
|
|||
RAPIDJSON_ASSERT(first >= MemberBegin());
|
||||
RAPIDJSON_ASSERT(first <= last);
|
||||
RAPIDJSON_ASSERT(last <= MemberEnd());
|
||||
|
||||
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
||||
for (MemberIterator itr = pos; itr != last; ++itr)
|
||||
itr->~Member();
|
||||
std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
||||
data_.o.size -= static_cast<SizeType>(last - first);
|
||||
return pos;
|
||||
return DoEraseMembers(first, last);
|
||||
}
|
||||
|
||||
//! Erase a member in object by its name.
|
||||
|
@ -1629,7 +1626,9 @@ public:
|
|||
}
|
||||
|
||||
Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||
Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
||||
ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||
ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
||||
|
||||
//@}
|
||||
|
||||
|
@ -1851,12 +1850,12 @@ public:
|
|||
//!@name String
|
||||
//@{
|
||||
|
||||
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
|
||||
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
|
||||
|
||||
//! Get the length of string.
|
||||
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
||||
*/
|
||||
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
|
||||
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
|
||||
|
||||
//! Set this value as a string without copying source string.
|
||||
/*! This version has better performance with supplied length, and also support string containing null character.
|
||||
|
@ -1967,7 +1966,7 @@ public:
|
|||
case kArrayType:
|
||||
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
||||
return false;
|
||||
for (const GenericValue* v = Begin(); v != End(); ++v)
|
||||
for (ConstValueIterator v = Begin(); v != End(); ++v)
|
||||
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
|
||||
return false;
|
||||
return handler.EndArray(data_.a.size);
|
||||
|
@ -2105,6 +2104,13 @@ private:
|
|||
Flag f;
|
||||
}; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
||||
|
||||
static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
|
||||
return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
|
||||
}
|
||||
static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
|
||||
return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
|
||||
}
|
||||
|
||||
RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
|
||||
RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
|
||||
RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
|
||||
|
@ -2112,6 +2118,286 @@ private:
|
|||
RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
|
||||
RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
|
||||
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
|
||||
struct MapTraits {
|
||||
struct Less {
|
||||
bool operator()(const Data& s1, const Data& s2) const {
|
||||
SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
|
||||
int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
|
||||
return cmp < 0 || (cmp == 0 && n1 < n2);
|
||||
}
|
||||
};
|
||||
typedef std::pair<const Data, SizeType> Pair;
|
||||
typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
|
||||
typedef typename Map::iterator Iterator;
|
||||
};
|
||||
typedef typename MapTraits::Map Map;
|
||||
typedef typename MapTraits::Less MapLess;
|
||||
typedef typename MapTraits::Pair MapPair;
|
||||
typedef typename MapTraits::Iterator MapIterator;
|
||||
|
||||
//
|
||||
// Layout of the members' map/array, re(al)located according to the needed capacity:
|
||||
//
|
||||
// {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
|
||||
//
|
||||
// (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
|
||||
//
|
||||
|
||||
static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
|
||||
return RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||
RAPIDJSON_ALIGN(sizeof(SizeType)) +
|
||||
RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
|
||||
capacity * sizeof(MapIterator);
|
||||
}
|
||||
|
||||
static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
|
||||
return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
|
||||
RAPIDJSON_ALIGN(sizeof(Map*)));
|
||||
}
|
||||
|
||||
static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
|
||||
return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
|
||||
RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||
RAPIDJSON_ALIGN(sizeof(SizeType)));
|
||||
}
|
||||
|
||||
static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
|
||||
return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
|
||||
RAPIDJSON_ALIGN(sizeof(Map*)) +
|
||||
RAPIDJSON_ALIGN(sizeof(SizeType)) +
|
||||
RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
|
||||
}
|
||||
|
||||
static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
|
||||
RAPIDJSON_ASSERT(members != 0);
|
||||
return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
|
||||
RAPIDJSON_ALIGN(sizeof(SizeType)) -
|
||||
RAPIDJSON_ALIGN(sizeof(Map*)));
|
||||
}
|
||||
|
||||
// Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
|
||||
RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
MapIterator ret = std::move(rhs);
|
||||
#else
|
||||
MapIterator ret = rhs;
|
||||
#endif
|
||||
rhs.~MapIterator();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
|
||||
Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
|
||||
GetMapCapacity(*newMap) = newCapacity;
|
||||
if (!oldMap) {
|
||||
*newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
|
||||
}
|
||||
else {
|
||||
*newMap = *oldMap;
|
||||
size_t count = (*oldMap)->size();
|
||||
std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
|
||||
static_cast<void*>(GetMapMembers(*oldMap)),
|
||||
count * sizeof(Member));
|
||||
MapIterator *oldIt = GetMapIterators(*oldMap),
|
||||
*newIt = GetMapIterators(*newMap);
|
||||
while (count--) {
|
||||
new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
|
||||
}
|
||||
Allocator::Free(oldMap);
|
||||
}
|
||||
return *newMap;
|
||||
}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
|
||||
return GetMapMembers(DoReallocMap(0, capacity, allocator));
|
||||
}
|
||||
|
||||
void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
|
||||
ObjectData& o = data_.o;
|
||||
if (newCapacity > o.capacity) {
|
||||
Member* oldMembers = GetMembersPointer();
|
||||
Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
|
||||
*&newMap = DoReallocMap(oldMap, newCapacity, allocator);
|
||||
RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
|
||||
o.capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SourceAllocator>
|
||||
MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||
if (Member* members = GetMembersPointer()) {
|
||||
Map* &map = GetMap(members);
|
||||
MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
|
||||
if (mit != map->end()) {
|
||||
return MemberIterator(&members[mit->second]);
|
||||
}
|
||||
}
|
||||
return MemberEnd();
|
||||
}
|
||||
|
||||
void DoClearMembers() {
|
||||
if (Member* members = GetMembersPointer()) {
|
||||
Map* &map = GetMap(members);
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
for (SizeType i = 0; i < data_.o.size; i++) {
|
||||
map->erase(DropMapIterator(mit[i]));
|
||||
members[i].~Member();
|
||||
}
|
||||
data_.o.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DoFreeMembers() {
|
||||
if (Member* members = GetMembersPointer()) {
|
||||
GetMap(members)->~Map();
|
||||
for (SizeType i = 0; i < data_.o.size; i++) {
|
||||
members[i].~Member();
|
||||
}
|
||||
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
||||
Map** map = &GetMap(members);
|
||||
Allocator::Free(*map);
|
||||
Allocator::Free(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else // !RAPIDJSON_USE_MEMBERSMAP
|
||||
|
||||
RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
|
||||
return Malloc<Member>(allocator, capacity);
|
||||
}
|
||||
|
||||
void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
|
||||
ObjectData& o = data_.o;
|
||||
if (newCapacity > o.capacity) {
|
||||
Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
|
||||
RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
|
||||
o.capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SourceAllocator>
|
||||
MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||
MemberIterator member = MemberBegin();
|
||||
for ( ; member != MemberEnd(); ++member)
|
||||
if (name.StringEqual(member->name))
|
||||
break;
|
||||
return member;
|
||||
}
|
||||
|
||||
void DoClearMembers() {
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
data_.o.size = 0;
|
||||
}
|
||||
|
||||
void DoFreeMembers() {
|
||||
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
|
||||
m->~Member();
|
||||
Allocator::Free(GetMembersPointer());
|
||||
}
|
||||
|
||||
#endif // !RAPIDJSON_USE_MEMBERSMAP
|
||||
|
||||
void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
||||
ObjectData& o = data_.o;
|
||||
if (o.size >= o.capacity)
|
||||
DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
|
||||
Member* members = GetMembersPointer();
|
||||
Member* m = members + o.size;
|
||||
m->name.RawAssign(name);
|
||||
m->value.RawAssign(value);
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
Map* &map = GetMap(members);
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
|
||||
#endif
|
||||
++o.size;
|
||||
}
|
||||
|
||||
MemberIterator DoRemoveMember(MemberIterator m) {
|
||||
ObjectData& o = data_.o;
|
||||
Member* members = GetMembersPointer();
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
Map* &map = GetMap(members);
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
SizeType mpos = static_cast<SizeType>(&*m - members);
|
||||
map->erase(DropMapIterator(mit[mpos]));
|
||||
#endif
|
||||
MemberIterator last(members + (o.size - 1));
|
||||
if (o.size > 1 && m != last) {
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
|
||||
mit[mpos]->second = mpos;
|
||||
#endif
|
||||
*m = *last; // Move the last one to this place
|
||||
}
|
||||
else {
|
||||
m->~Member(); // Only one left, just destroy
|
||||
}
|
||||
--o.size;
|
||||
return m;
|
||||
}
|
||||
|
||||
MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
|
||||
ObjectData& o = data_.o;
|
||||
MemberIterator beg = MemberBegin(),
|
||||
pos = beg + (first - beg),
|
||||
end = MemberEnd();
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
Map* &map = GetMap(GetMembersPointer());
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
#endif
|
||||
for (MemberIterator itr = pos; itr != last; ++itr) {
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
map->erase(DropMapIterator(mit[itr - beg]));
|
||||
#endif
|
||||
itr->~Member();
|
||||
}
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
if (first != last) {
|
||||
// Move remaining members/iterators
|
||||
MemberIterator next = pos + (last - first);
|
||||
for (MemberIterator itr = pos; next != end; ++itr, ++next) {
|
||||
std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
|
||||
SizeType mpos = static_cast<SizeType>(itr - beg);
|
||||
new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
|
||||
mit[mpos]->second = mpos;
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::memmove(static_cast<void*>(&*pos), &*last,
|
||||
static_cast<size_t>(end - last) * sizeof(Member));
|
||||
#endif
|
||||
o.size -= static_cast<SizeType>(last - first);
|
||||
return pos;
|
||||
}
|
||||
|
||||
template <typename SourceAllocator>
|
||||
void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
|
||||
RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
|
||||
|
||||
data_.f.flags = kObjectFlag;
|
||||
SizeType count = rhs.data_.o.size;
|
||||
Member* lm = DoAllocMembers(count, allocator);
|
||||
const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
Map* &map = GetMap(lm);
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
#endif
|
||||
for (SizeType i = 0; i < count; i++) {
|
||||
new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
|
||||
new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
|
||||
#endif
|
||||
}
|
||||
data_.o.size = data_.o.capacity = count;
|
||||
SetMembersPointer(lm);
|
||||
}
|
||||
|
||||
// Initialize this value as array with initial data, without calling destructor.
|
||||
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
||||
data_.f.flags = kArrayFlag;
|
||||
|
@ -2129,9 +2415,16 @@ private:
|
|||
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
||||
data_.f.flags = kObjectFlag;
|
||||
if (count) {
|
||||
Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
||||
Member* m = DoAllocMembers(count, allocator);
|
||||
SetMembersPointer(m);
|
||||
std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
|
||||
#if RAPIDJSON_USE_MEMBERSMAP
|
||||
Map* &map = GetMap(m);
|
||||
MapIterator* mit = GetMapIterators(map);
|
||||
for (SizeType i = 0; i < count; i++) {
|
||||
new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
SetMembersPointer(0);
|
||||
|
@ -2208,6 +2501,7 @@ public:
|
|||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
|
||||
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
||||
typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter.
|
||||
|
||||
//! Constructor
|
||||
/*! Creates an empty document of specified type.
|
||||
|
@ -2252,6 +2546,13 @@ public:
|
|||
#endif
|
||||
|
||||
~GenericDocument() {
|
||||
// Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
|
||||
// runs last and may access its elements or members which would be freed
|
||||
// with an allocator like MemoryPoolAllocator (CrtAllocator does not
|
||||
// free its data when destroyed, but MemoryPoolAllocator does).
|
||||
if (ownAllocator_) {
|
||||
ValueType::SetNull();
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
|
@ -2734,4 +3035,9 @@ private:
|
|||
RAPIDJSON_NAMESPACE_END
|
||||
RAPIDJSON_DIAG_POP
|
||||
|
||||
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||
#pragma pop_macro("GetObject")
|
||||
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_DOCUMENT_H_
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// 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.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
|
@ -7,9 +7,9 @@
|
|||
//
|
||||
// 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_ERROR_EN_H_
|
||||
|
@ -39,13 +39,13 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
|||
|
||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
||||
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
||||
|
||||
|
||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||
|
||||
|
||||
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
||||
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
||||
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
||||
|
||||
|
||||
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
||||
|
||||
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
||||
|
@ -104,15 +104,69 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode val
|
|||
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
||||
|
||||
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
||||
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
|
||||
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'.");
|
||||
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
||||
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
||||
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
||||
|
||||
case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing.");
|
||||
case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
//! Maps error code of schema document compilation into error message.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\param schemaErrorCode Error code obtained from compiling the schema document.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) {
|
||||
switch (schemaErrorCode) {
|
||||
case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document.");
|
||||
case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer.");
|
||||
case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string.");
|
||||
case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'.");
|
||||
case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document.");
|
||||
case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical.");
|
||||
case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider.");
|
||||
case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema.");
|
||||
case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'.");
|
||||
case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized.");
|
||||
case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported.");
|
||||
case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document.");
|
||||
case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
//! Maps error code of pointer parse into error message.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_ERRORS
|
||||
\param pointerParseErrorCode Error code obtained from pointer parse.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) {
|
||||
switch (pointerParseErrorCode) {
|
||||
case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'.");
|
||||
case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape.");
|
||||
case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment.");
|
||||
case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment.");
|
||||
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// 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.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
|
@ -7,9 +7,9 @@
|
|||
//
|
||||
// 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_ERROR_ERROR_H_
|
||||
|
@ -42,7 +42,7 @@ RAPIDJSON_DIAG_OFF(padded)
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_STRING
|
||||
|
||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
By default this conversion macro does nothing.
|
||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
||||
|
@ -185,14 +185,17 @@ enum ValidateErrorCode {
|
|||
kValidateErrorPatternProperties, //!< See other errors.
|
||||
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
|
||||
|
||||
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values
|
||||
kValidateErrorType, //!< Property has a type that is not allowed by the schema..
|
||||
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values.
|
||||
kValidateErrorType, //!< Property has a type that is not allowed by the schema.
|
||||
|
||||
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
|
||||
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
|
||||
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
|
||||
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
|
||||
kValidateErrorNot //!< Property matched the sub-schema specified by 'not'.
|
||||
kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'.
|
||||
|
||||
kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing
|
||||
kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading
|
||||
};
|
||||
|
||||
//! Function pointer type of GetValidateError().
|
||||
|
@ -207,6 +210,72 @@ enum ValidateErrorCode {
|
|||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SchemaErrorCode
|
||||
|
||||
//! Error codes when validating.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericSchemaValidator
|
||||
*/
|
||||
enum SchemaErrorCode {
|
||||
kSchemaErrorNone = 0, //!< No error.
|
||||
|
||||
kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document
|
||||
kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer
|
||||
kSchemaErrorRefInvalid, //!< $ref must not be an empty string
|
||||
kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset
|
||||
kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document
|
||||
kSchemaErrorRefCyclical, //!< $ref is cyclical
|
||||
kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider
|
||||
kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema
|
||||
kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties'
|
||||
kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized
|
||||
kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported
|
||||
kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document
|
||||
kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly'
|
||||
};
|
||||
|
||||
//! Function pointer type of GetSchemaError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetSchemaError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PointerParseErrorCode
|
||||
|
||||
//! Error code of JSON pointer parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
||||
*/
|
||||
enum PointerParseErrorCode {
|
||||
kPointerParseErrorNone = 0, //!< The parse is successful
|
||||
|
||||
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
||||
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
||||
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
||||
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
||||
};
|
||||
|
||||
//! Function pointer type of GetPointerParseError().
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
|
||||
This is the prototype for \c GetPointerParseError_X(), where \c X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
\code
|
||||
GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode());
|
||||
\endcode
|
||||
*/
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode);
|
||||
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
||||
#include <intrin.h> // for _umul128
|
||||
#if !defined(_ARM64EC_)
|
||||
#pragma intrinsic(_umul128)
|
||||
#else
|
||||
#pragma comment(lib,"softintrin")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -37,7 +41,8 @@ public:
|
|||
digits_[0] = u;
|
||||
}
|
||||
|
||||
BigInteger(const char* decimals, size_t length) : count_(1) {
|
||||
template<typename Ch>
|
||||
BigInteger(const Ch* decimals, size_t length) : count_(1) {
|
||||
RAPIDJSON_ASSERT(length > 0);
|
||||
digits_[0] = 0;
|
||||
size_t i = 0;
|
||||
|
@ -221,7 +226,8 @@ public:
|
|||
bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
|
||||
|
||||
private:
|
||||
void AppendDecimal64(const char* begin, const char* end) {
|
||||
template<typename Ch>
|
||||
void AppendDecimal64(const Ch* begin, const Ch* end) {
|
||||
uint64_t u = ParseUint64(begin, end);
|
||||
if (IsZero())
|
||||
*this = u;
|
||||
|
@ -236,11 +242,12 @@ private:
|
|||
digits_[count_++] = digit;
|
||||
}
|
||||
|
||||
static uint64_t ParseUint64(const char* begin, const char* end) {
|
||||
template<typename Ch>
|
||||
static uint64_t ParseUint64(const Ch* begin, const Ch* end) {
|
||||
uint64_t r = 0;
|
||||
for (const char* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
||||
r = r * 10u + static_cast<unsigned>(*p - '0');
|
||||
for (const Ch* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= Ch('0') && *p <= Ch('9'));
|
||||
r = r * 10u + static_cast<unsigned>(*p - Ch('0'));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -252,7 +259,7 @@ private:
|
|||
if (low < k)
|
||||
(*outHigh)++;
|
||||
return low;
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
__extension__ typedef unsigned __int128 uint128;
|
||||
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
|
||||
p += k;
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||
#include <intrin.h>
|
||||
#if !defined(_ARM64EC_)
|
||||
#pragma intrinsic(_umul128)
|
||||
#else
|
||||
#pragma comment(lib,"softintrin")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -75,7 +79,7 @@ struct DiyFp {
|
|||
if (l & (uint64_t(1) << 63)) // rounding
|
||||
h++;
|
||||
return DiyFp(h, e + rhs.e + 64);
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
__extension__ typedef unsigned __int128 uint128;
|
||||
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
|
||||
uint64_t h = static_cast<uint64_t>(p >> 64);
|
||||
|
|
|
@ -58,7 +58,11 @@ inline int CountDecimalDigit32(uint32_t n) {
|
|||
}
|
||||
|
||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||
static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL,
|
||||
1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL,
|
||||
10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
|
||||
10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
|
||||
10000000000000000000ULL };
|
||||
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
||||
const DiyFp wp_w = Mp - W;
|
||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||
|
@ -86,7 +90,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
|
||||
if (tmp <= delta) {
|
||||
*K += kappa;
|
||||
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
|
||||
GrisuRound(buffer, *len, delta, tmp, kPow10[kappa] << -one.e, wp_w.f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +107,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||
if (p2 < delta) {
|
||||
*K += kappa;
|
||||
int index = -kappa;
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 20 ? kPow10[index] : 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -615,7 +615,7 @@ public:
|
|||
RAPIDJSON_ASSERT(regex_.IsValid());
|
||||
if (!allocator_)
|
||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||
stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));
|
||||
stateSet_ = static_cast<uint32_t*>(allocator_->Malloc(GetStateSetSize()));
|
||||
state0_.template Reserve<SizeType>(regex_.stateCount_);
|
||||
state1_.template Reserve<SizeType>(regex_.stateCount_);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,20 @@ inline SizeType StrLen(const wchar_t* s) {
|
|||
return SizeType(std::wcslen(s));
|
||||
}
|
||||
|
||||
//! Custom strcmpn() which works on different character types.
|
||||
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
|
||||
\param s1 Null-terminated input string.
|
||||
\param s2 Null-terminated input string.
|
||||
\return 0 if equal
|
||||
*/
|
||||
template<typename Ch>
|
||||
inline int StrCmp(const Ch* s1, const Ch* s2) {
|
||||
RAPIDJSON_ASSERT(s1 != 0);
|
||||
RAPIDJSON_ASSERT(s2 != 0);
|
||||
while(*s1 && (*s1 == *s2)) { s1++; s2++; }
|
||||
return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
|
||||
}
|
||||
|
||||
//! Returns number of code points in a encoded string.
|
||||
template<typename Encoding>
|
||||
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
|
||||
|
|
|
@ -128,17 +128,18 @@ 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, int dLen, int dExp, double* result) {
|
||||
template<typename Ch>
|
||||
inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result) {
|
||||
uint64_t significand = 0;
|
||||
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'))
|
||||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5')))
|
||||
break;
|
||||
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
|
||||
significand = significand * 10u + static_cast<unsigned>(decimals[i] - Ch('0'));
|
||||
}
|
||||
|
||||
if (i < dLen && decimals[i] >= '5') // Rounding
|
||||
if (i < dLen && decimals[i] >= Ch('5')) // Rounding
|
||||
significand++;
|
||||
|
||||
int remaining = dLen - i;
|
||||
|
@ -205,7 +206,8 @@ inline bool StrtodDiyFp(const char* decimals, int dLen, int dExp, double* result
|
|||
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
|
||||
}
|
||||
|
||||
inline double StrtodBigInteger(double approx, const char* decimals, int dLen, int dExp) {
|
||||
template<typename Ch>
|
||||
inline double StrtodBigInteger(double approx, const Ch* decimals, int dLen, int dExp) {
|
||||
RAPIDJSON_ASSERT(dLen >= 0);
|
||||
const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
|
||||
Double a(approx);
|
||||
|
@ -223,7 +225,8 @@ inline double StrtodBigInteger(double approx, const char* decimals, int dLen, in
|
|||
return a.NextPositiveDouble();
|
||||
}
|
||||
|
||||
inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||
template<typename Ch>
|
||||
inline double StrtodFullPrecision(double d, int p, const Ch* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||
RAPIDJSON_ASSERT(d >= 0.0);
|
||||
RAPIDJSON_ASSERT(length >= 1);
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#define RAPIDJSON_POINTER_H_
|
||||
|
||||
#include "document.h"
|
||||
#include "uri.h"
|
||||
#include "internal/itoa.h"
|
||||
#include "error/error.h" // PointerParseErrorCode
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
|
@ -30,19 +32,6 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||
|
||||
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
||||
|
||||
//! Error code of parsing.
|
||||
/*! \ingroup RAPIDJSON_ERRORS
|
||||
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
||||
*/
|
||||
enum PointerParseErrorCode {
|
||||
kPointerParseErrorNone = 0, //!< The parse is successful
|
||||
|
||||
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
||||
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
||||
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
||||
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GenericPointer
|
||||
|
||||
|
@ -68,10 +57,10 @@ enum PointerParseErrorCode {
|
|||
supplied tokens eliminates these.
|
||||
|
||||
GenericPointer depends on GenericDocument and GenericValue.
|
||||
|
||||
|
||||
\tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
|
||||
\tparam Allocator The allocator type for allocating memory for internal representation.
|
||||
|
||||
|
||||
\note GenericPointer uses same encoding of ValueType.
|
||||
However, Allocator of GenericPointer is independent of Allocator of Value.
|
||||
*/
|
||||
|
@ -80,8 +69,10 @@ class GenericPointer {
|
|||
public:
|
||||
typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
|
||||
typedef typename ValueType::Ch Ch; //!< Character type from Value
|
||||
typedef GenericUri<ValueType, Allocator> UriType;
|
||||
|
||||
//! A token is the basic units of internal representation.
|
||||
|
||||
//! A token is the basic units of internal representation.
|
||||
/*!
|
||||
A JSON pointer string representation "/foo/123" is parsed to two tokens:
|
||||
"foo" and 123. 123 will be represented in both numeric form and string form.
|
||||
|
@ -163,7 +154,7 @@ public:
|
|||
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_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||
GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
|
@ -520,6 +511,70 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
//!@name Compute URI
|
||||
//@{
|
||||
|
||||
//! Compute the in-scope URI for a subtree.
|
||||
// For use with JSON pointers into JSON schema documents.
|
||||
/*!
|
||||
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
|
||||
\param rootUri Root URI
|
||||
\param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
|
||||
\param allocator Allocator for Uris
|
||||
\return Uri if it can be resolved. Otherwise null.
|
||||
|
||||
\note
|
||||
There are only 3 situations when a URI cannot be resolved:
|
||||
1. A value in the path is not an array nor object.
|
||||
2. An object value does not contain the token.
|
||||
3. A token is out of range of an array value.
|
||||
|
||||
Use unresolvedTokenIndex to retrieve the token index.
|
||||
*/
|
||||
UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
|
||||
static const Ch kIdString[] = { 'i', 'd', '\0' };
|
||||
static const ValueType kIdValue(kIdString, 2);
|
||||
UriType base = UriType(rootUri, allocator);
|
||||
RAPIDJSON_ASSERT(IsValid());
|
||||
ValueType* v = &root;
|
||||
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
||||
switch (v->GetType()) {
|
||||
case kObjectType:
|
||||
{
|
||||
// See if we have an id, and if so resolve with the current base
|
||||
typename ValueType::MemberIterator m = v->FindMember(kIdValue);
|
||||
if (m != v->MemberEnd() && (m->value).IsString()) {
|
||||
UriType here = UriType(m->value, allocator).Resolve(base, allocator);
|
||||
base = here;
|
||||
}
|
||||
m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||
if (m == v->MemberEnd())
|
||||
break;
|
||||
v = &m->value;
|
||||
}
|
||||
continue;
|
||||
case kArrayType:
|
||||
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
|
||||
break;
|
||||
v = &((*v)[t->index]);
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Error: unresolved token
|
||||
if (unresolvedTokenIndex)
|
||||
*unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
|
||||
return UriType(allocator);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
|
||||
return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
|
||||
}
|
||||
|
||||
|
||||
//!@name Query value
|
||||
//@{
|
||||
|
||||
|
@ -634,7 +689,7 @@ public:
|
|||
ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
|
||||
return GetWithDefault(document, defaultValue, document.GetAllocator());
|
||||
}
|
||||
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
//! Query a value in a document with default std::basic_string.
|
||||
template <typename stackAllocator>
|
||||
|
@ -835,10 +890,16 @@ private:
|
|||
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
||||
}
|
||||
|
||||
// Adjust pointers to name buffer
|
||||
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
||||
for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
|
||||
t->name += diff;
|
||||
// The names of each token point to a string in the nameBuffer_. The
|
||||
// previous memcpy copied over string pointers into the rhs.nameBuffer_,
|
||||
// but they should point to the strings in the new nameBuffer_.
|
||||
for (size_t i = 0; i < rhs.tokenCount_; ++i) {
|
||||
// The offset between the string address and the name buffer should
|
||||
// still be constant, so we can just get this offset and set each new
|
||||
// token name according the new buffer start + the known offset.
|
||||
std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
|
||||
tokens_[i].name = nameBuffer_ + name_offset;
|
||||
}
|
||||
|
||||
return nameBuffer_ + nameBufferSize;
|
||||
}
|
||||
|
@ -928,7 +989,7 @@ private:
|
|||
}
|
||||
|
||||
i++;
|
||||
|
||||
|
||||
// Escaping "~0" -> '~', "~1" -> '/'
|
||||
if (c == '~') {
|
||||
if (i < length) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// 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.
|
||||
//
|
||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||
|
@ -7,9 +7,9 @@
|
|||
//
|
||||
// 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_RAPIDJSON_H_
|
||||
|
@ -17,7 +17,7 @@
|
|||
|
||||
/*!\file rapidjson.h
|
||||
\brief common definitions and configuration
|
||||
|
||||
|
||||
\see RAPIDJSON_CONFIG
|
||||
*/
|
||||
|
||||
|
@ -124,6 +124,19 @@
|
|||
#define RAPIDJSON_NAMESPACE_END }
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// __cplusplus macro
|
||||
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define RAPIDJSON_CPLUSPLUS _MSVC_LANG
|
||||
#else
|
||||
#define RAPIDJSON_CPLUSPLUS __cplusplus
|
||||
#endif
|
||||
|
||||
//!@endcond
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
|
@ -149,6 +162,24 @@
|
|||
#include <string>
|
||||
#endif // RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_USE_MEMBERSMAP
|
||||
|
||||
/*! \def RAPIDJSON_USE_MEMBERSMAP
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\brief Enable RapidJSON support for object members handling in a \c std::multimap
|
||||
|
||||
By defining this preprocessor symbol to \c 1, \ref rapidjson::GenericValue object
|
||||
members are stored in a \c std::multimap for faster lookup and deletion times, a
|
||||
trade off with a slightly slower insertion time and a small object allocat(or)ed
|
||||
memory overhead.
|
||||
|
||||
\hideinitializer
|
||||
*/
|
||||
#ifndef RAPIDJSON_USE_MEMBERSMAP
|
||||
#define RAPIDJSON_USE_MEMBERSMAP 0 // not by default
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_NO_INT64DEFINE
|
||||
|
||||
|
@ -164,7 +195,7 @@
|
|||
*/
|
||||
#ifndef RAPIDJSON_NO_INT64DEFINE
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
|
||||
#include "msinttypes/stdint.h"
|
||||
#include "msinttypes/inttypes.h"
|
||||
#else
|
||||
|
@ -246,7 +277,7 @@
|
|||
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
||||
# define RAPIDJSON_ENDIAN
|
||||
# else
|
||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||
# endif
|
||||
#endif // RAPIDJSON_ENDIAN
|
||||
|
||||
|
@ -411,7 +442,7 @@ RAPIDJSON_NAMESPACE_END
|
|||
|
||||
// Prefer C++11 static_assert, if available
|
||||
#ifndef RAPIDJSON_STATIC_ASSERT
|
||||
#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
|
||||
#if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
|
||||
#define RAPIDJSON_STATIC_ASSERT(x) \
|
||||
static_assert(x, RAPIDJSON_STRINGIFY(x))
|
||||
#endif // C++11
|
||||
|
@ -482,7 +513,7 @@ RAPIDJSON_NAMESPACE_END
|
|||
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
|
||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
||||
#define RAPIDJSON_MULTILINEMACRO_END \
|
||||
} while((void)0, 0)
|
||||
|
||||
|
@ -541,8 +572,14 @@ RAPIDJSON_NAMESPACE_END
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++11 features
|
||||
|
||||
#ifndef RAPIDJSON_HAS_CXX11
|
||||
#define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L)
|
||||
#endif
|
||||
|
||||
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
#if defined(__clang__)
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
||||
#elif defined(__clang__)
|
||||
#if __has_feature(cxx_rvalue_references) && \
|
||||
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
|
||||
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
|
||||
|
@ -559,8 +596,14 @@ RAPIDJSON_NAMESPACE_END
|
|||
#endif
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
#include <utility> // std::move
|
||||
#endif
|
||||
|
||||
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#if defined(__clang__)
|
||||
#if RAPIDJSON_HAS_CXX11
|
||||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
|
||||
#elif 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 >= 1900) || \
|
||||
|
@ -570,11 +613,13 @@ RAPIDJSON_NAMESPACE_END
|
|||
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef RAPIDJSON_NOEXCEPT
|
||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#define RAPIDJSON_NOEXCEPT noexcept
|
||||
#else
|
||||
#define RAPIDJSON_NOEXCEPT /* noexcept */
|
||||
#define RAPIDJSON_NOEXCEPT throw()
|
||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||
#endif
|
||||
|
||||
// no automatic detection, yet
|
||||
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
|
||||
|
@ -600,9 +645,17 @@ RAPIDJSON_NAMESPACE_END
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++17 features
|
||||
|
||||
#if defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(fallthrough)
|
||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
|
||||
#ifndef RAPIDJSON_HAS_CXX17
|
||||
#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L)
|
||||
#endif
|
||||
|
||||
#if RAPIDJSON_HAS_CXX17
|
||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
|
||||
#elif defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(clang::fallthrough)
|
||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]]
|
||||
# elif __has_cpp_attribute(fallthrough)
|
||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough))
|
||||
# else
|
||||
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
||||
# endif
|
||||
|
@ -628,12 +681,8 @@ RAPIDJSON_NAMESPACE_END
|
|||
|
||||
#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
|
||||
|
@ -682,7 +731,7 @@ enum Type {
|
|||
kFalseType = 1, //!< false
|
||||
kTrueType = 2, //!< true
|
||||
kObjectType = 3, //!< object
|
||||
kArrayType = 4, //!< array
|
||||
kArrayType = 4, //!< array
|
||||
kStringType = 5, //!< string
|
||||
kNumberType = 6 //!< number
|
||||
};
|
||||
|
|
|
@ -1404,11 +1404,11 @@ private:
|
|||
}
|
||||
#endif // RAPIDJSON_NEON
|
||||
|
||||
template<typename InputStream, bool backup, bool pushOnTake>
|
||||
template<typename InputStream, typename StackCharacter, bool backup, bool pushOnTake>
|
||||
class NumberStream;
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, false, false> {
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, false, false> {
|
||||
public:
|
||||
typedef typename InputStream::Ch Ch;
|
||||
|
||||
|
@ -1421,7 +1421,7 @@ private:
|
|||
|
||||
size_t Tell() { return is.Tell(); }
|
||||
size_t Length() { return 0; }
|
||||
const char* Pop() { return 0; }
|
||||
const StackCharacter* Pop() { return 0; }
|
||||
|
||||
protected:
|
||||
NumberStream& operator=(const NumberStream&);
|
||||
|
@ -1429,45 +1429,47 @@ private:
|
|||
InputStream& is;
|
||||
};
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
|
||||
typedef NumberStream<InputStream, false, false> Base;
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
||||
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
||||
stackStream.Put(static_cast<char>(Base::is.Peek()));
|
||||
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
|
||||
return Base::is.Take();
|
||||
}
|
||||
|
||||
RAPIDJSON_FORCEINLINE void Push(char c) {
|
||||
RAPIDJSON_FORCEINLINE void Push(StackCharacter c) {
|
||||
stackStream.Put(c);
|
||||
}
|
||||
|
||||
size_t Length() { return stackStream.Length(); }
|
||||
|
||||
const char* Pop() {
|
||||
const StackCharacter* Pop() {
|
||||
stackStream.Put('\0');
|
||||
return stackStream.Pop();
|
||||
}
|
||||
|
||||
private:
|
||||
StackStream<char> stackStream;
|
||||
StackStream<StackCharacter> stackStream;
|
||||
};
|
||||
|
||||
template<typename InputStream>
|
||||
class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
|
||||
typedef NumberStream<InputStream, true, false> Base;
|
||||
template<typename InputStream, typename StackCharacter>
|
||||
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
||||
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
||||
public:
|
||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
||||
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
|
||||
};
|
||||
|
||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||
void ParseNumber(InputStream& is, Handler& handler) {
|
||||
typedef typename internal::SelectIf<internal::BoolType<(parseFlags & kParseNumbersAsStringsFlag) != 0>, typename TargetEncoding::Ch, char>::Type NumberCharacter;
|
||||
|
||||
internal::StreamLocalCopy<InputStream> copy(is);
|
||||
NumberStream<InputStream,
|
||||
NumberStream<InputStream, NumberCharacter,
|
||||
((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
|
||||
((parseFlags & kParseInsituFlag) == 0) :
|
||||
((parseFlags & kParseFullPrecisionFlag) != 0),
|
||||
|
@ -1692,10 +1694,10 @@ private:
|
|||
}
|
||||
else {
|
||||
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
|
||||
StringStream srcStream(s.Pop());
|
||||
GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
|
||||
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
|
||||
while (numCharsToCopy--) {
|
||||
Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||
}
|
||||
dstStream.Put('\0');
|
||||
const typename TargetEncoding::Ch* str = dstStream.Pop();
|
||||
|
@ -1705,7 +1707,7 @@ private:
|
|||
}
|
||||
else {
|
||||
size_t length = s.Length();
|
||||
const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
|
||||
const NumberCharacter* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
|
||||
|
||||
if (useDouble) {
|
||||
int p = exp + expFrac;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,481 @@
|
|||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
//
|
||||
// (C) Copyright IBM Corporation 2021
|
||||
//
|
||||
// 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_URI_H_
|
||||
#define RAPIDJSON_URI_H_
|
||||
|
||||
#include "internal/strfunc.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#elif defined(_MSC_VER)
|
||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// GenericUri
|
||||
|
||||
template <typename ValueType, typename Allocator=CrtAllocator>
|
||||
class GenericUri {
|
||||
public:
|
||||
typedef typename ValueType::Ch Ch;
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
typedef std::basic_string<Ch> String;
|
||||
#endif
|
||||
|
||||
//! Constructors
|
||||
GenericUri(Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
}
|
||||
|
||||
GenericUri(const Ch* uri, SizeType len, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
Parse(uri, len);
|
||||
}
|
||||
|
||||
GenericUri(const Ch* uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
Parse(uri, internal::StrLen<Ch>(uri));
|
||||
}
|
||||
|
||||
// Use with specializations of GenericValue
|
||||
template<typename T> GenericUri(const T& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
const Ch* u = uri.template Get<const Ch*>(); // TypeHelper from document.h
|
||||
Parse(u, internal::StrLen<Ch>(u));
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
GenericUri(const String& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
Parse(uri.c_str(), internal::StrLen<Ch>(uri.c_str()));
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Copy constructor
|
||||
GenericUri(const GenericUri& rhs) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(), ownAllocator_() {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
//! Copy constructor
|
||||
GenericUri(const GenericUri& rhs, Allocator* allocator) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
//! Destructor.
|
||||
~GenericUri() {
|
||||
Free();
|
||||
RAPIDJSON_DELETE(ownAllocator_);
|
||||
}
|
||||
|
||||
//! Assignment operator
|
||||
GenericUri& operator=(const GenericUri& rhs) {
|
||||
if (this != &rhs) {
|
||||
// Do not delete ownAllocator
|
||||
Free();
|
||||
Allocate(rhs.GetStringLength());
|
||||
auth_ = CopyPart(scheme_, rhs.scheme_, rhs.GetSchemeStringLength());
|
||||
path_ = CopyPart(auth_, rhs.auth_, rhs.GetAuthStringLength());
|
||||
query_ = CopyPart(path_, rhs.path_, rhs.GetPathStringLength());
|
||||
frag_ = CopyPart(query_, rhs.query_, rhs.GetQueryStringLength());
|
||||
base_ = CopyPart(frag_, rhs.frag_, rhs.GetFragStringLength());
|
||||
uri_ = CopyPart(base_, rhs.base_, rhs.GetBaseStringLength());
|
||||
CopyPart(uri_, rhs.uri_, rhs.GetStringLength());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Getters
|
||||
// Use with specializations of GenericValue
|
||||
template<typename T> void Get(T& uri, Allocator& allocator) {
|
||||
uri.template Set<const Ch*>(this->GetString(), allocator); // TypeHelper from document.h
|
||||
}
|
||||
|
||||
const Ch* GetString() const { return uri_; }
|
||||
SizeType GetStringLength() const { return uri_ == 0 ? 0 : internal::StrLen<Ch>(uri_); }
|
||||
const Ch* GetBaseString() const { return base_; }
|
||||
SizeType GetBaseStringLength() const { return base_ == 0 ? 0 : internal::StrLen<Ch>(base_); }
|
||||
const Ch* GetSchemeString() const { return scheme_; }
|
||||
SizeType GetSchemeStringLength() const { return scheme_ == 0 ? 0 : internal::StrLen<Ch>(scheme_); }
|
||||
const Ch* GetAuthString() const { return auth_; }
|
||||
SizeType GetAuthStringLength() const { return auth_ == 0 ? 0 : internal::StrLen<Ch>(auth_); }
|
||||
const Ch* GetPathString() const { return path_; }
|
||||
SizeType GetPathStringLength() const { return path_ == 0 ? 0 : internal::StrLen<Ch>(path_); }
|
||||
const Ch* GetQueryString() const { return query_; }
|
||||
SizeType GetQueryStringLength() const { return query_ == 0 ? 0 : internal::StrLen<Ch>(query_); }
|
||||
const Ch* GetFragString() const { return frag_; }
|
||||
SizeType GetFragStringLength() const { return frag_ == 0 ? 0 : internal::StrLen<Ch>(frag_); }
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
static String Get(const GenericUri& uri) { return String(uri.GetString(), uri.GetStringLength()); }
|
||||
static String GetBase(const GenericUri& uri) { return String(uri.GetBaseString(), uri.GetBaseStringLength()); }
|
||||
static String GetScheme(const GenericUri& uri) { return String(uri.GetSchemeString(), uri.GetSchemeStringLength()); }
|
||||
static String GetAuth(const GenericUri& uri) { return String(uri.GetAuthString(), uri.GetAuthStringLength()); }
|
||||
static String GetPath(const GenericUri& uri) { return String(uri.GetPathString(), uri.GetPathStringLength()); }
|
||||
static String GetQuery(const GenericUri& uri) { return String(uri.GetQueryString(), uri.GetQueryStringLength()); }
|
||||
static String GetFrag(const GenericUri& uri) { return String(uri.GetFragString(), uri.GetFragStringLength()); }
|
||||
#endif
|
||||
|
||||
//! Equality operators
|
||||
bool operator==(const GenericUri& rhs) const {
|
||||
return Match(rhs, true);
|
||||
}
|
||||
|
||||
bool operator!=(const GenericUri& rhs) const {
|
||||
return !Match(rhs, true);
|
||||
}
|
||||
|
||||
bool Match(const GenericUri& uri, bool full = true) const {
|
||||
Ch* s1;
|
||||
Ch* s2;
|
||||
if (full) {
|
||||
s1 = uri_;
|
||||
s2 = uri.uri_;
|
||||
} else {
|
||||
s1 = base_;
|
||||
s2 = uri.base_;
|
||||
}
|
||||
if (s1 == s2) return true;
|
||||
if (s1 == 0 || s2 == 0) return false;
|
||||
return internal::StrCmp<Ch>(s1, s2) == 0;
|
||||
}
|
||||
|
||||
//! Resolve this URI against another (base) URI in accordance with URI resolution rules.
|
||||
// See https://tools.ietf.org/html/rfc3986
|
||||
// Use for resolving an id or $ref with an in-scope id.
|
||||
// Returns a new GenericUri for the resolved URI.
|
||||
GenericUri Resolve(const GenericUri& baseuri, Allocator* allocator = 0) {
|
||||
GenericUri resuri;
|
||||
resuri.allocator_ = allocator;
|
||||
// Ensure enough space for combining paths
|
||||
resuri.Allocate(GetStringLength() + baseuri.GetStringLength() + 1); // + 1 for joining slash
|
||||
|
||||
if (!(GetSchemeStringLength() == 0)) {
|
||||
// Use all of this URI
|
||||
resuri.auth_ = CopyPart(resuri.scheme_, scheme_, GetSchemeStringLength());
|
||||
resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
|
||||
resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
|
||||
resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
|
||||
resuri.RemoveDotSegments();
|
||||
} else {
|
||||
// Use the base scheme
|
||||
resuri.auth_ = CopyPart(resuri.scheme_, baseuri.scheme_, baseuri.GetSchemeStringLength());
|
||||
if (!(GetAuthStringLength() == 0)) {
|
||||
// Use this auth, path, query
|
||||
resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
|
||||
resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
|
||||
resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
|
||||
resuri.RemoveDotSegments();
|
||||
} else {
|
||||
// Use the base auth
|
||||
resuri.path_ = CopyPart(resuri.auth_, baseuri.auth_, baseuri.GetAuthStringLength());
|
||||
if (GetPathStringLength() == 0) {
|
||||
// Use the base path
|
||||
resuri.query_ = CopyPart(resuri.path_, baseuri.path_, baseuri.GetPathStringLength());
|
||||
if (GetQueryStringLength() == 0) {
|
||||
// Use the base query
|
||||
resuri.frag_ = CopyPart(resuri.query_, baseuri.query_, baseuri.GetQueryStringLength());
|
||||
} else {
|
||||
// Use this query
|
||||
resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
|
||||
}
|
||||
} else {
|
||||
if (path_[0] == '/') {
|
||||
// Absolute path - use all of this path
|
||||
resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
|
||||
resuri.RemoveDotSegments();
|
||||
} else {
|
||||
// Relative path - append this path to base path after base path's last slash
|
||||
size_t pos = 0;
|
||||
if (!(baseuri.GetAuthStringLength() == 0) && baseuri.GetPathStringLength() == 0) {
|
||||
resuri.path_[pos] = '/';
|
||||
pos++;
|
||||
}
|
||||
size_t lastslashpos = baseuri.GetPathStringLength();
|
||||
while (lastslashpos > 0) {
|
||||
if (baseuri.path_[lastslashpos - 1] == '/') break;
|
||||
lastslashpos--;
|
||||
}
|
||||
std::memcpy(&resuri.path_[pos], baseuri.path_, lastslashpos * sizeof(Ch));
|
||||
pos += lastslashpos;
|
||||
resuri.query_ = CopyPart(&resuri.path_[pos], path_, GetPathStringLength());
|
||||
resuri.RemoveDotSegments();
|
||||
}
|
||||
// Use this query
|
||||
resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Always use this frag
|
||||
resuri.base_ = CopyPart(resuri.frag_, frag_, GetFragStringLength());
|
||||
|
||||
// Re-constitute base_ and uri_
|
||||
resuri.SetBase();
|
||||
resuri.uri_ = resuri.base_ + resuri.GetBaseStringLength() + 1;
|
||||
resuri.SetUri();
|
||||
return resuri;
|
||||
}
|
||||
|
||||
//! Get the allocator of this GenericUri.
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
|
||||
private:
|
||||
// Allocate memory for a URI
|
||||
// Returns total amount allocated
|
||||
std::size_t Allocate(std::size_t len) {
|
||||
// Create own allocator if user did not supply.
|
||||
if (!allocator_)
|
||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
|
||||
|
||||
// Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated.
|
||||
// Order: scheme, auth, path, query, frag, base, uri
|
||||
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
|
||||
size_t total = (3 * len + 7) * sizeof(Ch);
|
||||
scheme_ = static_cast<Ch*>(allocator_->Malloc(total));
|
||||
*scheme_ = '\0';
|
||||
auth_ = scheme_;
|
||||
auth_++;
|
||||
*auth_ = '\0';
|
||||
path_ = auth_;
|
||||
path_++;
|
||||
*path_ = '\0';
|
||||
query_ = path_;
|
||||
query_++;
|
||||
*query_ = '\0';
|
||||
frag_ = query_;
|
||||
frag_++;
|
||||
*frag_ = '\0';
|
||||
base_ = frag_;
|
||||
base_++;
|
||||
*base_ = '\0';
|
||||
uri_ = base_;
|
||||
uri_++;
|
||||
*uri_ = '\0';
|
||||
return total;
|
||||
}
|
||||
|
||||
// Free memory for a URI
|
||||
void Free() {
|
||||
if (scheme_) {
|
||||
Allocator::Free(scheme_);
|
||||
scheme_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse a URI into constituent scheme, authority, path, query, & fragment parts
|
||||
// Supports URIs that match regex ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? as per
|
||||
// https://tools.ietf.org/html/rfc3986
|
||||
void Parse(const Ch* uri, std::size_t len) {
|
||||
std::size_t start = 0, pos1 = 0, pos2 = 0;
|
||||
Allocate(len);
|
||||
|
||||
// Look for scheme ([^:/?#]+):)?
|
||||
if (start < len) {
|
||||
while (pos1 < len) {
|
||||
if (uri[pos1] == ':') break;
|
||||
pos1++;
|
||||
}
|
||||
if (pos1 != len) {
|
||||
while (pos2 < len) {
|
||||
if (uri[pos2] == '/') break;
|
||||
if (uri[pos2] == '?') break;
|
||||
if (uri[pos2] == '#') break;
|
||||
pos2++;
|
||||
}
|
||||
if (pos1 < pos2) {
|
||||
pos1++;
|
||||
std::memcpy(scheme_, &uri[start], pos1 * sizeof(Ch));
|
||||
scheme_[pos1] = '\0';
|
||||
start = pos1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look for auth (//([^/?#]*))?
|
||||
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
|
||||
auth_ = scheme_ + GetSchemeStringLength();
|
||||
auth_++;
|
||||
*auth_ = '\0';
|
||||
if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') {
|
||||
pos2 = start + 2;
|
||||
while (pos2 < len) {
|
||||
if (uri[pos2] == '/') break;
|
||||
if (uri[pos2] == '?') break;
|
||||
if (uri[pos2] == '#') break;
|
||||
pos2++;
|
||||
}
|
||||
std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch));
|
||||
auth_[pos2 - start] = '\0';
|
||||
start = pos2;
|
||||
}
|
||||
// Look for path ([^?#]*)
|
||||
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
|
||||
path_ = auth_ + GetAuthStringLength();
|
||||
path_++;
|
||||
*path_ = '\0';
|
||||
if (start < len) {
|
||||
pos2 = start;
|
||||
while (pos2 < len) {
|
||||
if (uri[pos2] == '?') break;
|
||||
if (uri[pos2] == '#') break;
|
||||
pos2++;
|
||||
}
|
||||
if (start != pos2) {
|
||||
std::memcpy(path_, &uri[start], (pos2 - start) * sizeof(Ch));
|
||||
path_[pos2 - start] = '\0';
|
||||
if (path_[0] == '/')
|
||||
RemoveDotSegments(); // absolute path - normalize
|
||||
start = pos2;
|
||||
}
|
||||
}
|
||||
// Look for query (\?([^#]*))?
|
||||
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
|
||||
query_ = path_ + GetPathStringLength();
|
||||
query_++;
|
||||
*query_ = '\0';
|
||||
if (start < len && uri[start] == '?') {
|
||||
pos2 = start + 1;
|
||||
while (pos2 < len) {
|
||||
if (uri[pos2] == '#') break;
|
||||
pos2++;
|
||||
}
|
||||
if (start != pos2) {
|
||||
std::memcpy(query_, &uri[start], (pos2 - start) * sizeof(Ch));
|
||||
query_[pos2 - start] = '\0';
|
||||
start = pos2;
|
||||
}
|
||||
}
|
||||
// Look for fragment (#(.*))?
|
||||
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
|
||||
frag_ = query_ + GetQueryStringLength();
|
||||
frag_++;
|
||||
*frag_ = '\0';
|
||||
if (start < len && uri[start] == '#') {
|
||||
std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch));
|
||||
frag_[len - start] = '\0';
|
||||
}
|
||||
|
||||
// Re-constitute base_ and uri_
|
||||
base_ = frag_ + GetFragStringLength() + 1;
|
||||
SetBase();
|
||||
uri_ = base_ + GetBaseStringLength() + 1;
|
||||
SetUri();
|
||||
}
|
||||
|
||||
// Reconstitute base
|
||||
void SetBase() {
|
||||
Ch* next = base_;
|
||||
std::memcpy(next, scheme_, GetSchemeStringLength() * sizeof(Ch));
|
||||
next+= GetSchemeStringLength();
|
||||
std::memcpy(next, auth_, GetAuthStringLength() * sizeof(Ch));
|
||||
next+= GetAuthStringLength();
|
||||
std::memcpy(next, path_, GetPathStringLength() * sizeof(Ch));
|
||||
next+= GetPathStringLength();
|
||||
std::memcpy(next, query_, GetQueryStringLength() * sizeof(Ch));
|
||||
next+= GetQueryStringLength();
|
||||
*next = '\0';
|
||||
}
|
||||
|
||||
// Reconstitute uri
|
||||
void SetUri() {
|
||||
Ch* next = uri_;
|
||||
std::memcpy(next, base_, GetBaseStringLength() * sizeof(Ch));
|
||||
next+= GetBaseStringLength();
|
||||
std::memcpy(next, frag_, GetFragStringLength() * sizeof(Ch));
|
||||
next+= GetFragStringLength();
|
||||
*next = '\0';
|
||||
}
|
||||
|
||||
// Copy a part from one GenericUri to another
|
||||
// Return the pointer to the next part to be copied to
|
||||
Ch* CopyPart(Ch* to, Ch* from, std::size_t len) {
|
||||
RAPIDJSON_ASSERT(to != 0);
|
||||
RAPIDJSON_ASSERT(from != 0);
|
||||
std::memcpy(to, from, len * sizeof(Ch));
|
||||
to[len] = '\0';
|
||||
Ch* next = to + len + 1;
|
||||
return next;
|
||||
}
|
||||
|
||||
// Remove . and .. segments from the path_ member.
|
||||
// https://tools.ietf.org/html/rfc3986
|
||||
// This is done in place as we are only removing segments.
|
||||
void RemoveDotSegments() {
|
||||
std::size_t pathlen = GetPathStringLength();
|
||||
std::size_t pathpos = 0; // Position in path_
|
||||
std::size_t newpos = 0; // Position in new path_
|
||||
|
||||
// Loop through each segment in original path_
|
||||
while (pathpos < pathlen) {
|
||||
// Get next segment, bounded by '/' or end
|
||||
size_t slashpos = 0;
|
||||
while ((pathpos + slashpos) < pathlen) {
|
||||
if (path_[pathpos + slashpos] == '/') break;
|
||||
slashpos++;
|
||||
}
|
||||
// Check for .. and . segments
|
||||
if (slashpos == 2 && path_[pathpos] == '.' && path_[pathpos + 1] == '.') {
|
||||
// Backup a .. segment in the new path_
|
||||
// We expect to find a previously added slash at the end or nothing
|
||||
RAPIDJSON_ASSERT(newpos == 0 || path_[newpos - 1] == '/');
|
||||
size_t lastslashpos = newpos;
|
||||
// Make sure we don't go beyond the start segment
|
||||
if (lastslashpos > 1) {
|
||||
// Find the next to last slash and back up to it
|
||||
lastslashpos--;
|
||||
while (lastslashpos > 0) {
|
||||
if (path_[lastslashpos - 1] == '/') break;
|
||||
lastslashpos--;
|
||||
}
|
||||
// Set the new path_ position
|
||||
newpos = lastslashpos;
|
||||
}
|
||||
} else if (slashpos == 1 && path_[pathpos] == '.') {
|
||||
// Discard . segment, leaves new path_ unchanged
|
||||
} else {
|
||||
// Move any other kind of segment to the new path_
|
||||
RAPIDJSON_ASSERT(newpos <= pathpos);
|
||||
std::memmove(&path_[newpos], &path_[pathpos], slashpos * sizeof(Ch));
|
||||
newpos += slashpos;
|
||||
// Add slash if not at end
|
||||
if ((pathpos + slashpos) < pathlen) {
|
||||
path_[newpos] = '/';
|
||||
newpos++;
|
||||
}
|
||||
}
|
||||
// Move to next segment
|
||||
pathpos += slashpos + 1;
|
||||
}
|
||||
path_[newpos] = '\0';
|
||||
}
|
||||
|
||||
Ch* uri_; // Everything
|
||||
Ch* base_; // Everything except fragment
|
||||
Ch* scheme_; // Includes the :
|
||||
Ch* auth_; // Includes the //
|
||||
Ch* path_; // Absolute if starts with /
|
||||
Ch* query_; // Includes the ?
|
||||
Ch* frag_; // Includes the #
|
||||
|
||||
Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
|
||||
Allocator* ownAllocator_; //!< Allocator owned by this Uri.
|
||||
};
|
||||
|
||||
//! GenericUri for Value (UTF-8, default allocator).
|
||||
typedef GenericUri<Value> Uri;
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_URI_H_
|
|
@ -67,6 +67,7 @@ enum WriteFlag {
|
|||
kWriteNoFlags = 0, //!< No flags are set.
|
||||
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
||||
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
|
||||
kWriteNanAndInfNullFlag = 4, //!< Allow writing of Infinity, -Infinity and NaN as null.
|
||||
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||
};
|
||||
|
||||
|
@ -348,8 +349,13 @@ protected:
|
|||
|
||||
bool WriteDouble(double d) {
|
||||
if (internal::Double(d).IsNanOrInf()) {
|
||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
||||
if (!(writeFlags & kWriteNanAndInfFlag) && !(writeFlags & kWriteNanAndInfNullFlag))
|
||||
return false;
|
||||
if (writeFlags & kWriteNanAndInfNullFlag) {
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
|
@ -548,6 +554,11 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
|||
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
|
||||
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
|
||||
return false;
|
||||
if (kWriteDefaultFlags & kWriteNanAndInfNullFlag) {
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Tencent is pleased to support the open source community by making RapidJSON available.
|
||||
|
||||
Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
||||
|
||||
* [RapidJSON GitHub](https://github.com/Tencent/rapidjson/)
|
||||
* RapidJSON Documentation
|
||||
|
@ -43,7 +43,7 @@ RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](
|
|||
|
||||
More features can be read [here](doc/features.md).
|
||||
|
||||
JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in fully compliance with RFC7159/ECMA-404, with optional support of relaxed syntax. More information about JSON can be obtained at
|
||||
JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in full compliance with RFC7159/ECMA-404, with optional support of relaxed syntax. More information about JSON can be obtained at
|
||||
* [Introducing JSON](http://json.org/)
|
||||
* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)
|
||||
* [Standard ECMA-404: The JSON Data Interchange Format](https://www.ecma-international.org/publications/standards/Ecma-404.htm)
|
||||
|
@ -72,6 +72,9 @@ Users can build and run the unit tests on their platform/compiler.
|
|||
|
||||
RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path.
|
||||
|
||||
Alternatively, if you are using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager you can download and install rapidjson with CMake integration in a single command:
|
||||
* vcpkg install rapidjson
|
||||
|
||||
RapidJSON uses following software as its dependencies:
|
||||
* [CMake](https://cmake.org/) as a general build tool
|
||||
* (optional) [Doxygen](http://www.doxygen.org) to build documentation
|
||||
|
@ -158,3 +161,50 @@ More [examples](https://github.com/Tencent/rapidjson/tree/master/example) are av
|
|||
* [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
|
||||
* [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
|
||||
* [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
|
||||
|
||||
## Contributing
|
||||
|
||||
RapidJSON welcomes contributions. When contributing, please follow the code below.
|
||||
|
||||
### Issues
|
||||
|
||||
Feel free to submit issues and enhancement requests.
|
||||
|
||||
Please help us by providing **minimal reproducible examples**, because source code is easier to let other people understand what happens.
|
||||
For crash problems on certain platforms, please bring stack dump content with the detail of the OS, compiler, etc.
|
||||
|
||||
Please try breakpoint debugging first, tell us what you found, see if we can start exploring based on more information been prepared.
|
||||
|
||||
### Workflow
|
||||
|
||||
In general, we follow the "fork-and-pull" Git workflow.
|
||||
|
||||
1. **Fork** the repo on GitHub
|
||||
2. **Clone** the project to your own machine
|
||||
3. **Checkout** a new branch on your fork, start developing on the branch
|
||||
4. **Test** the change before commit, Make sure the changes pass all the tests, including `unittest` and `preftest`, please add test case for each new feature or bug-fix if needed.
|
||||
5. **Commit** changes to your own branch
|
||||
6. **Push** your work back up to your fork
|
||||
7. Submit a **Pull request** so that we can review your changes
|
||||
|
||||
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
|
||||
|
||||
### Copyright and Licensing
|
||||
|
||||
You can copy and paste the license summary from below.
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
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.
|
||||
```
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
|
||||
{
|
||||
static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
|
@ -46,8 +45,7 @@ static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
|
|||
/***********************************************************************
|
||||
* Update the encryption keys with the next byte of plain text
|
||||
*/
|
||||
static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
|
||||
{
|
||||
static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) {
|
||||
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
|
||||
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
|
||||
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
|
||||
|
@ -63,8 +61,7 @@ static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
|
|||
* Initialize the encryption keys and the random header according to
|
||||
* the given password.
|
||||
*/
|
||||
static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
|
||||
{
|
||||
static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
|
||||
*(pkeys+0) = 305419896L;
|
||||
*(pkeys+1) = 591751049L;
|
||||
*(pkeys+2) = 878082192L;
|
||||
|
@ -93,8 +90,7 @@ static unsigned crypthead(const char* passwd, /* password string */
|
|||
int bufSize,
|
||||
unsigned long* pkeys,
|
||||
const z_crc_t* pcrc_32_tab,
|
||||
unsigned long crcForCrypting)
|
||||
{
|
||||
unsigned long crcForCrypting) {
|
||||
unsigned n; /* index in random header */
|
||||
int t; /* temporary */
|
||||
int c; /* random byte */
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(IOAPI_NO_64)
|
||||
#if defined(__APPLE__) || defined(IOAPI_NO_64) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64)
|
||||
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
|
||||
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
|
||||
#define FTELLO_FUNC(stream) ftello(stream)
|
||||
|
@ -28,8 +28,7 @@
|
|||
|
||||
#include "ioapi.h"
|
||||
|
||||
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
|
||||
{
|
||||
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void*filename, int mode) {
|
||||
if (pfilefunc->zfile_func64.zopen64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
|
||||
else
|
||||
|
@ -38,8 +37,7 @@ voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename
|
|||
}
|
||||
}
|
||||
|
||||
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) {
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
|
||||
else
|
||||
|
@ -52,8 +50,7 @@ long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZP
|
|||
}
|
||||
}
|
||||
|
||||
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
|
||||
{
|
||||
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream) {
|
||||
if (pfilefunc->zfile_func64.zseek64_file != NULL)
|
||||
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
|
||||
else
|
||||
|
@ -66,11 +63,9 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream
|
|||
}
|
||||
}
|
||||
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
|
||||
{
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32) {
|
||||
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
|
||||
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
|
||||
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
|
||||
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
|
||||
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
|
||||
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
|
||||
|
@ -84,16 +79,7 @@ void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filef
|
|||
|
||||
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
|
||||
static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
|
||||
static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
|
||||
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
|
||||
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
|
||||
|
||||
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
|
||||
{
|
||||
static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) {
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
(void)opaque;
|
||||
|
@ -111,8 +97,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in
|
|||
return file;
|
||||
}
|
||||
|
||||
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
|
||||
{
|
||||
static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) {
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
(void)opaque;
|
||||
|
@ -131,24 +116,21 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
|
|||
}
|
||||
|
||||
|
||||
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
|
||||
{
|
||||
static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) {
|
||||
uLong ret;
|
||||
(void)opaque;
|
||||
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
|
||||
{
|
||||
static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) {
|
||||
uLong ret;
|
||||
(void)opaque;
|
||||
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) {
|
||||
long ret;
|
||||
(void)opaque;
|
||||
ret = ftell((FILE *)stream);
|
||||
|
@ -156,16 +138,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
|
|||
}
|
||||
|
||||
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) {
|
||||
ZPOS64_T ret;
|
||||
(void)opaque;
|
||||
ret = (ZPOS64_T)FTELLO_FUNC((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
|
||||
{
|
||||
static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) {
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
(void)opaque;
|
||||
|
@ -188,8 +168,7 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs
|
|||
return ret;
|
||||
}
|
||||
|
||||
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
||||
{
|
||||
static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) {
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
(void)opaque;
|
||||
|
@ -208,31 +187,28 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
|
|||
}
|
||||
ret = 0;
|
||||
|
||||
if(FSEEKO_FUNC((FILE *)stream, (z_off_t)offset, fseek_origin) != 0)
|
||||
if(FSEEKO_FUNC((FILE *)stream, (z_off64_t)offset, fseek_origin) != 0)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) {
|
||||
int ret;
|
||||
(void)opaque;
|
||||
ret = fclose((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
|
||||
{
|
||||
static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) {
|
||||
int ret;
|
||||
(void)opaque;
|
||||
ret = ferror((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
|
||||
{
|
||||
void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def) {
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
|
@ -243,8 +219,7 @@ void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
|
|||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
||||
|
||||
void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def) {
|
||||
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#define ftello64 ftell
|
||||
#define fseeko64 fseek
|
||||
#else
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64)
|
||||
#define fopen64 fopen
|
||||
#define ftello64 ftello
|
||||
#define fseeko64 fseeko
|
||||
|
@ -82,7 +82,7 @@
|
|||
#include "mz64conf.h"
|
||||
#endif
|
||||
|
||||
/* a type choosen by DEFINE */
|
||||
/* a type chosen by DEFINE */
|
||||
#ifdef HAVE_64BIT_INT_CUSTOM
|
||||
typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
|
||||
#else
|
||||
|
@ -134,17 +134,17 @@ extern "C" {
|
|||
|
||||
|
||||
|
||||
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode);
|
||||
typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size);
|
||||
typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size);
|
||||
typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream);
|
||||
typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream);
|
||||
|
||||
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream);
|
||||
typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin);
|
||||
|
||||
|
||||
/* here is the "old" 32 bits structure structure */
|
||||
/* here is the "old" 32 bits structure */
|
||||
typedef struct zlib_filefunc_def_s
|
||||
{
|
||||
open_file_func zopen_file;
|
||||
|
@ -157,9 +157,9 @@ typedef struct zlib_filefunc_def_s
|
|||
voidpf opaque;
|
||||
} zlib_filefunc_def;
|
||||
|
||||
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
|
||||
typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
|
||||
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream);
|
||||
typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
|
||||
typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void* filename, int mode);
|
||||
|
||||
typedef struct zlib_filefunc64_def_s
|
||||
{
|
||||
|
@ -173,8 +173,8 @@ typedef struct zlib_filefunc64_def_s
|
|||
voidpf opaque;
|
||||
} zlib_filefunc64_def;
|
||||
|
||||
void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def);
|
||||
void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def);
|
||||
|
||||
/* now internal definition, only for zip.c and unzip.h */
|
||||
typedef struct zlib_filefunc64_32_def_s
|
||||
|
@ -193,11 +193,11 @@ typedef struct zlib_filefunc64_32_def_s
|
|||
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
|
||||
|
||||
voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
|
||||
long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
|
||||
ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
|
||||
voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode);
|
||||
long call_zseek64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin);
|
||||
ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream);
|
||||
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
|
||||
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
|
||||
|
||||
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
|
||||
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
|
||||
|
|
|
@ -49,12 +49,12 @@
|
|||
Copyright (C) 2007-2008 Even Rouault
|
||||
|
||||
|
||||
Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
|
||||
Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
|
||||
Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
|
||||
should only read the compressed/uncompressed size from the Zip64 format if
|
||||
the size from normal header was 0xFFFFFFFF
|
||||
Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
|
||||
Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
|
||||
Oct-2009 - Mathias Svensson - Applied some bug fixes from patches received from Gilles Vollant
|
||||
Oct-2009 - Mathias Svensson - Applied support to unzip files with compression method BZIP2 (bzip2 lib is required)
|
||||
Patch created by Daniel Borca
|
||||
|
||||
Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
|
||||
|
@ -77,8 +77,6 @@
|
|||
|
||||
#ifdef STDC
|
||||
# include <stddef.h>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_ERRNO_H
|
||||
extern int errno;
|
||||
|
@ -111,9 +109,6 @@
|
|||
#ifndef ALLOC
|
||||
# define ALLOC(size) (malloc(size))
|
||||
#endif
|
||||
#ifndef TRYFREE
|
||||
# define TRYFREE(p) { free(p);}
|
||||
#endif
|
||||
|
||||
#define SIZECENTRALDIRITEM (0x2e)
|
||||
#define SIZEZIPLOCALHEADER (0x1e)
|
||||
|
@ -122,7 +117,7 @@
|
|||
const char unz_copyright[] =
|
||||
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
||||
|
||||
/* unz_file_info_interntal contain internal info about a file in zipfile*/
|
||||
/* unz_file_info64_internal contain internal info about a file in zipfile*/
|
||||
typedef struct unz_file_info64_internal_s
|
||||
{
|
||||
ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
|
||||
|
@ -153,7 +148,7 @@ typedef struct
|
|||
ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
|
||||
ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
|
||||
zlib_filefunc64_32_def z_filefunc;
|
||||
voidpf filestream; /* io structore of the zipfile */
|
||||
voidpf filestream; /* io structure of the zipfile */
|
||||
uLong compression_method; /* compression method (0==store) */
|
||||
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
|
||||
int raw;
|
||||
|
@ -166,7 +161,7 @@ typedef struct
|
|||
{
|
||||
zlib_filefunc64_32_def z_filefunc;
|
||||
int is64bitOpenFunction;
|
||||
voidpf filestream; /* io structore of the zipfile */
|
||||
voidpf filestream; /* io structure of the zipfile */
|
||||
unz_global_info64 gi; /* public global information */
|
||||
ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
|
||||
ZPOS64_T num_file; /* number of the current file in the zipfile*/
|
||||
|
@ -197,29 +192,44 @@ typedef struct
|
|||
#include "crypt.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
|
||||
for end of file.
|
||||
IN assertion: the stream s has been successfully opened for reading.
|
||||
Reads a long in LSB order from the given gz_stream. Sets
|
||||
*/
|
||||
|
||||
|
||||
local int unz64local_getByte OF((
|
||||
const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
int *pi));
|
||||
|
||||
local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
|
||||
{
|
||||
unsigned char c;
|
||||
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
|
||||
if (err==1)
|
||||
local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX) {
|
||||
unsigned char c[2];
|
||||
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,2);
|
||||
if (err==2)
|
||||
{
|
||||
*pi = (int)c;
|
||||
*pX = c[0] | ((uLong)c[1] << 8);
|
||||
return UNZ_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pX = 0;
|
||||
if (ZERROR64(*pzlib_filefunc_def,filestream))
|
||||
return UNZ_ERRNO;
|
||||
else
|
||||
return UNZ_EOF;
|
||||
}
|
||||
}
|
||||
|
||||
local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX) {
|
||||
unsigned char c[4];
|
||||
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,4);
|
||||
if (err==4)
|
||||
{
|
||||
*pX = c[0] | ((uLong)c[1] << 8) | ((uLong)c[2] << 16) | ((uLong)c[3] << 24);
|
||||
return UNZ_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pX = 0;
|
||||
if (ZERROR64(*pzlib_filefunc_def,filestream))
|
||||
return UNZ_ERRNO;
|
||||
else
|
||||
|
@ -228,126 +238,29 @@ local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, v
|
|||
}
|
||||
|
||||
|
||||
/* ===========================================================================
|
||||
Reads a long in LSB order from the given gz_stream. Sets
|
||||
*/
|
||||
local int unz64local_getShort OF((
|
||||
const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX));
|
||||
|
||||
local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX)
|
||||
{
|
||||
uLong x ;
|
||||
int i = 0;
|
||||
int err;
|
||||
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x = (uLong)i;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((uLong)i)<<8;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
*pX = x;
|
||||
local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
ZPOS64_T *pX) {
|
||||
unsigned char c[8];
|
||||
int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,c,8);
|
||||
if (err==8)
|
||||
{
|
||||
*pX = c[0] | ((ZPOS64_T)c[1] << 8) | ((ZPOS64_T)c[2] << 16) | ((ZPOS64_T)c[3] << 24)
|
||||
| ((ZPOS64_T)c[4] << 32) | ((ZPOS64_T)c[5] << 40) | ((ZPOS64_T)c[6] << 48) | ((ZPOS64_T)c[7] << 56);
|
||||
return UNZ_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pX = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
local int unz64local_getLong OF((
|
||||
const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX));
|
||||
|
||||
local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
uLong *pX)
|
||||
{
|
||||
uLong x ;
|
||||
int i = 0;
|
||||
int err;
|
||||
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x = (uLong)i;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((uLong)i)<<8;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((uLong)i)<<16;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x += ((uLong)i)<<24;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
*pX = x;
|
||||
else
|
||||
*pX = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
local int unz64local_getLong64 OF((
|
||||
const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
ZPOS64_T *pX));
|
||||
|
||||
|
||||
local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream,
|
||||
ZPOS64_T *pX)
|
||||
{
|
||||
ZPOS64_T x ;
|
||||
int i = 0;
|
||||
int err;
|
||||
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x = (ZPOS64_T)i;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<8;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<16;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<24;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<32;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<40;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<48;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
|
||||
x |= ((ZPOS64_T)i)<<56;
|
||||
|
||||
if (err==UNZ_OK)
|
||||
*pX = x;
|
||||
else
|
||||
*pX = 0;
|
||||
return err;
|
||||
if (ZERROR64(*pzlib_filefunc_def,filestream))
|
||||
return UNZ_ERRNO;
|
||||
else
|
||||
return UNZ_EOF;
|
||||
}
|
||||
}
|
||||
|
||||
/* My own strcmpi / strcasecmp */
|
||||
local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
|
||||
{
|
||||
local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) {
|
||||
for (;;)
|
||||
{
|
||||
char c1=*(fileName1++);
|
||||
|
@ -379,19 +292,17 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil
|
|||
#endif
|
||||
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
Compare two filenames (fileName1,fileName2).
|
||||
If iCaseSensitivity = 1, comparison is case sensitive (like strcmp)
|
||||
If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
If iCaseSensitivity = 0, case sensitivity is default of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
|
||||
*/
|
||||
extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity)
|
||||
|
||||
{
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity) {
|
||||
if (iCaseSensitivity==0)
|
||||
iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
|
||||
|
||||
|
@ -405,21 +316,23 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
|
|||
#define BUFREADCOMMENT (0x400)
|
||||
#endif
|
||||
|
||||
#ifndef CENTRALDIRINVALID
|
||||
#define CENTRALDIRINVALID ((ZPOS64_T)(-1))
|
||||
#endif
|
||||
|
||||
/*
|
||||
Locate the Central directory of a zipfile (at the end, just before
|
||||
the global comment)
|
||||
*/
|
||||
local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
|
||||
local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
|
||||
{
|
||||
local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) {
|
||||
unsigned char* buf;
|
||||
ZPOS64_T uSizeFile;
|
||||
ZPOS64_T uBackRead;
|
||||
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
|
||||
ZPOS64_T uPosFound=0;
|
||||
ZPOS64_T uPosFound=CENTRALDIRINVALID;
|
||||
|
||||
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
|
||||
uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
|
||||
|
@ -429,7 +342,7 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
|
|||
|
||||
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
|
||||
if (buf==NULL)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
uBackRead = 4;
|
||||
while (uBackRead<uMaxBack)
|
||||
|
@ -459,10 +372,10 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
|
|||
break;
|
||||
}
|
||||
|
||||
if (uPosFound!=0)
|
||||
if (uPosFound!=CENTRALDIRINVALID)
|
||||
break;
|
||||
}
|
||||
TRYFREE(buf);
|
||||
free(buf);
|
||||
return uPosFound;
|
||||
}
|
||||
|
||||
|
@ -471,23 +384,18 @@ local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_f
|
|||
Locate the Central directory 64 of a zipfile (at the end, just before
|
||||
the global comment)
|
||||
*/
|
||||
local ZPOS64_T unz64local_SearchCentralDir64 OF((
|
||||
const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream));
|
||||
|
||||
local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
|
||||
voidpf filestream)
|
||||
{
|
||||
voidpf filestream) {
|
||||
unsigned char* buf;
|
||||
ZPOS64_T uSizeFile;
|
||||
ZPOS64_T uBackRead;
|
||||
ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
|
||||
ZPOS64_T uPosFound=0;
|
||||
ZPOS64_T uPosFound=CENTRALDIRINVALID;
|
||||
uLong uL;
|
||||
ZPOS64_T relativeOffset;
|
||||
|
||||
if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
|
||||
uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
|
||||
|
@ -497,7 +405,7 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
|
|||
|
||||
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
|
||||
if (buf==NULL)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
uBackRead = 4;
|
||||
while (uBackRead<uMaxBack)
|
||||
|
@ -527,47 +435,47 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
|
|||
break;
|
||||
}
|
||||
|
||||
if (uPosFound!=0)
|
||||
if (uPosFound!=CENTRALDIRINVALID)
|
||||
break;
|
||||
}
|
||||
TRYFREE(buf);
|
||||
if (uPosFound == 0)
|
||||
return 0;
|
||||
free(buf);
|
||||
if (uPosFound == CENTRALDIRINVALID)
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* Zip64 end of central directory locator */
|
||||
if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* the signature, already checked */
|
||||
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* number of the disk with the start of the zip64 end of central directory */
|
||||
/* number of the disk with the start of the zip64 end of central directory */
|
||||
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
if (uL != 0)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* relative offset of the zip64 end of central directory record */
|
||||
if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* total number of disks */
|
||||
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
if (uL != 1)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* Goto end of central directory record */
|
||||
if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
/* the signature */
|
||||
if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
if (uL != 0x06064b50)
|
||||
return 0;
|
||||
return CENTRALDIRINVALID;
|
||||
|
||||
return relativeOffset;
|
||||
}
|
||||
|
@ -581,19 +489,18 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
|
|||
Else, the return value is a unzFile Handle, usable with other function
|
||||
of this unzip package.
|
||||
*/
|
||||
local unzFile unzOpenInternal (const void *path,
|
||||
zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
|
||||
int is64bitOpenFunction)
|
||||
{
|
||||
local unzFile unzOpenInternal(const void *path,
|
||||
zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
|
||||
int is64bitOpenFunction) {
|
||||
unz64_s us;
|
||||
unz64_s *s;
|
||||
ZPOS64_T central_pos;
|
||||
uLong uL;
|
||||
|
||||
uLong number_disk; /* number of the current dist, used for
|
||||
spaning ZIP, unsupported, always 0*/
|
||||
uLong number_disk_with_CD; /* number the the disk with central dir, used
|
||||
for spaning ZIP, unsupported, always 0*/
|
||||
uLong number_disk; /* number of the current disk, used for
|
||||
spanning ZIP, unsupported, always 0*/
|
||||
uLong number_disk_with_CD; /* number the disk with central dir, used
|
||||
for spanning ZIP, unsupported, always 0*/
|
||||
ZPOS64_T number_entry_CD; /* total number of entries in
|
||||
the central dir
|
||||
(same than number_entry on nospan) */
|
||||
|
@ -621,7 +528,7 @@ local unzFile unzOpenInternal (const void *path,
|
|||
return NULL;
|
||||
|
||||
central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
|
||||
if (central_pos)
|
||||
if (central_pos!=CENTRALDIRINVALID)
|
||||
{
|
||||
uLong uS;
|
||||
ZPOS64_T uL64;
|
||||
|
@ -683,7 +590,7 @@ local unzFile unzOpenInternal (const void *path,
|
|||
else
|
||||
{
|
||||
central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
|
||||
if (central_pos==0)
|
||||
if (central_pos==CENTRALDIRINVALID)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
us.isZip64 = 0;
|
||||
|
@ -762,9 +669,8 @@ local unzFile unzOpenInternal (const void *path,
|
|||
}
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen2 (const char *path,
|
||||
zlib_filefunc_def* pzlib_filefunc32_def)
|
||||
{
|
||||
extern unzFile ZEXPORT unzOpen2(const char *path,
|
||||
zlib_filefunc_def* pzlib_filefunc32_def) {
|
||||
if (pzlib_filefunc32_def != NULL)
|
||||
{
|
||||
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
|
||||
|
@ -775,9 +681,8 @@ extern unzFile ZEXPORT unzOpen2 (const char *path,
|
|||
return unzOpenInternal(path, NULL, 0);
|
||||
}
|
||||
|
||||
extern unzFile ZEXPORT unzOpen2_64 (const void *path,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def)
|
||||
{
|
||||
extern unzFile ZEXPORT unzOpen2_64(const void *path,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def) {
|
||||
if (pzlib_filefunc_def != NULL)
|
||||
{
|
||||
zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
|
||||
|
@ -790,13 +695,11 @@ extern unzFile ZEXPORT unzOpen2_64 (const void *path,
|
|||
return unzOpenInternal(path, NULL, 1);
|
||||
}
|
||||
|
||||
extern unzFile ZEXPORT unzOpen (const char *path)
|
||||
{
|
||||
extern unzFile ZEXPORT unzOpen(const char *path) {
|
||||
return unzOpenInternal(path, NULL, 0);
|
||||
}
|
||||
|
||||
extern unzFile ZEXPORT unzOpen64 (const void *path)
|
||||
{
|
||||
extern unzFile ZEXPORT unzOpen64(const void *path) {
|
||||
return unzOpenInternal(path, NULL, 1);
|
||||
}
|
||||
|
||||
|
@ -805,8 +708,7 @@ extern unzFile ZEXPORT unzOpen64 (const void *path)
|
|||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzCloseCurrentFile before call unzClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
extern int ZEXPORT unzClose (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzClose(unzFile file) {
|
||||
unz64_s* s;
|
||||
if (file==NULL)
|
||||
return UNZ_PARAMERROR;
|
||||
|
@ -816,7 +718,7 @@ extern int ZEXPORT unzClose (unzFile file)
|
|||
unzCloseCurrentFile(file);
|
||||
|
||||
ZCLOSE64(s->z_filefunc, s->filestream);
|
||||
TRYFREE(s);
|
||||
free(s);
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
|
@ -825,8 +727,7 @@ extern int ZEXPORT unzClose (unzFile file)
|
|||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
|
||||
{
|
||||
extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) {
|
||||
unz64_s* s;
|
||||
if (file==NULL)
|
||||
return UNZ_PARAMERROR;
|
||||
|
@ -835,8 +736,7 @@ extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_
|
|||
return UNZ_OK;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
|
||||
{
|
||||
extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) {
|
||||
unz64_s* s;
|
||||
if (file==NULL)
|
||||
return UNZ_PARAMERROR;
|
||||
|
@ -847,10 +747,9 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info
|
|||
return UNZ_OK;
|
||||
}
|
||||
/*
|
||||
Translate date/time from Dos format to tm_unz (readable more easilty)
|
||||
Translate date/time from Dos format to tm_unz (readable more easily)
|
||||
*/
|
||||
local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
|
||||
{
|
||||
local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) {
|
||||
ZPOS64_T uDate;
|
||||
uDate = (ZPOS64_T)(ulDosDate>>16);
|
||||
ptm->tm_mday = (int)(uDate&0x1f) ;
|
||||
|
@ -865,28 +764,16 @@ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
|
|||
/*
|
||||
Get Info about the current file in the zipfile, with internal only info
|
||||
*/
|
||||
local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
|
||||
unz_file_info64 *pfile_info,
|
||||
unz_file_info64_internal
|
||||
*pfile_info_internal,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
|
||||
local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
unz_file_info64 *pfile_info,
|
||||
unz_file_info64_internal
|
||||
*pfile_info_internal,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize)
|
||||
{
|
||||
local int unz64local_GetCurrentFileInfoInternal(unzFile file,
|
||||
unz_file_info64 *pfile_info,
|
||||
unz_file_info64_internal
|
||||
*pfile_info_internal,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize) {
|
||||
unz64_s* s;
|
||||
unz_file_info64 file_info;
|
||||
unz_file_info64_internal file_info_internal;
|
||||
|
@ -1038,33 +925,31 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
|||
/* ZIP64 extra fields */
|
||||
if (headerId == 0x0001)
|
||||
{
|
||||
uLong uL1;
|
||||
if(file_info.uncompressed_size == MAXU32)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info.uncompressed_size == MAXU32)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info.compressed_size == MAXU32)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info.compressed_size == MAXU32)
|
||||
{
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info_internal.offset_curfile == MAXU32)
|
||||
{
|
||||
/* Relative Header offset */
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info_internal.offset_curfile == MAXU32)
|
||||
{
|
||||
/* Relative Header offset */
|
||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
if(file_info.disk_num_start == MAXU32)
|
||||
{
|
||||
/* Disk Start Number */
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL1) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if(file_info.disk_num_start == 0xffff)
|
||||
{
|
||||
/* Disk Start Number */
|
||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -1121,24 +1006,22 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
|||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem.
|
||||
*/
|
||||
extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
|
||||
unz_file_info64 * pfile_info,
|
||||
char * szFileName, uLong fileNameBufferSize,
|
||||
void *extraField, uLong extraFieldBufferSize,
|
||||
char* szComment, uLong commentBufferSize)
|
||||
{
|
||||
extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file,
|
||||
unz_file_info64 * pfile_info,
|
||||
char * szFileName, uLong fileNameBufferSize,
|
||||
void *extraField, uLong extraFieldBufferSize,
|
||||
char* szComment, uLong commentBufferSize) {
|
||||
return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
|
||||
szFileName,fileNameBufferSize,
|
||||
extraField,extraFieldBufferSize,
|
||||
szComment,commentBufferSize);
|
||||
szFileName,fileNameBufferSize,
|
||||
extraField,extraFieldBufferSize,
|
||||
szComment,commentBufferSize);
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
||||
unz_file_info * pfile_info,
|
||||
char * szFileName, uLong fileNameBufferSize,
|
||||
void *extraField, uLong extraFieldBufferSize,
|
||||
char* szComment, uLong commentBufferSize)
|
||||
{
|
||||
extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
|
||||
unz_file_info * pfile_info,
|
||||
char * szFileName, uLong fileNameBufferSize,
|
||||
void *extraField, uLong extraFieldBufferSize,
|
||||
char* szComment, uLong commentBufferSize) {
|
||||
int err;
|
||||
unz_file_info64 file_info64;
|
||||
err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
|
||||
|
@ -1162,7 +1045,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
|||
pfile_info->internal_fa = file_info64.internal_fa;
|
||||
pfile_info->external_fa = file_info64.external_fa;
|
||||
|
||||
pfile_info->tmu_date = file_info64.tmu_date,
|
||||
pfile_info->tmu_date = file_info64.tmu_date;
|
||||
|
||||
|
||||
pfile_info->compressed_size = (uLong)file_info64.compressed_size;
|
||||
|
@ -1175,8 +1058,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
|||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
extern int ZEXPORT unzGoToFirstFile (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzGoToFirstFile(unzFile file) {
|
||||
int err=UNZ_OK;
|
||||
unz64_s* s;
|
||||
if (file==NULL)
|
||||
|
@ -1196,8 +1078,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file)
|
|||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
extern int ZEXPORT unzGoToNextFile (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzGoToNextFile(unzFile file) {
|
||||
unz64_s* s;
|
||||
int err;
|
||||
|
||||
|
@ -1229,8 +1110,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file)
|
|||
UNZ_OK if the file is found. It becomes the current file.
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
|
||||
{
|
||||
extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) {
|
||||
unz64_s* s;
|
||||
int err;
|
||||
|
||||
|
@ -1305,8 +1185,7 @@ typedef struct unz_file_pos_s
|
|||
} unz_file_pos;
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
|
||||
{
|
||||
extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) {
|
||||
unz64_s* s;
|
||||
|
||||
if (file==NULL || file_pos==NULL)
|
||||
|
@ -1321,10 +1200,7 @@ extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
|
|||
return UNZ_OK;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGetFilePos(
|
||||
unzFile file,
|
||||
unz_file_pos* file_pos)
|
||||
{
|
||||
extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos* file_pos) {
|
||||
unz64_file_pos file_pos64;
|
||||
int err = unzGetFilePos64(file,&file_pos64);
|
||||
if (err==UNZ_OK)
|
||||
|
@ -1335,8 +1211,7 @@ extern int ZEXPORT unzGetFilePos(
|
|||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
|
||||
{
|
||||
extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) {
|
||||
unz64_s* s;
|
||||
int err;
|
||||
|
||||
|
@ -1357,10 +1232,7 @@ extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos
|
|||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzGoToFilePos(
|
||||
unzFile file,
|
||||
unz_file_pos* file_pos)
|
||||
{
|
||||
extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos* file_pos) {
|
||||
unz64_file_pos file_pos64;
|
||||
if (file_pos == NULL)
|
||||
return UNZ_PARAMERROR;
|
||||
|
@ -1382,10 +1254,9 @@ extern int ZEXPORT unzGoToFilePos(
|
|||
store in *piSizeVar the size of extra info in local header
|
||||
(filename and size of extra field data)
|
||||
*/
|
||||
local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
|
||||
ZPOS64_T * poffset_local_extrafield,
|
||||
uInt * psize_local_extrafield)
|
||||
{
|
||||
local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar,
|
||||
ZPOS64_T * poffset_local_extrafield,
|
||||
uInt * psize_local_extrafield) {
|
||||
uLong uMagic,uData,uFlags;
|
||||
uLong size_filename;
|
||||
uLong size_extra_field;
|
||||
|
@ -1469,9 +1340,8 @@ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVa
|
|||
Open for reading data the current file in the zipfile.
|
||||
If there is no error and the file is opened, the return value is UNZ_OK.
|
||||
*/
|
||||
extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
||||
int* level, int raw, const char* password)
|
||||
{
|
||||
extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method,
|
||||
int* level, int raw, const char* password) {
|
||||
int err=UNZ_OK;
|
||||
uInt iSizeVar;
|
||||
unz64_s* s;
|
||||
|
@ -1509,7 +1379,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
|||
|
||||
if (pfile_in_zip_read_info->read_buffer==NULL)
|
||||
{
|
||||
TRYFREE(pfile_in_zip_read_info);
|
||||
free(pfile_in_zip_read_info);
|
||||
return UNZ_INTERNALERROR;
|
||||
}
|
||||
|
||||
|
@ -1566,8 +1436,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
|||
pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
|
||||
else
|
||||
{
|
||||
TRYFREE(pfile_in_zip_read_info->read_buffer);
|
||||
TRYFREE(pfile_in_zip_read_info);
|
||||
free(pfile_in_zip_read_info->read_buffer);
|
||||
free(pfile_in_zip_read_info);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
|
@ -1587,8 +1457,8 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
|||
pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
|
||||
else
|
||||
{
|
||||
TRYFREE(pfile_in_zip_read_info->read_buffer);
|
||||
TRYFREE(pfile_in_zip_read_info);
|
||||
free(pfile_in_zip_read_info->read_buffer);
|
||||
free(pfile_in_zip_read_info);
|
||||
return err;
|
||||
}
|
||||
/* windowBits is passed < 0 to tell that there is no zlib header.
|
||||
|
@ -1640,25 +1510,21 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
|
|||
return UNZ_OK;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzOpenCurrentFile(unzFile file) {
|
||||
return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
|
||||
{
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) {
|
||||
return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
|
||||
{
|
||||
extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) {
|
||||
return unzOpenCurrentFile3(file, method, level, raw, NULL);
|
||||
}
|
||||
|
||||
/** Addition for GDAL : START */
|
||||
|
||||
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
|
||||
{
|
||||
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) {
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
s=(unz64_s*)file;
|
||||
|
@ -1678,13 +1544,12 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
|
|||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return the number of byte copied if some bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
|
||||
{
|
||||
extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) {
|
||||
int err=UNZ_OK;
|
||||
uInt iRead = 0;
|
||||
unz64_s* s;
|
||||
|
@ -1891,8 +1756,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
|
|||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
extern z_off_t ZEXPORT unztell (unzFile file)
|
||||
{
|
||||
extern z_off_t ZEXPORT unztell(unzFile file) {
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
if (file==NULL)
|
||||
|
@ -1906,8 +1770,7 @@ extern z_off_t ZEXPORT unztell (unzFile file)
|
|||
return (z_off_t)pfile_in_zip_read_info->stream.total_out;
|
||||
}
|
||||
|
||||
extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
|
||||
{
|
||||
extern ZPOS64_T ZEXPORT unztell64(unzFile file) {
|
||||
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
|
@ -1926,8 +1789,7 @@ extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
|
|||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
extern int ZEXPORT unzeof (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzeof(unzFile file) {
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
if (file==NULL)
|
||||
|
@ -1958,8 +1820,7 @@ more info in the local-header version than in the central-header)
|
|||
the return value is the number of bytes copied in buf, or (if <0)
|
||||
the error code
|
||||
*/
|
||||
extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
|
||||
{
|
||||
extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) {
|
||||
unz64_s* s;
|
||||
file_in_zip64_read_info_s* pfile_in_zip_read_info;
|
||||
uInt read_now;
|
||||
|
@ -2006,8 +1867,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
|
|||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
||||
{
|
||||
extern int ZEXPORT unzCloseCurrentFile(unzFile file) {
|
||||
int err=UNZ_OK;
|
||||
|
||||
unz64_s* s;
|
||||
|
@ -2029,7 +1889,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
|||
}
|
||||
|
||||
|
||||
TRYFREE(pfile_in_zip_read_info->read_buffer);
|
||||
free(pfile_in_zip_read_info->read_buffer);
|
||||
pfile_in_zip_read_info->read_buffer = NULL;
|
||||
if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
|
||||
inflateEnd(&pfile_in_zip_read_info->stream);
|
||||
|
@ -2040,7 +1900,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
|||
|
||||
|
||||
pfile_in_zip_read_info->stream_initialised = 0;
|
||||
TRYFREE(pfile_in_zip_read_info);
|
||||
free(pfile_in_zip_read_info);
|
||||
|
||||
s->pfile_in_zip_read=NULL;
|
||||
|
||||
|
@ -2053,8 +1913,7 @@ extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
|||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0
|
||||
*/
|
||||
extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
|
||||
{
|
||||
extern int ZEXPORT unzGetGlobalComment(unzFile file, char * szComment, uLong uSizeBuf) {
|
||||
unz64_s* s;
|
||||
uLong uReadThis ;
|
||||
if (file==NULL)
|
||||
|
@ -2081,8 +1940,7 @@ extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uS
|
|||
}
|
||||
|
||||
/* Additions by RX '2004 */
|
||||
extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
|
||||
{
|
||||
extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) {
|
||||
unz64_s* s;
|
||||
|
||||
if (file==NULL)
|
||||
|
@ -2096,8 +1954,7 @@ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
|
|||
return s->pos_in_central_dir;
|
||||
}
|
||||
|
||||
extern uLong ZEXPORT unzGetOffset (unzFile file)
|
||||
{
|
||||
extern uLong ZEXPORT unzGetOffset(unzFile file) {
|
||||
ZPOS64_T offset64;
|
||||
|
||||
if (file==NULL)
|
||||
|
@ -2106,8 +1963,7 @@ extern uLong ZEXPORT unzGetOffset (unzFile file)
|
|||
return (uLong)offset64;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
|
||||
{
|
||||
extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) {
|
||||
unz64_s* s;
|
||||
int err;
|
||||
|
||||
|
@ -2124,7 +1980,6 @@ extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
|
|||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
|
||||
{
|
||||
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) {
|
||||
return unzSetOffset64(file,pos);
|
||||
}
|
||||
|
|
|
@ -150,21 +150,21 @@ typedef struct unz_file_info_s
|
|||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity));
|
||||
extern int ZEXPORT unzStringFileNameCompare(const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity);
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
Compare two filenames (fileName1,fileName2).
|
||||
If iCaseSensitivity = 1, comparison is case sensitive (like strcmp)
|
||||
If iCaseSensitivity = 2, comparison is not case sensitive (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
If iCaseSensitivity = 0, case sensitivity is default of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||
extern unzFile ZEXPORT unzOpen64 OF((const void *path));
|
||||
extern unzFile ZEXPORT unzOpen(const char *path);
|
||||
extern unzFile ZEXPORT unzOpen64(const void *path);
|
||||
/*
|
||||
Open a Zip file. path contain the full pathname (by example,
|
||||
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
|
||||
|
@ -181,41 +181,41 @@ extern unzFile ZEXPORT unzOpen64 OF((const void *path));
|
|||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen2 OF((const char *path,
|
||||
zlib_filefunc_def* pzlib_filefunc_def));
|
||||
extern unzFile ZEXPORT unzOpen2(const char *path,
|
||||
zlib_filefunc_def* pzlib_filefunc_def);
|
||||
/*
|
||||
Open a Zip file, like unzOpen, but provide a set of file low level API
|
||||
for read/write the zip file (see ioapi.h)
|
||||
*/
|
||||
|
||||
extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def));
|
||||
extern unzFile ZEXPORT unzOpen2_64(const void *path,
|
||||
zlib_filefunc64_def* pzlib_filefunc_def);
|
||||
/*
|
||||
Open a Zip file, like unz64Open, but provide a set of file low level API
|
||||
for read/write the zip file (see ioapi.h)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzClose OF((unzFile file));
|
||||
extern int ZEXPORT unzClose(unzFile file);
|
||||
/*
|
||||
Close a ZipFile opened with unzOpen.
|
||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzCloseCurrentFile before call unzClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||
unz_global_info *pglobal_info));
|
||||
extern int ZEXPORT unzGetGlobalInfo(unzFile file,
|
||||
unz_global_info *pglobal_info);
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
|
||||
unz_global_info64 *pglobal_info));
|
||||
extern int ZEXPORT unzGetGlobalInfo64(unzFile file,
|
||||
unz_global_info64 *pglobal_info);
|
||||
/*
|
||||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf));
|
||||
extern int ZEXPORT unzGetGlobalComment(unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf);
|
||||
/*
|
||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
|
@ -226,22 +226,22 @@ extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
|||
/***************************************************************************/
|
||||
/* Unzip package allow you browse the directory of the zipfile */
|
||||
|
||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||
extern int ZEXPORT unzGoToFirstFile(unzFile file);
|
||||
/*
|
||||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||
extern int ZEXPORT unzGoToNextFile(unzFile file);
|
||||
/*
|
||||
Set the current file of the zipfile to the next file.
|
||||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity));
|
||||
extern int ZEXPORT unzLocateFile(unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity);
|
||||
/*
|
||||
Try locate the file szFileName in the zipfile.
|
||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||
|
@ -285,28 +285,28 @@ extern int ZEXPORT unzGoToFilePos64(
|
|||
|
||||
/* ****************************************** */
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
|
||||
unz_file_info64 *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file,
|
||||
unz_file_info64 *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize);
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
extern int ZEXPORT unzGetCurrentFileInfo(unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize);
|
||||
/*
|
||||
Get Info about the current file
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain some info about
|
||||
the current file
|
||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||
if szFileName!=NULL, the filename string will be copied in szFileName
|
||||
(fileNameBufferSize is the size of the buffer)
|
||||
if extraField!=NULL, the extra field information will be copied in extraField
|
||||
(extraFieldBufferSize is the size of the buffer).
|
||||
|
@ -318,7 +318,7 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
|||
|
||||
/** Addition for GDAL : START */
|
||||
|
||||
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
|
||||
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file);
|
||||
|
||||
/** Addition for GDAL : END */
|
||||
|
||||
|
@ -328,24 +328,24 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
|
|||
from it, and close it (you can close it before reading all the file)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||
extern int ZEXPORT unzOpenCurrentFile(unzFile file);
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
|
||||
const char* password));
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file,
|
||||
const char* password);
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
password is a crypting password
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw));
|
||||
extern int ZEXPORT unzOpenCurrentFile2(unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw);
|
||||
/*
|
||||
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
|
||||
if raw==1
|
||||
|
@ -355,11 +355,11 @@ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
|
|||
but you CANNOT set method parameter as NULL
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw,
|
||||
const char* password));
|
||||
extern int ZEXPORT unzOpenCurrentFile3(unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw,
|
||||
const char* password);
|
||||
/*
|
||||
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
|
||||
if raw==1
|
||||
|
@ -370,41 +370,41 @@ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
|
|||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||
extern int ZEXPORT unzCloseCurrentFile(unzFile file);
|
||||
/*
|
||||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
extern int ZEXPORT unzReadCurrentFile(unzFile file,
|
||||
voidp buf,
|
||||
unsigned len);
|
||||
/*
|
||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return the number of byte copied if some bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
|
||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||
extern z_off_t ZEXPORT unztell(unzFile file);
|
||||
|
||||
extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
|
||||
extern ZPOS64_T ZEXPORT unztell64(unzFile file);
|
||||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzeof OF((unzFile file));
|
||||
extern int ZEXPORT unzeof(unzFile file);
|
||||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
extern int ZEXPORT unzGetLocalExtrafield(unzFile file,
|
||||
voidp buf,
|
||||
unsigned len);
|
||||
/*
|
||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||
This is the local-header version of the extra field (sometimes, there is
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
BaseImporter() AI_NO_EXCEPT;
|
||||
|
||||
/** Destructor, private as well */
|
||||
virtual ~BaseImporter();
|
||||
virtual ~BaseImporter() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -66,10 +65,10 @@ namespace Assimp {
|
|||
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
||||
// --------------------------------------------------------------------------------------
|
||||
class ByteSwap {
|
||||
ByteSwap() AI_NO_EXCEPT {}
|
||||
ByteSwap() AI_NO_EXCEPT = default;
|
||||
~ByteSwap() = default;
|
||||
|
||||
public:
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/** Swap two bytes of data
|
||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||
|
@ -89,8 +88,7 @@ public:
|
|||
// ----------------------------------------------------------------------
|
||||
/** Swap four bytes of data
|
||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||
static inline void Swap4(void* _szOut)
|
||||
{
|
||||
static inline void Swap4(void* _szOut) {
|
||||
ai_assert(_szOut);
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
|
|
|
@ -73,14 +73,14 @@ class ASSIMP_API IOStream
|
|||
{
|
||||
protected:
|
||||
/** Constructor protected, use IOSystem::Open() to create an instance. */
|
||||
IOStream() AI_NO_EXCEPT;
|
||||
IOStream() AI_NO_EXCEPT = default;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Destructor. Deleting the object closes the underlying file,
|
||||
* alternatively you may use IOSystem::Close() to release the file.
|
||||
*/
|
||||
virtual ~IOStream();
|
||||
virtual ~IOStream() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Read from the file
|
||||
|
@ -126,15 +126,6 @@ public:
|
|||
virtual void Flush() = 0;
|
||||
}; //! class IOStream
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
IOStream::IOStream() AI_NO_EXCEPT = default;
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE
|
||||
IOStream::~IOStream() = default;
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
} //!namespace Assimp
|
||||
|
||||
#endif //!!AI_IOSTREAM_H_INC
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
IOStreamBuffer(size_t cache = 4096 * 4096);
|
||||
|
||||
/// @brief The class destructor.
|
||||
~IOStreamBuffer();
|
||||
~IOStreamBuffer() = default;
|
||||
|
||||
/// @brief Will open the cached access for a given stream.
|
||||
/// @param stream The stream to cache.
|
||||
|
@ -140,9 +140,6 @@ AI_FORCE_INLINE IOStreamBuffer<T>::IOStreamBuffer(size_t cache) :
|
|||
std::fill(m_cache.begin(), m_cache.end(), '\n');
|
||||
}
|
||||
|
||||
template <class T>
|
||||
AI_FORCE_INLINE IOStreamBuffer<T>::~IOStreamBuffer() = default;
|
||||
|
||||
template <class T>
|
||||
AI_FORCE_INLINE bool IOStreamBuffer<T>::open(IOStream *stream) {
|
||||
// file still opened!
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
*/
|
||||
LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
|
||||
|
||||
~LineSplitter();
|
||||
~LineSplitter() = default;
|
||||
|
||||
// -----------------------------------------
|
||||
/** pseudo-iterator increment */
|
||||
|
@ -160,8 +160,6 @@ AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_emp
|
|||
mIdx = 0;
|
||||
}
|
||||
|
||||
AI_FORCE_INLINE LineSplitter::~LineSplitter() = default;
|
||||
|
||||
AI_FORCE_INLINE LineSplitter& LineSplitter::operator++() {
|
||||
if (mSwallow) {
|
||||
mSwallow = false;
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -63,10 +62,8 @@ namespace Assimp {
|
|||
* implementation to handle all details of its file format correctly.
|
||||
*/
|
||||
// ----------------------------------------------------------------------------------
|
||||
class ASSIMP_API SGSpatialSort
|
||||
{
|
||||
class ASSIMP_API SGSpatialSort {
|
||||
public:
|
||||
|
||||
SGSpatialSort();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -90,7 +87,7 @@ public:
|
|||
void Prepare();
|
||||
|
||||
/** Destructor */
|
||||
~SGSpatialSort();
|
||||
~SGSpatialSort() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns an iterator for all positions close to the given position.
|
||||
|
|
|
@ -59,18 +59,12 @@ struct aiAABB {
|
|||
|
||||
#ifdef __cplusplus
|
||||
/// @brief The default class constructor.
|
||||
aiAABB() :
|
||||
mMin(), mMax() {
|
||||
// empty
|
||||
}
|
||||
aiAABB() = default;
|
||||
|
||||
/// @brief The class constructor with the minimum and maximum.
|
||||
/// @param min The minimum dimension.
|
||||
/// @param max The maximum dimension.
|
||||
aiAABB(const aiVector3D &min, const aiVector3D &max) :
|
||||
mMin(min), mMax(max) {
|
||||
// empty
|
||||
}
|
||||
aiAABB(const aiVector3D &min, const aiVector3D &max) : mMin(min), mMax(max) {}
|
||||
|
||||
/// @brief The class destructor.
|
||||
~aiAABB() = default;
|
||||
|
|
|
@ -90,6 +90,7 @@ struct aiVectorKey {
|
|||
bool operator==(const aiVectorKey &rhs) const {
|
||||
return rhs.mValue == this->mValue;
|
||||
}
|
||||
|
||||
bool operator!=(const aiVectorKey &rhs) const {
|
||||
return rhs.mValue != this->mValue;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/vector3.h>
|
||||
#include <assimp/defs.h>
|
||||
#include <assimp/config.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
|
|
@ -48,18 +48,18 @@ TEST_F( utVersion, aiGetLegalStringTest ) {
|
|||
EXPECT_NE( lv, nullptr );
|
||||
std::string text( lv );
|
||||
|
||||
size_t pos = text.find(std::string("2023"));
|
||||
size_t pos = text.find(std::string("2024"));
|
||||
EXPECT_NE(pos, std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionMinorTest ) {
|
||||
EXPECT_EQ(aiGetVersionMinor(), 3U);
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionMajorTest ) {
|
||||
EXPECT_EQ( aiGetVersionMajor(), 5U );
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionMinorTest ) {
|
||||
EXPECT_EQ(aiGetVersionMinor(), 4U);
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionPatchTest ) {
|
||||
EXPECT_EQ(aiGetVersionPatch(), 0U );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue