diff options
277 files changed, 10261 insertions, 1030 deletions
diff --git a/.travis.yml b/.travis.yml index ee6dd4d28cc..e71daad7408 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ install: - mysql -uroot -e 'create database test_mysql;' - mkdir bin - cd bin - - cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DNOJEM=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" + - cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS=1 -DSERVERS=1 -DNOJEM=1 -DWITH_DYNAMIC_LINKING=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_INSTALL_PREFIX=check_install - cd .. - sudo chmod +x contrib/check_updates.sh @@ -38,4 +38,7 @@ script: - cat sql/updates/hotfixes/*.sql | mysql -utrinity -ptrinity hotfixes - mysql -uroot < sql/create/drop_mysql.sql - cd bin - - make -j 8 -k + - make -j 8 -k && make install + - cd check_install/bin + - ./bnetserver --version + - ./worldserver --version diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d4e1f051d..dda8f242feb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,9 +24,6 @@ endif(POLICY CMP0043) set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) -# build static libraries -set(BUILD_SHARED_LIBS OFF) - # Set RPATH-handing (CMake parameters) set(CMAKE_SKIP_BUILD_RPATH 0) set(CMAKE_BUILD_WITH_INSTALL_RPATH 0) diff --git a/cmake/compiler/clang/settings.cmake b/cmake/compiler/clang/settings.cmake index 261a55b285f..9a8cb85275e 100644 --- a/cmake/compiler/clang/settings.cmake +++ b/cmake/compiler/clang/settings.cmake @@ -18,3 +18,16 @@ endif() # -Wno-deprecated-register is needed to suppress 185 gsoap warnings on Unix systems. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-narrowing -Wno-deprecated-register") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1") + +if (WITH_DYNAMIC_LINKING) + # -fPIC is needed to allow static linking in shared libs. + # -fvisibility=hidden sets the default visibility to hidden to prevent exporting of all symbols. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden") + + # --no-undefined to throw errors when there are undefined symbols + # (caused through missing TRINITY_*_API macros). + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --no-undefined") + + message(STATUS "Clang: Disallow undefined symbols") +endif() diff --git a/cmake/compiler/gcc/settings.cmake b/cmake/compiler/gcc/settings.cmake index acd71e82fd9..d9eda767b8e 100644 --- a/cmake/compiler/gcc/settings.cmake +++ b/cmake/compiler/gcc/settings.cmake @@ -34,3 +34,15 @@ if( WITH_COREDEBUG ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3") message(STATUS "GCC: Debug-flags set (-g3)") endif() + +if (WITH_DYNAMIC_LINKING) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -fvisibility=hidden -Wno-attributes") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -fvisibility=hidden -Wno-attributes") + + # Should break the build when there are TRINITY_*_API macros missing + # but it complains about missing references in precompiled headers. + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--no-undefined") + # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined") + + message(STATUS "GCC: Enabled shared linking") +endif() diff --git a/cmake/compiler/msvc/settings.cmake b/cmake/compiler/msvc/settings.cmake index 52c19b336cb..86470f327c5 100644 --- a/cmake/compiler/msvc/settings.cmake +++ b/cmake/compiler/msvc/settings.cmake @@ -18,11 +18,6 @@ if(PLATFORM EQUAL 64) add_definitions("-D_WIN64") message(STATUS "MSVC: 64-bit platform, enforced -D_WIN64 parameter") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.23026.0) - #Enable extended object support for debug compiles on X64 (not required on X86) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj") - message(STATUS "MSVC: Enabled increased number of sections in object files") - endif() else() # mark 32 bit executables large address aware so they can use > 2GB address space set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") @@ -41,15 +36,20 @@ add_definitions(-D_BUILD_DIRECTIVE=\\"$(ConfigurationName)\\") # multithreaded compiling on VS set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") +if((PLATFORM EQUAL 64) OR (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.23026.0) OR WITH_DYNAMIC_LINKING) + # Enable extended object support + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") + message(STATUS "MSVC: Enabled increased number of sections in object files") +endif() + # /Zc:throwingNew. # When you specify Zc:throwingNew on the command line, it instructs the compiler to assume # that the program will eventually be linked with a conforming operator new implementation, # and can omit all of these extra null checks from your program. # http://blogs.msdn.com/b/vcblog/archive/2015/08/06/new-in-vs-2015-zc-throwingnew.aspx if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0.23026.0)) - # also enable /bigobj for ALL builds under visual studio 2015, increased number of templates in standard library # makes this flag a requirement to build TC at all - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:throwingNew /bigobj") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:throwingNew") endif() # Define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES - eliminates the warning by changing the strcpy call to strcpy_s, which prevents buffer overruns @@ -75,6 +75,13 @@ if(NOT WITH_WARNINGS) message(STATUS "MSVC: Disabled generic compiletime warnings") endif() +if (WITH_DYNAMIC_LINKING) + # C4251: needs to have dll-interface to be used by clients of class '...' + # C4275: non dll-interface class ...' used as base for dll-interface class '...' + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4275") + message(STATUS "MSVC: Enabled shared linking") +endif() + # Specify the maximum PreCompiled Header memory allocation limit # Fixes a compiler-problem when using PCH - the /Ym flag is adjusted by the compiler in MSVC2012, hence we need to set an upper limit with /Zm to avoid discrepancies) # (And yes, this is a verified , unresolved bug with MSVC... *sigh*) diff --git a/cmake/options.cmake b/cmake/options.cmake index 6b6a672adc6..1a028959047 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -13,6 +13,7 @@ option(SCRIPTS "Build core with scripts included" option(TOOLS "Build map/vmap/mmap extraction/assembler tools" 0) option(USE_SCRIPTPCH "Use precompiled headers when compiling scripts" 1) option(USE_COREPCH "Use precompiled headers when compiling servers" 1) +option(WITH_DYNAMIC_LINKING "Enable dynamic library linking." 0) option(WITH_WARNINGS "Show all warnings during compile" 0) option(WITH_COREDEBUG "Include additional debug-code in core" 0) set(WITH_SOURCE_TREE "hierarchical" CACHE STRING "Build the source tree for IDE's.") diff --git a/cmake/showoptions.cmake b/cmake/showoptions.cmake index b4ef652cf35..b485cfe5ce6 100644 --- a/cmake/showoptions.cmake +++ b/cmake/showoptions.cmake @@ -113,5 +113,15 @@ if ( HELGRIND ) add_definitions(-DHELGRIND) endif() -message("") +if (WITH_DYNAMIC_LINKING) + message("") + message(" *** WITH_DYNAMIC_LINKING - INFO!") + message(" *** Will link against shared libraries!") + message(" *** Please note that this is an experimental feature!") + add_definitions(-DTRINITY_API_USE_DYNAMIC_LINKING) + set(BUILD_SHARED_LIBS ON) +else() + set(BUILD_SHARED_LIBS OFF) +endif() +message("") diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index d60e0ca56a6..2d646f35f0f 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -34,6 +34,7 @@ if(SERVERS) add_subdirectory(process) add_subdirectory(readline) add_subdirectory(gsoap) + add_subdirectory(rapidjson) endif() if(TOOLS) diff --git a/dep/PackageList.txt b/dep/PackageList.txt index f57c925e18f..6dd91453e4d 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -55,3 +55,7 @@ recastnavigation (Recast is state of the art navigation mesh construction toolse CascLib (An open-source implementation of library for reading CASC storage from Blizzard games since 2014) https://github.com/ladislav-zezula/CascLib Version: 919a2d670cb749c501ee15887a88e9b9a538961b + +rapidjson (A fast JSON parser/generator for C++ with both SAX/DOM style API http://rapidjson.org/) + https://github.com/miloyip/rapidjson + Version: v1.0.2 diff --git a/dep/rapidjson/CMakeLists.txt b/dep/rapidjson/CMakeLists.txt new file mode 100644 index 00000000000..de1466a41a6 --- /dev/null +++ b/dep/rapidjson/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +add_library(rapidjson INTERFACE) + +target_include_directories(rapidjson + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}) + +target_compile_definitions(rapidjson + INTERFACE + -DRAPIDJSON_HAS_STDSTRING + -DRAPIDJSON_SSE2) diff --git a/dep/rapidjson/rapidjson/allocators.h b/dep/rapidjson/rapidjson/allocators.h new file mode 100644 index 00000000000..d74a67155b4 --- /dev/null +++ b/dep/rapidjson/rapidjson/allocators.h @@ -0,0 +1,261 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return std::malloc(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + std::free(originalPtr); + return NULL; + } + return std::realloc(originalPtr, newSize); + } + static void Free(void *ptr) { std::free(ptr); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template <typename BaseAllocator = CrtAllocator> +class MemoryPoolAllocator { +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer); + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + RAPIDJSON_DELETE(ownBaseAllocator_); + } + + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while (chunkHead_ && chunkHead_ != userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + if (chunkHead_ && chunkHead_ == userBuffer_) + chunkHead_->size = 0; // Clear user buffer + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) + AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); + + void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + chunkHead_->size; + chunkHead_->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + if (newSize == 0) + return NULL; + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { + size_t increment = static_cast<size_t>(newSize - originalSize); + increment = RAPIDJSON_ALIGN(increment); + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + void* newBuffer = Malloc(newSize); + RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly. + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) { (void)ptr; } // Do nothing + +private: + //! Copy constructor is not permitted. + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; + //! Copy assignment operator is not permitted. + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; + + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + */ + void AddChunk(size_t capacity) { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator()); + ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity)); + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + } + + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + void *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/dep/rapidjson/rapidjson/document.h b/dep/rapidjson/rapidjson/document.h new file mode 100644 index 00000000000..c6acbd907ab --- /dev/null +++ b/dep/rapidjson/rapidjson/document.h @@ -0,0 +1,2014 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include <new> // placement new + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include <string> +#endif // RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include <iterator> // std::iterator, std::random_access_iterator_tag +#endif + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include <utility> // std::move +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template <typename Encoding, typename Allocator> +class GenericValue; + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template <typename Encoding, typename Allocator> +struct GenericMember { + GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) + GenericValue<Encoding, Allocator> value; //!< value of member. +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ <iterator> header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template <bool Const, typename Encoding, typename Allocator> +class GenericMemberIterator + : public std::iterator<std::random_access_iterator_tag + , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> { + + friend class GenericValue<Encoding,Allocator>; + template <bool, typename, typename> friend class GenericMemberIterator; + + typedef GenericMember<Encoding,Allocator> PlainType; + typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; + typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator; + + //! Pointer to (const) GenericMember + typedef typename BaseType::pointer Pointer; + //! Reference to (const) GenericMember + typedef typename BaseType::reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef typename BaseType::difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } + bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } + bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } + bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } + bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template <bool Const, typename Encoding, typename Allocator> +struct GenericMemberIterator; + +//! non-const GenericMemberIterator +template <typename Encoding, typename Allocator> +struct GenericMemberIterator<false,Encoding,Allocator> { + //! use plain pointer as iterator type + typedef GenericMember<Encoding,Allocator>* Iterator; +}; +//! const GenericMemberIterator +template <typename Encoding, typename Allocator> +struct GenericMemberIterator<true,Encoding,Allocator> { + //! use plain const pointer as iterator type + typedef const GenericMember<Encoding,Allocator>* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template<typename CharType> +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ + template<SizeType N> + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ + explicit GenericStringRef(const CharType* str) + : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); } + + //! Create constant string reference from pointer and length + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ + GenericStringRef(const CharType* str, SizeType len) + : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); } + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + //! Disallow copy-assignment + GenericStringRef operator=(const GenericStringRef&); + //! Disallow construction from non-const array + template<SizeType N> + GenericStringRef(CharType (&str)[N]) /* = delete */; +}; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template<typename CharType> +inline GenericStringRef<CharType> StringRef(const CharType* str) { + return GenericStringRef<CharType>(str, internal::StrLen(str)); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template<typename CharType> +inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) { + return GenericStringRef<CharType>(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template<typename CharType> +inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) { + return GenericStringRef<CharType>(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template <typename T, typename Encoding = void, typename Allocator = void> +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type> + : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember<Encoding, Allocator> Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself. + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) { + rhs.flags_ = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() { + static const unsigned defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + flags_ = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \see CopyFrom() + */ + template< typename SourceAllocator > + GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator); + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template <typename T> + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_(), flags_(b ? kTrueFlag : kFalseFlag) { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value)); + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) { + data_.n.i64 = i; + if (i >= 0) + flags_ |= kUintFlag | kUint64Flag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) { + data_.n.u64 = u; + if (!(u & 0x80000000)) + flags_ |= kIntFlag | kInt64Flag; + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) { + data_.n.i64 = i64; + if (i64 >= 0) { + flags_ |= kNumberUint64Flag; + if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + flags_ |= kUintFlag; + if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) { + data_.n.u64 = u64; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + flags_ |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + flags_ |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + flags_ |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(flags_) { + case kArrayFlag: + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(data_.a.elements); + break; + + case kObjectFlag: + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(data_.o.members); + break; + + case kCopyStringFlag: + Allocator::Free(const_cast<Ch*>(data_.s.str)); + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + RawAssign(rhs); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + */ + template <typename SourceAllocator> + GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { + RAPIDJSON_ASSERT((void*)this != (void const*)&rhs); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Linear time complexity (number of all values in the subtree and total lengths of all strings). + */ + template <typename SourceAllocator> + bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const { + typedef GenericValue<Encoding, SourceAllocator> RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + 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) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: // kTrueType, kFalseType, kNullType + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template <typename SourceAllocator> + bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} + + //!@name Type + //@{ + + Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); } + bool IsNull() const { return flags_ == kNullFlag; } + bool IsFalse() const { return flags_ == kFalseFlag; } + bool IsTrue() const { return flags_ == kTrueFlag; } + bool IsBool() const { return (flags_ & kBoolFlag) != 0; } + bool IsObject() const { return flags_ == kObjectFlag; } + bool IsArray() const { return flags_ == kArrayFlag; } + bool IsNumber() const { return (flags_ & kNumberFlag) != 0; } + bool IsInt() const { return (flags_ & kIntFlag) != 0; } + bool IsUint() const { return (flags_ & kUintFlag) != 0; } + bool IsInt64() const { return (flags_ & kInt64Flag) != 0; } + bool IsUint64() const { return (flags_ & kUint64Flag) != 0; } + bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; } + bool IsString() const { return (flags_ & kStringFlag) != 0; } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template <typename SourceAllocator> + GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + static GenericValue NullValue; + return NullValue; + } + } + template <typename SourceAllocator> + const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template <typename SourceAllocator> + bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template <typename SourceAllocator> + 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; + } + template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); } + ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + + Object& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 + o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member))); + } + } + o.members[o.size].name.RawAssign(name); + o.members[o.size].value.RawAssign(value); + o.size++; + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template <typename SourceAllocator> + bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(data_.o.members != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + + MemberIterator last(data_.o.members + (data_.o.size - 1)); + if (data_.o.size > 1 && m != last) { + // Move the last one to this place + *m = *last; + } + else { + // Only one left, just destroy + m->~Member(); + } + --data_.o.size; + return m; + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(data_.o.members != 0); + 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(&*pos, &*last, (MemberEnd() - last) * sizeof(Member)); + data_.o.size -= (last - first); + return pos; + } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + for (SizeType i = 0; i < data_.a.size; ++i) + data_.a.elements[i].~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return data_.a.elements[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + data_.a.elements[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack<StringRefType>(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template <typename T> + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + data_.a.elements[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(data_.a.elements != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(pos, last, (End() - last) * sizeof(GenericValue)); + data_.a.size -= (last - first); + return pos; + } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } + + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision) + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); } + + //! 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 ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } + + //! 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. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } +#endif + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template <typename Handler> + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (!handler.StartObject()) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0)) + return false; + if (!m->value.Accept(handler)) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (!handler.StartArray()) + return false; + for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) + if (!v->Accept(handler)) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else if (IsUint64()) return handler.Uint64(data_.n.u64); + else return handler.Double(data_.n.d); + } + } + +private: + template <typename, typename> friend class GenericValue; + template <typename, typename, typename> friend class GenericDocument; + + enum { + kBoolFlag = 0x100, + kNumberFlag = 0x200, + kIntFlag = 0x400, + kUintFlag = 0x800, + kInt64Flag = 0x1000, + kUint64Flag = 0x2000, + kDoubleFlag = 0x4000, + kStringFlag = 0x100000, + kCopyFlag = 0x200000, + kInlineStrFlag = 0x400000, + + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler + }; + + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; + + struct String { + const Ch* str; + SizeType length; + unsigned hashcode; //!< reserved + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode + // inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); } + inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct Object { + Member* members; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct Array { + GenericValue* elements; + SizeType size; + SizeType capacity; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + Object o; + Array a; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + flags_ = kArrayFlag; + if (count) { + data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue)); + std::memcpy(data_.a.elements, values, count * sizeof(GenericValue)); + } + else + data_.a.elements = NULL; + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + flags_ = kObjectFlag; + if (count) { + data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member)); + std::memcpy(data_.o.members, members, count * sizeof(Member)); + } + else + data_.o.members = NULL; + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + flags_ = kConstStringFlag; + data_.s.str = s; + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = NULL; + if(ShortString::Usable(s.length)) { + flags_ = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + flags_ = kCopyStringFlag; + data_.s.length = s.length; + str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch)); + data_.s.str = str; + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + flags_ = rhs.flags_; + rhs.flags_ = kNullFlag; + } + + template <typename SourceAllocator> + bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; + unsigned flags_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue<UTF8<> > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator> +class GenericDocument : public GenericValue<Encoding, Allocator> { +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. + + //! Constructor + /*! \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::move(rhs)), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward<ValueType>(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template <unsigned parseFlags, typename SourceEncoding, typename InputStream> + GenericDocument& ParseStream(InputStream& is) { + ValueType::SetNull(); // Remove existing root if exist + GenericReader<SourceEncoding, Encoding, StackAllocator> reader(&stack_.GetAllocator()); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse<parseFlags>(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13. + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template <unsigned parseFlags, typename InputStream> + GenericDocument& ParseStream(InputStream& is) { + return ParseStream<parseFlags, Encoding, InputStream>(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template <typename InputStream> + GenericDocument& ParseStream(InputStream& is) { + return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template <unsigned parseFlags> + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream<Encoding> s(str); + return ParseStream<parseFlags | kParseInsituFlag>(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu<kParseDefaultFlags>(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template <unsigned parseFlags, typename SourceEncoding> + GenericDocument& Parse(const Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream<SourceEncoding> s(str); + return ParseStream<parseFlags, SourceEncoding>(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template <unsigned parseFlags> + GenericDocument& Parse(const Ch* str) { + return Parse<parseFlags, Encoding>(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse<kParseDefaultFlags>(str); + } + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { return *allocator_; } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + template <typename,typename,typename> friend class GenericReader; // for parsing + template <typename, typename> friend class GenericValue; // for deep copying + + // Implementation of Handler + bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push<ValueType>()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); + stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop<ValueType>(elementCount); + stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop<ValueType>(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack<StackAllocator> stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument<UTF8<> > Document; + +// defined here due to the dependency on GenericDocument +template <typename Encoding, typename Allocator> +template <typename SourceAllocator> +inline +GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) +{ + switch (rhs.GetType()) { + case kObjectType: + case kArrayType: { // perform deep copy via SAX Handler + GenericDocument<Encoding,Allocator> d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop<GenericValue>(1)); + } + break; + case kStringType: + if (rhs.flags_ == kConstStringFlag) { + flags_ = rhs.flags_; + data_ = *reinterpret_cast<const Data*>(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: // kNumberType, kTrueType, kFalseType, kNullType + flags_ = rhs.flags_; + data_ = *reinterpret_cast<const Data*>(&rhs.data_); + } +} + +RAPIDJSON_NAMESPACE_END + +#if defined(_MSC_VER) || defined(__GNUC__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/dep/rapidjson/rapidjson/encodedstream.h b/dep/rapidjson/rapidjson/encodedstream.h new file mode 100644 index 00000000000..7c8863fee2f --- /dev/null +++ b/dep/rapidjson/rapidjson/encodedstream.h @@ -0,0 +1,261 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template <typename Encoding, typename InputByteStream> +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template <typename Encoding, typename OutputByteStream> +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); } + Ch Take() { RAPIDJSON_ASSERT(false); } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template <typename CharType, typename InputByteStream> +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = (const unsigned char *)is_->Peek4(); + if (!c) + return; + + unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam InputByteStream type of output byte stream to be wrapped. +*/ +template <typename CharType, typename OutputByteStream> +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); } + Ch Take() { RAPIDJSON_ASSERT(false); } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/dep/rapidjson/rapidjson/encodings.h b/dep/rapidjson/rapidjson/encodings.h new file mode 100644 index 00000000000..90b46ed325b --- /dev/null +++ b/dep/rapidjson/rapidjson/encodings.h @@ -0,0 +1,625 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template<typename OutputStream> + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template <typename InputStream> + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template <typename InputStream, typename OutputStream> + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template <typename InputByteStream> + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template <typename OutputByteStream> + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template<typename CharType = char> +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template<typename OutputStream> + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast<Ch>(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); + } + } + + template <typename InputStream> + static bool Decode(InputStream& is, unsigned* codepoint) { +#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu) +#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = (unsigned char)c; + return true; + } + + unsigned char type = GetRange((unsigned char)c); + *codepoint = (0xFF >> type) & (unsigned char)c; + bool result = true; + switch (type) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + template <typename InputStream, typename OutputStream> + static bool Validate(InputStream& is, OutputStream& os) { +#define COPY() os.Put(c = is.Take()) +#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c; + COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange((unsigned char)c)) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + Ch c = Take(is); + if ((unsigned char)c != 0xEFu) return c; + c = is.Take(); + if ((unsigned char)c != 0xBBu) return c; + c = is.Take(); + if ((unsigned char)c != 0xBFu) return c; + c = is.Take(); + return c; + } + + template <typename InputByteStream> + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return is.Take(); + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu); + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast<typename OutputByteStream::Ch>(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template<typename CharType = wchar_t> +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template<typename OutputStream> + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast<typename OutputStream::Ch>(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); + os.Put((v & 0x3FF) | 0xDC00); + } + } + + template <typename InputStream> + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = c; + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (c & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (c & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template <typename InputStream, typename OutputStream> + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + Ch c; + os.Put(c = is.Take()); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template<typename CharType = wchar_t> +struct UTF16LE : UTF16<CharType> { + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned short)c == 0xFEFFu ? Take(is) : c; + } + + template <typename InputByteStream> + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take(); + c |= (unsigned char)is.Take() << 8; + return c; + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFFu); os.Put(0xFEu); + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(c & 0xFFu); + os.Put((c >> 8) & 0xFFu); + } +}; + +//! UTF-16 big endian encoding. +template<typename CharType = wchar_t> +struct UTF16BE : UTF16<CharType> { + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned short)c == 0xFEFFu ? Take(is) : c; + } + + template <typename InputByteStream> + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take(); + return c; + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFEu); os.Put(0xFFu); + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put((c >> 8) & 0xFFu); + os.Put(c & 0xFFu); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template<typename CharType = unsigned> +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template<typename OutputStream> + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template <typename InputStream> + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template <typename InputStream, typename OutputStream> + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian enocoding. +template<typename CharType = unsigned> +struct UTF32LE : UTF32<CharType> { + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned)c == 0x0000FEFFu ? Take(is) : c; + } + + template <typename InputByteStream> + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take(); + c |= (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take() << 16; + c |= (unsigned char)is.Take() << 24; + return c; + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u); + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(c & 0xFFu); + os.Put((c >> 8) & 0xFFu); + os.Put((c >> 16) & 0xFFu); + os.Put((c >> 24) & 0xFFu); + } +}; + +//! UTF-32 big endian encoding. +template<typename CharType = unsigned> +struct UTF32BE : UTF32<CharType> { + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return (unsigned)c == 0x0000FEFFu ? Take(is) : c; + } + + template <typename InputByteStream> + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = (unsigned char)is.Take() << 24; + c |= (unsigned char)is.Take() << 16; + c |= (unsigned char)is.Take() << 8; + c |= (unsigned char)is.Take(); + return c; + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu); + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put((c >> 24) & 0xFFu); + os.Put((c >> 16) & 0xFFu); + os.Put((c >> 8) & 0xFFu); + os.Put(c & 0xFFu); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template<typename CharType = char> +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template<typename OutputStream> + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast<Ch>(codepoint & 0xFF)); + } + + template <typename InputStream> + static bool Decode(InputStream& is, unsigned* codepoint) { + unsigned char c = static_cast<unsigned char>(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template <typename InputStream, typename OutputStream> + static bool Validate(InputStream& is, OutputStream& os) { + unsigned char c = is.Take(); + os.Put(c); + return c <= 0x7F; + } + + template <typename InputByteStream> + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + Ch c = Take(is); + return c; + } + + template <typename InputByteStream> + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return is.Take(); + } + + template <typename OutputByteStream> + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template <typename OutputByteStream> + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast<typename OutputByteStream::Ch>(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). +*/ +template<typename CharType> +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x + + template<typename OutputStream> + RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template <typename InputStream> + RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template <typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template<typename SourceEncoding, typename TargetEncoding> +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template<typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template<typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +//! Specialization of Transcoder with same source and target encoding. +template<typename Encoding> +struct Transcoder<Encoding, Encoding> { + template<typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template<typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(_MSV_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/dep/rapidjson/rapidjson/error/en.h b/dep/rapidjson/rapidjson/error/en.h new file mode 100644 index 00000000000..d5f9caab8e9 --- /dev/null +++ b/dep/rapidjson/rapidjson/error/en.h @@ -0,0 +1,65 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H__ +#define RAPIDJSON_ERROR_EN_H__ + +#include "error.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: + return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ERROR_EN_H__ diff --git a/dep/rapidjson/rapidjson/error/error.h b/dep/rapidjson/rapidjson/error/error.h new file mode 100644 index 00000000000..f9094fb9594 --- /dev/null +++ b/dep/rapidjson/rapidjson/error/error.h @@ -0,0 +1,146 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H__ +#define RAPIDJSON_ERROR_ERROR_H__ + +#include "../rapidjson.h" + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { + + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Conversion to \c bool, returns \c true, iff !\ref IsError(). + operator bool() const { return !IsError(); } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ERROR_ERROR_H__ diff --git a/dep/rapidjson/rapidjson/filereadstream.h b/dep/rapidjson/rapidjson/filereadstream.h new file mode 100644 index 00000000000..3913eb74b0d --- /dev/null +++ b/dep/rapidjson/rapidjson/filereadstream.h @@ -0,0 +1,88 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "rapidjson.h" +#include <cstdio> + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/dep/rapidjson/rapidjson/filewritestream.h b/dep/rapidjson/rapidjson/filewritestream.h new file mode 100644 index 00000000000..dfb9cbd02a9 --- /dev/null +++ b/dep/rapidjson/rapidjson/filewritestream.h @@ -0,0 +1,91 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "rapidjson.h" +#include <cstdio> + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast<size_t>(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast<size_t>(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_); + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/dep/rapidjson/rapidjson/internal/biginteger.h b/dep/rapidjson/rapidjson/internal/biginteger.h new file mode 100644 index 00000000000..99a30acf613 --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/biginteger.h @@ -0,0 +1,280 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include <intrin.h> // for _umul128 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + BigInteger(const char* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + void AppendDecimal64(const char* begin, const char* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast<unsigned>(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + static uint64_t ParseUint64(const char* begin, const char* end) { + uint64_t r = 0; + for (const char* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); + r = r * 10 + (*p - '0'); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif (__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; + *outHigh = static_cast<uint64_t>(p >> 64); + return static_cast<uint64_t>(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast<uint64_t>(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/dep/rapidjson/rapidjson/internal/diyfp.h b/dep/rapidjson/rapidjson/internal/diyfp.h new file mode 100644 index 00000000000..3b6c4238c1f --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/diyfp.h @@ -0,0 +1,247 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include <intrin.h> +#pragma intrinsic(_BitScanReverse64) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +struct DiyFp { + DiyFp() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __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); + uint64_t l = static_cast<uint64_t>(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp(f << (63 - index), e - (63 - index)); +#elif defined(__GNUC__) && __GNUC__ >= 4 + int s = __builtin_clzll(f); + return DiyFp(f << s, e - s); +#else + DiyFp res = *this; + while (!(res.f & (static_cast<uint64_t>(1) << 63))) { + res.f <<= 1; + res.e--; + } + return res; +#endif + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast<uint64_t>(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast<int>(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast<unsigned>((k >> 3) + 1); + *K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + unsigned index = (exp + 348) / 8; + *outExp = -348 + index * 8; + return GetCachedPowerByIndex(index); + } + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/dep/rapidjson/rapidjson/internal/dtoa.h b/dep/rapidjson/rapidjson/internal/dtoa.h new file mode 100644 index 00000000000..2d8d2e46a3f --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/dtoa.h @@ -0,0 +1,217 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline unsigned CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d)); + kappa--; + uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast<char>(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast<char>('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast<char>('0' + static_cast<char>(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (length <= kk && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], length - kk); + buffer[kk] = '.'; + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], length); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + return &buffer[length + offset]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], length - 1); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer) { + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/dep/rapidjson/rapidjson/internal/ieee754.h b/dep/rapidjson/rapidjson/internal/ieee754.h new file mode 100644 index 00000000000..e3f03364c60 --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/ieee754.h @@ -0,0 +1,77 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static unsigned EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return order + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/dep/rapidjson/rapidjson/internal/itoa.h b/dep/rapidjson/rapidjson/internal/itoa.h new file mode 100644 index 00000000000..01a4e7e72d7 --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/itoa.h @@ -0,0 +1,304 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast<char>('0' + static_cast<char>(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + uint32_t u = static_cast<uint32_t>(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast<uint32_t>(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast<uint32_t>(value / kTen8); + const uint32_t v1 = static_cast<uint32_t>(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + if (value >= kTen8) + *buffer++ = cDigitsLut[d4 + 1]; + + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast<char>('0' + static_cast<char>(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast<uint32_t>(value / kTen8); + const uint32_t v1 = static_cast<uint32_t>(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + uint64_t u = static_cast<uint64_t>(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/dep/rapidjson/rapidjson/internal/meta.h b/dep/rapidjson/rapidjson/internal/meta.h new file mode 100644 index 00000000000..5a9aaa42866 --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/meta.h @@ -0,0 +1,181 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif +#if defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include <type_traits> +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template <typename T> struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template <bool Cond> struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType<true> TrueType; +typedef BoolType<false> FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; }; +template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {}; +template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {}; + +template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {}; +template <> struct AndExprCond<true, true> : TrueType {}; +template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {}; +template <> struct OrExprCond<false, false> : FalseType {}; + +template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {}; +template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {}; +template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {}; +template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template <typename T> struct AddConst { typedef const T Type; }; +template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {}; +template <typename T> struct RemoveConst { typedef T Type; }; +template <typename T> struct RemoveConst<const T> { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template <typename T, typename U> struct IsSame : FalseType {}; +template <typename T> struct IsSame<T, T> : TrueType {}; + +template <typename T> struct IsConst : FalseType {}; +template <typename T> struct IsConst<const T> : TrueType {}; + +template <typename CT, typename T> +struct IsMoreConst + : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>, + BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {}; + +template <typename T> struct IsPointer : FalseType {}; +template <typename T> struct IsPointer<T*> : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template <typename B, typename D> struct IsBaseOf + : BoolType< ::std::is_base_of<B,D>::value> {}; + +#else // simplified version adopted from Boost + +template<typename B, typename D> struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template <typename T> + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template <typename B, typename D> struct IsBaseOf + : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; }; +template <typename T> struct EnableIfCond<false, T> { /* empty */ }; + +template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; }; +template <typename T> struct DisableIfCond<true, T> { /* empty */ }; + +template <typename Condition, typename T = void> +struct EnableIf : EnableIfCond<Condition::Value, T> {}; + +template <typename Condition, typename T = void> +struct DisableIf : DisableIfCond<Condition::Value, T> {}; + +// SFINAE helpers +struct SfinaeTag {}; +template <typename T> struct RemoveSfinaeTag; +template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + <RAPIDJSON_REMOVEFPTR_(cond), \ + RAPIDJSON_REMOVEFPTR_(returntype)>::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + <RAPIDJSON_REMOVEFPTR_(cond), \ + RAPIDJSON_REMOVEFPTR_(returntype)>::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/dep/rapidjson/rapidjson/internal/pow10.h b/dep/rapidjson/rapidjson/internal/pow10.h new file mode 100644 index 00000000000..02f475d705f --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/dep/rapidjson/rapidjson/internal/stack.h b/dep/rapidjson/rapidjson/internal/stack.h new file mode 100644 index 00000000000..722d569230b --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/stack.h @@ -0,0 +1,179 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template <typename Allocator> +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + RAPIDJSON_ASSERT(stackCapacity > 0); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template<typename T> + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + // Expand the stack if needed + if (stackTop_ + sizeof(T) * count >= stackEnd_) + Expand<T>(count); + + T* ret = reinterpret_cast<T*>(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template<typename T> + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast<T*>(stackTop_); + } + + template<typename T> + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast<T*>(stackTop_ - sizeof(T)); + } + + template<typename T> + T* Bottom() { return (T*)stack_; } + + Allocator& GetAllocator() { return *allocator_; } + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); } + +private: + template<typename T> + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STACK_H_ diff --git a/dep/rapidjson/rapidjson/internal/strfunc.h b/dep/rapidjson/rapidjson/internal/strfunc.h new file mode 100644 index 00000000000..84405065a27 --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/strfunc.h @@ -0,0 +1,39 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template <typename Ch> +inline SizeType StrLen(const Ch* s) { + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/dep/rapidjson/rapidjson/internal/strtod.h b/dep/rapidjson/rapidjson/internal/strtod.h new file mode 100644 index 00000000000..ace65f6773f --- /dev/null +++ b/dep/rapidjson/rapidjson/internal/strtod.h @@ -0,0 +1,270 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "../rapidjson.h" +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template <typename T> +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2; + + BigInteger bS(bInt); + bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2; + + BigInteger hS(1); + hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2; + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { + uint64_t significand = 0; + size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < length; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) + break; + significand = significand * 10 + (decimals[i] - '0'); + } + + if (i < length && decimals[i] >= '5') // Rounding + significand++; + + size_t remaining = length - i; + const unsigned kUlpShift = 3; + const unsigned kUlp = 1 << kUlpShift; + int error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + const int dExp = (int)decimalPosition - (int)i + exp; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp - 1; + RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); + v = v * kPow10[adjustment]; + if (length + adjustment > 19) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + unsigned precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + unsigned scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + kUlp; + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + error) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - error >= precisionBits || precisionBits >= halfWay + error; +} + +inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { + const BigInteger dInt(decimals, length); + const int dExp = (int)decimalPosition - (int)length + exp; + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result; + if (StrtodFast(d, p, &result)) + return result; + + // Trim leading zeros + while (*decimals == '0' && length > 1) { + length--; + decimals++; + decimalPosition--; + } + + // Trim trailing zeros + while (decimals[length - 1] == '0' && length > 1) { + length--; + decimalPosition--; + exp++; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 780; + if ((int)length > kMaxDecimalDigit) { + int delta = (int(length) - kMaxDecimalDigit); + exp += delta; + decimalPosition -= delta; + length = kMaxDecimalDigit; + } + + // If too small, underflow to zero + if (int(length) + exp < -324) + return 0.0; + + if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, length, decimalPosition, exp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/dep/rapidjson/rapidjson/memorybuffer.h b/dep/rapidjson/rapidjson/memorybuffer.h new file mode 100644 index 00000000000..2484b2185a8 --- /dev/null +++ b/dep/rapidjson/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template <typename Allocator = CrtAllocator> +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push<Ch>() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push<Ch>(count); } + void Pop(size_t count) { stack_.template Pop<Ch>(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom<Ch>(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack<Allocator> stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/dep/rapidjson/rapidjson/memorystream.h b/dep/rapidjson/rapidjson/memorystream.h new file mode 100644 index 00000000000..99feae5d7f8 --- /dev/null +++ b/dep/rapidjson/rapidjson/memorystream.h @@ -0,0 +1,61 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return (src_ == end_) ? '\0' : *src_; } + Ch Take() { return (src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast<size_t>(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/dep/rapidjson/rapidjson/msinttypes/inttypes.h b/dep/rapidjson/rapidjson/msinttypes/inttypes.h new file mode 100644 index 00000000000..18111286bf5 --- /dev/null +++ b/dep/rapidjson/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include <inttypes.h> +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/dep/rapidjson/rapidjson/msinttypes/stdint.h b/dep/rapidjson/rapidjson/msinttypes/stdint.h new file mode 100644 index 00000000000..a26fff4bf45 --- /dev/null +++ b/dep/rapidjson/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include <stdint.h> + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include <limits.h> + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include <wchar.h> +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/dep/rapidjson/rapidjson/prettywriter.h b/dep/rapidjson/rapidjson/prettywriter.h new file mode 100644 index 00000000000..416dd492e34 --- /dev/null +++ b/dep/rapidjson/rapidjson/prettywriter.h @@ -0,0 +1,207 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of ouptut os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator> +class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> { +public: + typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator> Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + return Base::WriteString(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string<Ch>& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); + bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndObject(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray); + bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndArray(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + Base::os_->Put('\n'); + } + else + Base::os_->Put('\n'); + WriteIndent(); + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, indentChar_, count); + } + + Ch indentChar_; + unsigned indentCharCount_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/dep/rapidjson/rapidjson/rapidjson.h b/dep/rapidjson/rapidjson/rapidjson.h new file mode 100644 index 00000000000..f22130d3cb8 --- /dev/null +++ b/dep/rapidjson/rapidjson/rapidjson.h @@ -0,0 +1,654 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overriden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include <cstdlib> // malloc(), realloc(), free(), size_t +#include <cstring> // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in "<major>.<minor>.<patch>" string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 0 +#define RAPIDJSON_PATCH_VERSION 2 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#ifdef _MSC_VER +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include <stdint.h> +#include <inttypes.h> +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && !defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include <endian.h> +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || defined(_WIN64) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. Currently the default uses 4 bytes + alignment. User can customize by defining the RAPIDJSON_ALIGN function macro., +*/ +#ifndef RAPIDJSON_ALIGN +#if RAPIDJSON_64BIT == 1 +#define RAPIDJSON_ALIGN(x) ((x + 7u) & ~7u) +#else +#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2 optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible + processors. + + To enable these optimizations, two different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + \c RAPIDJSON_SSE42 takes precedence, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include <cassert> +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Adopt from boost +#ifndef RAPIDJSON_STATIC_ASSERT +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +RAPIDJSON_NAMESPACE_BEGIN +template <bool x> struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; +template<int x> struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y + +#if defined(__GNUC__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +//!@endcond + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT /* noexcept */ +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(x) new x +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Allocators and Encodings + +#include "allocators.h" +#include "encodings.h" + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template<typename Stream> +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits<StringStream>. + */ + enum { copyOptimization = 0 }; +}; + +//! Put N copies of a character to a stream. +template<typename Stream, typename Ch> +inline void PutN(Stream& stream, Ch c, size_t n) { + for (size_t i = 0; i < n; i++) + stream.Put(c); +} + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template <typename Encoding> +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast<size_t>(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template <typename Encoding> +struct StreamTraits<GenericStringStream<Encoding> > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream<UTF8<> > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template <typename Encoding> +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast<size_t>(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template <typename Encoding> +struct StreamTraits<GenericInsituStringStream<Encoding> > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream<UTF8<> > InsituStringStream; + +/////////////////////////////////////////////////////////////////////////////// +// Type + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/dep/rapidjson/rapidjson/reader.h b/dep/rapidjson/rapidjson/reader.h new file mode 100644 index 00000000000..c5ecf4be595 --- /dev/null +++ b/dep/rapidjson/rapidjson/reader.h @@ -0,0 +1,1452 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "rapidjson.h" +#include "encodings.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include <intrin.h> +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include <nmmintrin.h> +#elif defined(RAPIDJSON_SSE2) +#include <emmintrin.h> +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (HasParseError()) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include <stdexcept> // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template<typename Encoding = UTF8<>, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast<Override&>(*this).Default(); } + bool Bool(bool) { return static_cast<Override&>(*this).Default(); } + bool Int(int) { return static_cast<Override&>(*this).Default(); } + bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); } + bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); } + bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); } + bool Double(double) { return static_cast<Override&>(*this).Default(); } + bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); } + bool StartObject() { return static_cast<Override&>(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); } + bool StartArray() { return static_cast<Override&>(*this).Default(); } + bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template<typename Stream, int = StreamTraits<Stream>::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template<typename Stream> +class StreamLocalCopy<Stream, 1> { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template<typename Stream> +class StreamLocalCopy<Stream, 0> { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template<typename InputStream> +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy<InputStream> copy(is); + InputStream& s(copy.s); + + while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') + s.Take(); +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_load_si128((const __m128i *)&whitespace[0]); + + for (;; p += 16) { + const __m128i s = _mm_load_si128((const __m128i *)p); + const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + static const char whitespaces[4][17] = { + " ", + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", + "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r", + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"}; + + const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]); + const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]); + const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]); + const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]); + + for (;; p += 16) { + const __m128i s = _mm_load_si128((const __m128i *)p); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = (unsigned short)~_mm_movemask_epi8(x); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +#endif // RAPIDJSON_SSE2 + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator> +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template <unsigned parseFlags, typename InputStream, typename Handler> + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse<parseFlags>(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespace(is); + + if (is.Peek() == '\0') { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue<parseFlags>(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespace(is); + + if (is.Peek() != '\0') { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template <typename InputStream, typename Handler> + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse<kParseDefaultFlags>(is, handler); + } + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + // Parse object: { string : value, ... } + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (!handler.StartObject()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespace(is); + + if (is.Peek() == '}') { + is.Take(); + if (!handler.EndObject(0)) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (is.Peek() != '"') + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString<parseFlags>(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespace(is); + + if (is.Take() != ':') + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespace(is); + + ParseValue<parseFlags>(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespace(is); + + ++memberCount; + + switch (is.Take()) { + case ',': SkipWhitespace(is); break; + case '}': + if (!handler.EndObject(memberCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); + } + } + } + + // Parse array: [ value, ... ] + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (!handler.StartArray()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespace(is); + + if (is.Peek() == ']') { + is.Take(); + if (!handler.EndArray(0)) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue<parseFlags>(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespace(is); + + switch (is.Take()) { + case ',': SkipWhitespace(is); break; + case ']': + if (!handler.EndArray(elementCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + } + } + } + + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') { + if (!handler.Null()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') { + if (!handler.Bool(true)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') { + if (!handler.Bool(false)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); + } + + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template<typename InputStream> + unsigned ParseHex4(InputStream& is) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Take(); + codepoint <<= 4; + codepoint += static_cast<unsigned>(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, is.Tell() - 1); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + } + return codepoint; + } + + template <typename CharType> + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push<Ch>() = c; + ++length_; + } + size_t Length() const { return length_; } + Ch* Pop() { + return stack_.template Pop<Ch>(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack<StackAllocator>& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy<InputStream> copy(is); + InputStream& s(copy.s); + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head; + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream<typename TargetEncoding::Ch> stackStream(stack_); + ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast<SizeType>(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (!success) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream> + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + RAPIDJSON_ASSERT(is.Peek() == '\"'); + is.Take(); // Skip '\"' + + for (;;) { + Ch c = is.Peek(); + if (c == '\\') { // Escape + is.Take(); + Ch e = is.Take(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) { + os.Put(escape[(unsigned char)e]); + } + else if (e == 'u') { // Unicode + unsigned codepoint = ParseHex4(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { + // Handle UTF-16 surrogate pair + if (is.Take() != '\\' || is.Take() != 'u') + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); + unsigned codepoint2 = ParseHex4(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1); + } + else if (c == '"') { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1); + else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1); + else { + if (parseFlags & kParseValidateEncodingFlag ? + !Transcoder<SEncoding, TEncoding>::Validate(is, os) : + !Transcoder<SEncoding, TEncoding>::Transcode(is, os)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell()); + } + } + } + + template<typename InputStream, bool backup> + class NumberStream; + + template<typename InputStream> + class NumberStream<InputStream, false> { + public: + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const char* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template<typename InputStream> + class NumberStream<InputStream, true> : public NumberStream<InputStream, false> { + typedef NumberStream<InputStream, false> Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : NumberStream<InputStream, false>(reader, is), stackStream(reader.stack_) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put((char)Base::is.Peek()); + return Base::is.Take(); + } + + size_t Length() { return stackStream.Length(); } + + const char* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream<char> stackStream; + }; + + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseNumber(InputStream& is, Handler& handler) { + internal::StreamLocalCopy<InputStream> copy(is); + NumberStream<InputStream, (parseFlags & kParseFullPrecisionFlag) != 0> s(*this, copy.s); + + // Parse minus + bool minus = false; + if (s.Peek() == '-') { + minus = true; + s.Take(); + } + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (s.Peek() == '0') { + i = 0; + s.TakePush(); + } + else if (s.Peek() >= '1' && s.Peek() <= '9') { + i = static_cast<unsigned>(s.TakePush() - '0'); + + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 214748364) { // 2^31 = 2147483648 + if (i != 214748364 || s.Peek() > '8') { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); + significandDigit++; + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i >= 429496729) { // 2^32 - 1 = 4294967295 + if (i != 429496729 || s.Peek() > '5') { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); + significandDigit++; + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + double d = 0.0; + if (use64bit) { + if (minus) + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808 + if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') { + d = i64; + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); + significandDigit++; + } + else + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615 + if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') { + d = i64; + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0 + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (s.Peek() == '.') { + s.Take(); + decimalPosition = s.Length(); + + if (!(s.Peek() >= '0' && s.Peek() <= '9')) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = (double)i64; +#else + // Use double to store significand in 32-bit architecture + d = use64bit ? (double)i64 : (double)i; +#endif + useDouble = true; + } + + while (s.Peek() >= '0' && s.Peek() <= '9') { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (d > 0.0) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (s.Peek() == 'e' || s.Peek() == 'E') { + if (!useDouble) { + d = use64bit ? i64 : i; + useDouble = true; + } + s.Take(); + + bool expMinus = false; + if (s.Peek() == '+') + s.Take(); + else if (s.Peek() == '-') { + s.Take(); + expMinus = true; + } + + if (s.Peek() >= '0' && s.Peek() <= '9') { + exp = s.Take() - '0'; + if (expMinus) { + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp >= 214748364) { // Issue #313: prevent overflow exponent + while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (s.Peek() >= '0' && s.Peek() <= '9') { + exp = exp * 10 + (s.Take() - '0'); + if (exp > maxExp) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell()); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + size_t length = s.Length(); + const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + cont = handler.Double(minus ? -d : d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(-(int64_t)i64); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(-(int)i); + else + cont = handler.Uint(i); + } + } + if (!cont) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse any JSON value + template<unsigned parseFlags, typename InputStream, typename Handler> + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull <parseFlags>(is, handler); break; + case 't': ParseTrue <parseFlags>(is, handler); break; + case 'f': ParseFalse <parseFlags>(is, handler); break; + case '"': ParseString<parseFlags>(is, handler); break; + case '{': ParseObject<parseFlags>(is, handler); break; + case '[': ParseArray <parseFlags>(is, handler); break; + default : ParseNumber<parseFlags>(is, handler); + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingStartState = 0, + IterativeParsingFinishState, + IterativeParsingErrorState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberValueState, + IterativeParsingMemberDelimiterState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingElementDelimiterState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState, + + cIterativeParsingStateCount + }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || unsigned(c) < 256) + return (Token)tokenMap[(unsigned char)c]; + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + } + }; // End of G + + return (IterativeParsingState)G[state][token]; + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template <unsigned parseFlags, typename InputStream, typename Handler> + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemeberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push<SizeType>(1) = n; + // Initialize and push the member/element count. + *stack_.template Push<SizeType>(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString<parseFlags>(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue<parseFlags>(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue<parseFlags>(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Get member count. + SizeType c = *stack_.template Pop<SizeType>(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Get element count. + SizeType c = *stack_.template Pop<SizeType>(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue<parseFlags>(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template <typename InputStream> + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); + case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + } + } + + template <unsigned parseFlags, typename InputStream, typename Handler> + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespace(is); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespace(is); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader<UTF8<>, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/dep/rapidjson/rapidjson/stringbuffer.h b/dep/rapidjson/rapidjson/stringbuffer.h new file mode 100644 index 00000000000..1c9c80b7993 --- /dev/null +++ b/dep/rapidjson/rapidjson/stringbuffer.h @@ -0,0 +1,93 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "rapidjson.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include <utility> // std::move +#endif + +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template <typename Encoding, typename Allocator = CrtAllocator> +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push<Ch>() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push<Ch>() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop<Ch>(1); + } + Ch* Push(size_t count) { return stack_.template Push<Ch>(count); } + void Pop(size_t count) { stack_.template Pop<Ch>(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push<Ch>() = '\0'; + stack_.template Pop<Ch>(1); + + return stack_.template Bottom<Ch>(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack<Allocator> stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer<UTF8<> > StringBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) { + std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/dep/rapidjson/rapidjson/writer.h b/dep/rapidjson/rapidjson/writer.h new file mode 100644 index 00000000000..e1eea38b987 --- /dev/null +++ b/dep/rapidjson/rapidjson/writer.h @@ -0,0 +1,395 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include <new> // placement new + +#if RAPIDJSON_HAS_STDSTRING +#include <string> +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), hasRoot_(false) {} + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer<OutputStream> writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return WriteNull(); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); } + bool Int(int i) { Prefix(kNumberType); return WriteInt(i); } + bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); } + bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + return WriteString(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string<Ch>& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push<Level>()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); + level_stack_.template Pop<Level>(1); + bool ret = WriteEndObject(); + if (level_stack_.Empty()) // end of json text + os_->Flush(); + return ret; + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push<Level>()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray); + level_stack_.template Pop<Level>(1); + bool ret = WriteEndArray(); + if (level_stack_.Empty()) // end of json text + os_->Flush(); + return ret; + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + static const size_t kDefaultLevelDepth = 32; + + bool WriteNull() { + os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e'); + } + else { + os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + for (const char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + for (char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteDouble(double d) { + char buffer[25]; + char* end = internal::dtoa(d, buffer); + for (char* p = buffer; p != end; ++p) + os_->Put(*p); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + os_->Put('\"'); + GenericStringStream<SourceEncoding> is(str); + while (is.Tell() < length) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + os_->Put('\\'); + os_->Put('u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + os_->Put(hexDigits[(codepoint >> 12) & 15]); + os_->Put(hexDigits[(codepoint >> 8) & 15]); + os_->Put(hexDigits[(codepoint >> 4) & 15]); + os_->Put(hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + os_->Put(hexDigits[(lead >> 12) & 15]); + os_->Put(hexDigits[(lead >> 8) & 15]); + os_->Put(hexDigits[(lead >> 4) & 15]); + os_->Put(hexDigits[(lead ) & 15]); + os_->Put('\\'); + os_->Put('u'); + os_->Put(hexDigits[(trail >> 12) & 15]); + os_->Put(hexDigits[(trail >> 8) & 15]); + os_->Put(hexDigits[(trail >> 4) & 15]); + os_->Put(hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) { + is.Take(); + os_->Put('\\'); + os_->Put(escape[(unsigned char)c]); + if (escape[(unsigned char)c] == 'u') { + os_->Put('0'); + os_->Put('0'); + os_->Put(hexDigits[(unsigned char)c >> 4]); + os_->Put(hexDigits[(unsigned char)c & 0xF]); + } + } + else + if (!Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_)) + return false; + } + os_->Put('\"'); + return true; + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + void Prefix(Type type) { + (void)type; + if (level_stack_.GetSize() != 0) { // this value is not at root + Level* level = level_stack_.template Top<Level>(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + OutputStream* os_; + internal::Stack<StackAllocator> level_stack_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer<StringBuffer>::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(11 - (end - buffer)); + return true; +} + +template<> +inline bool Writer<StringBuffer>::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(10 - (end - buffer)); + return true; +} + +template<> +inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(21 - (end - buffer)); + return true; +} + +template<> +inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(20 - (end - buffer)); + return true; +} + +template<> +inline bool Writer<StringBuffer>::WriteDouble(double d) { + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer); + os_->Pop(25 - (end - buffer)); + return true; +} + +RAPIDJSON_NAMESPACE_END + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/sql/updates/world/2016_03_23_00_world.sql b/sql/updates/world/2016_03_23_00_world.sql new file mode 100644 index 00000000000..b5a31f35526 --- /dev/null +++ b/sql/updates/world/2016_03_23_00_world.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `npc_vendor` WHERE `item` IN (2512,2515,3030,3464,9399,11285,19316,18042,12654,28053,24417,28056,30611,31949,33803,34581,31737,30319,41165,41586,52021,2516,8067,4960,2519,8068,5568,3033,8069,3465,10512,11284,10513,19317,15997,11630,13377,28060,23772,28061,30612,32883,32882,23773,34582,31735,41164,41584,52020); +DELETE FROM `creature_loot_template` WHERE `Item` IN (2512,2515,3030,3464,9399,11285,19316,18042,12654,28053,24417,28056,30611,31949,33803,34581,31737,30319,41165,41586,52021,2516,8067,4960,2519,8068,5568,3033,8069,3465,10512,11284,10513,19317,15997,11630,13377,28060,23772,28061,30612,32883,32882,23773,34582,31735,41164,41584,52020); +DELETE FROM `gameobject_loot_template` WHERE `Item` IN (2512,2515,3030,3464,9399,11285,19316,18042,12654,28053,24417,28056,30611,31949,33803,34581,31737,30319,41165,41586,52021,2516,8067,4960,2519,8068,5568,3033,8069,3465,10512,11284,10513,19317,15997,11630,13377,28060,23772,28061,30612,32883,32882,23773,34582,31735,41164,41584,52020); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 6f13dc821a9..4250df6d1f1 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -30,6 +30,8 @@ endif (USE_COREPCH) GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) +add_definitions(-DTRINITY_API_EXPORT_COMMON) + add_library(common ${PRIVATE_SOURCES} ${PRIVATE_PCH_SOURCE} @@ -78,6 +80,18 @@ set_target_properties(common FOLDER "server") +if( BUILD_SHARED_LIBS ) + if( UNIX ) + install(TARGETS common + LIBRARY + DESTINATION lib) + elseif( WIN32 ) + install(TARGETS common + RUNTIME + DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() +endif() + # Generate precompiled header if (USE_COREPCH) add_cxx_pch(common ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) diff --git a/src/common/Collision/BoundingIntervalHierarchy.h b/src/common/Collision/BoundingIntervalHierarchy.h index 22ea36ec2e6..d84ee3f6bf3 100644 --- a/src/common/Collision/BoundingIntervalHierarchy.h +++ b/src/common/Collision/BoundingIntervalHierarchy.h @@ -67,7 +67,7 @@ struct AABound Copyright (c) 2003-2007 Christopher Kulla */ -class BIH +class TC_COMMON_API BIH { private: void init_empty() diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h index 0f18bb265f8..85707efebd2 100644 --- a/src/common/Collision/DynamicTree.h +++ b/src/common/Collision/DynamicTree.h @@ -31,7 +31,7 @@ namespace G3D class GameObjectModel; struct DynTreeImpl; -class DynamicMapTree +class TC_COMMON_API DynamicMapTree { DynTreeImpl *impl; diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h index 1e64551956c..35437b7b816 100644 --- a/src/common/Collision/Management/IVMapManager.h +++ b/src/common/Collision/Management/IVMapManager.h @@ -42,7 +42,7 @@ namespace VMAP #define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case //=========================================================== - class IVMapManager + class TC_COMMON_API IVMapManager { private: bool iEnableLineOfSightCalc; diff --git a/src/common/Collision/Management/MMapFactory.h b/src/common/Collision/Management/MMapFactory.h index edd074fc93d..6dda7a40a22 100644 --- a/src/common/Collision/Management/MMapFactory.h +++ b/src/common/Collision/Management/MMapFactory.h @@ -38,7 +38,7 @@ namespace MMAP // static class // holds all mmap global data // access point to MMapManager singleton - class MMapFactory + class TC_COMMON_API MMapFactory { public: static MMapManager* createOrGetMMapManager(); diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index 45a60d88dc7..8aa28ec7ab4 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -38,7 +38,7 @@ namespace MMAP typedef std::set<uint32> TerrainSet; - struct NavMeshHolder + struct TC_COMMON_API NavMeshHolder { // Pre-built navMesh dtNavMesh* navMesh; @@ -49,7 +49,7 @@ namespace MMAP MMapTileSet loadedTileRefs; }; - struct PhasedTile + struct TC_COMMON_API PhasedTile { unsigned char* data; MmapTileHeader fileHeader; @@ -62,7 +62,7 @@ namespace MMAP typedef std::unordered_map<uint32, TerrainSet> TerrainSetMap; - class MMapData + class TC_COMMON_API MMapData { public: MMapData(dtNavMesh* mesh, uint32 mapId); @@ -90,7 +90,7 @@ namespace MMAP // singleton class // holds all all access to mmap loading unloading and meshes - class MMapManager + class TC_COMMON_API MMapManager { public: MMapManager() : loadedTiles(0), thread_safe_environment(true) {} diff --git a/src/common/Collision/Management/VMapFactory.h b/src/common/Collision/Management/VMapFactory.h index 1a45bd5094b..a730fa12ef2 100644 --- a/src/common/Collision/Management/VMapFactory.h +++ b/src/common/Collision/Management/VMapFactory.h @@ -29,7 +29,7 @@ namespace VMAP { //=========================================================== - class VMapFactory + class TC_COMMON_API VMapFactory { public: static IVMapManager* createOrGetVMapManager(); diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h index 4125970f757..a3b383bdc10 100644 --- a/src/common/Collision/Management/VMapManager2.h +++ b/src/common/Collision/Management/VMapManager2.h @@ -51,7 +51,7 @@ namespace VMAP class StaticMapTree; class WorldModel; - class ManagedModel + class TC_COMMON_API ManagedModel { public: ManagedModel() : iModel(nullptr), iRefCount(0) { } @@ -75,7 +75,7 @@ namespace VMAP VMAP_DISABLE_LIQUIDSTATUS = 0x8 }; - class VMapManager2 : public IVMapManager + class TC_COMMON_API VMapManager2 : public IVMapManager { protected: // Tree to check collision diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h index 58b58bf3073..0227a982b4c 100644 --- a/src/common/Collision/Maps/MapTree.h +++ b/src/common/Collision/Maps/MapTree.h @@ -29,7 +29,7 @@ namespace VMAP class GroupModel; class VMapManager2; - struct LocationInfo + struct TC_COMMON_API LocationInfo { LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { } const ModelInstance* hitInstance; @@ -37,7 +37,7 @@ namespace VMAP float ground_Z; }; - class StaticMapTree + class TC_COMMON_API StaticMapTree { typedef std::unordered_map<uint32, bool> loadedTileMap; typedef std::unordered_map<uint32, uint32> loadedSpawnMap; @@ -87,7 +87,7 @@ namespace VMAP StaticMapTree& operator=(StaticMapTree const& right) = delete; }; - struct AreaInfo + struct TC_COMMON_API AreaInfo { AreaInfo(): result(false), ground_Z(-G3D::finf()), flags(0), adtId(0), rootId(0), groupId(0) { } diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h index 1e2dc1924f1..74111f69910 100644 --- a/src/common/Collision/Maps/TileAssembler.h +++ b/src/common/Collision/Maps/TileAssembler.h @@ -35,7 +35,7 @@ namespace VMAP */ //=============================================== - class ModelPosition + class TC_COMMON_API ModelPosition { private: G3D::Matrix3 iRotation; @@ -55,7 +55,7 @@ namespace VMAP typedef std::map<uint32, ModelSpawn> UniqueEntryMap; typedef std::multimap<uint32, uint32> TileMap; - struct MapSpawns + struct TC_COMMON_API MapSpawns { UniqueEntryMap UniqueEntries; TileMap TileEntries; @@ -64,7 +64,7 @@ namespace VMAP typedef std::map<uint32, MapSpawns*> MapData; //=============================================== - struct GroupModel_Raw + struct TC_COMMON_API GroupModel_Raw { uint32 mogpflags; uint32 GroupWMOID; @@ -82,7 +82,7 @@ namespace VMAP bool Read(FILE* f); }; - struct WorldModel_Raw + struct TC_COMMON_API WorldModel_Raw { uint32 RootWMOID; std::vector<GroupModel_Raw> groupsArray; @@ -90,7 +90,7 @@ namespace VMAP bool Read(const char * path); }; - class TileAssembler + class TC_COMMON_API TileAssembler { private: std::string iDestDir; diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 7834f53c63a..37f11af20ac 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -35,7 +35,7 @@ namespace VMAP class GameObject; struct GameObjectDisplayInfoEntry; -class GameObjectModelOwnerBase +class TC_COMMON_API GameObjectModelOwnerBase { public: virtual bool IsSpawned() const { return false; } @@ -47,7 +47,7 @@ public: virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const { } }; -class GameObjectModel /*, public Intersectable*/ +class TC_COMMON_API GameObjectModel /*, public Intersectable*/ { GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { } public: @@ -84,6 +84,6 @@ private: std::unique_ptr<GameObjectModelOwnerBase> owner; }; -void LoadGameObjectModelList(std::string const& dataPath); +TC_COMMON_API void LoadGameObjectModelList(std::string const& dataPath); #endif // _GAMEOBJECT_MODEL_H diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h index d101630d1e9..84a41b15ce6 100644 --- a/src/common/Collision/Models/ModelInstance.h +++ b/src/common/Collision/Models/ModelInstance.h @@ -39,7 +39,7 @@ namespace VMAP MOD_HAS_BOUND = 1<<2 }; - class ModelSpawn + class TC_COMMON_API ModelSpawn { public: //mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name @@ -60,7 +60,7 @@ namespace VMAP static bool writeToFile(FILE* rw, const ModelSpawn &spawn); }; - class ModelInstance: public ModelSpawn + class TC_COMMON_API ModelInstance: public ModelSpawn { public: ModelInstance(): iInvScale(0.0f), iModel(nullptr) { } diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h index 39787f6c664..bfc0367627f 100644 --- a/src/common/Collision/Models/WorldModel.h +++ b/src/common/Collision/Models/WorldModel.h @@ -33,7 +33,7 @@ namespace VMAP struct AreaInfo; struct LocationInfo; - class MeshTriangle + class TC_COMMON_API MeshTriangle { public: MeshTriangle() : idx0(0), idx1(0), idx2(0) { } @@ -44,7 +44,7 @@ namespace VMAP uint32 idx2; }; - class WmoLiquid + class TC_COMMON_API WmoLiquid { public: WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type); @@ -70,7 +70,7 @@ namespace VMAP }; /*! holding additional info for WMO group files */ - class GroupModel + class TC_COMMON_API GroupModel { public: GroupModel() : iBound(), iMogpFlags(0), iGroupWMOID(0), iLiquid(NULL) { } @@ -103,7 +103,7 @@ namespace VMAP }; /*! Holds a model (converted M2 or WMO) in its original coordinate space */ - class WorldModel + class TC_COMMON_API WorldModel { public: WorldModel(): RootWMOID(0) { } diff --git a/src/common/Collision/RegularGrid.h b/src/common/Collision/RegularGrid.h index a582f3c081c..2f3819c872c 100644 --- a/src/common/Collision/RegularGrid.h +++ b/src/common/Collision/RegularGrid.h @@ -20,7 +20,7 @@ class NodeCreatorFunc = NodeCreator<Node>, /*class BoundsFunc = BoundsTrait<T>,*/ class PositionFunc = PositionTrait<T> > -class RegularGrid2D +class TC_COMMON_API RegularGrid2D { public: diff --git a/src/common/Collision/VMapTools.h b/src/common/Collision/VMapTools.h index 54b8fcd0032..86ec498f72a 100644 --- a/src/common/Collision/VMapTools.h +++ b/src/common/Collision/VMapTools.h @@ -22,6 +22,8 @@ #include <G3D/CollisionDetection.h> #include <G3D/AABox.h> +#include "Define.h" + #include "NodeValueAccess.h" /** @@ -48,7 +50,7 @@ namespace VMAP //============================================================== //============================================================== - class MyCollisionDetection + class TC_COMMON_API MyCollisionDetection { private: public: diff --git a/src/common/Common.cpp b/src/common/Common.cpp index 4555f00a76c..eb4316edd69 100644 --- a/src/common/Common.cpp +++ b/src/common/Common.cpp @@ -18,7 +18,7 @@ #include "Common.h" -char const* localeNames[TOTAL_LOCALES] = +TC_COMMON_API char const* localeNames[TOTAL_LOCALES] = { "enUS", "koKR", diff --git a/src/common/Common.h b/src/common/Common.h index ad48358ca8d..a6e2a8635cf 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -135,15 +135,15 @@ const uint8 OLD_TOTAL_LOCALES = 9; /// @todo convert in simple system #define MAX_LOCALES 11 -extern char const* localeNames[TOTAL_LOCALES]; +extern "C" TC_COMMON_API char const* localeNames[TOTAL_LOCALES]; -LocaleConstant GetLocaleByName(const std::string& name); +TC_COMMON_API LocaleConstant GetLocaleByName(const std::string& name); typedef std::vector<std::string> StringVector; #pragma pack(push, 1) -struct LocalizedString +struct TC_COMMON_API LocalizedString { char const* Str[TOTAL_LOCALES]; }; diff --git a/src/common/Configuration/BuiltInConfig.h b/src/common/Configuration/BuiltInConfig.h index 4ae4ed40189..0ffa059bc41 100644 --- a/src/common/Configuration/BuiltInConfig.h +++ b/src/common/Configuration/BuiltInConfig.h @@ -19,6 +19,7 @@ #define BUILT_IN_CONFIG_H #include <string> +#include "Define.h" /// Provides helper functions to access built-in values /// which can be overwritten in config @@ -26,16 +27,16 @@ namespace BuiltInConfig { /// Returns the CMake command when any is specified in the config, /// returns the built-in path otherwise - std::string GetCMakeCommand(); + TC_COMMON_API std::string GetCMakeCommand(); /// Returns the build directory path when any is specified in the config, /// returns the built-in one otherwise - std::string GetBuildDirectory(); + TC_COMMON_API std::string GetBuildDirectory(); /// Returns the source directory path when any is specified in the config, /// returns the built-in one otherwise - std::string GetSourceDirectory(); + TC_COMMON_API std::string GetSourceDirectory(); /// Returns the path to the mysql executable (`mysql`) when any is specified /// in the config, returns the built-in one otherwise - std::string GetMySQLExecutable(); + TC_COMMON_API std::string GetMySQLExecutable(); } // namespace BuiltInConfig diff --git a/src/common/Configuration/Config.h b/src/common/Configuration/Config.h index c1c50e8f1e8..d8dfeb230a7 100644 --- a/src/common/Configuration/Config.h +++ b/src/common/Configuration/Config.h @@ -19,12 +19,14 @@ #ifndef CONFIG_H #define CONFIG_H +#include "Define.h" + #include <string> #include <list> #include <mutex> #include <boost/property_tree/ptree.hpp> -class ConfigMgr +class TC_COMMON_API ConfigMgr { ConfigMgr() { } ~ConfigMgr() { } diff --git a/src/common/Cryptography/ARC4.h b/src/common/Cryptography/ARC4.h index 5b5fbf4a020..df412944ef6 100644 --- a/src/common/Cryptography/ARC4.h +++ b/src/common/Cryptography/ARC4.h @@ -22,7 +22,7 @@ #include <openssl/evp.h> #include "Define.h" -class ARC4 +class TC_COMMON_API ARC4 { public: ARC4(uint32 len); diff --git a/src/common/Cryptography/Authentication/PacketCrypt.h b/src/common/Cryptography/Authentication/PacketCrypt.h index 9e13cb02529..8af6c7ae926 100644 --- a/src/common/Cryptography/Authentication/PacketCrypt.h +++ b/src/common/Cryptography/Authentication/PacketCrypt.h @@ -22,7 +22,7 @@ class BigNumber; -class PacketCrypt +class TC_COMMON_API PacketCrypt { public: PacketCrypt(uint32 rc4InitSize); diff --git a/src/common/Cryptography/Authentication/WorldPacketCrypt.h b/src/common/Cryptography/Authentication/WorldPacketCrypt.h index 2b19fb54188..d296b049af2 100644 --- a/src/common/Cryptography/Authentication/WorldPacketCrypt.h +++ b/src/common/Cryptography/Authentication/WorldPacketCrypt.h @@ -23,7 +23,7 @@ class BigNumber; -class WorldPacketCrypt : public PacketCrypt +class TC_COMMON_API WorldPacketCrypt : public PacketCrypt { public: WorldPacketCrypt(); diff --git a/src/common/Cryptography/BigNumber.h b/src/common/Cryptography/BigNumber.h index 56fc2196fde..baf338552d0 100644 --- a/src/common/Cryptography/BigNumber.h +++ b/src/common/Cryptography/BigNumber.h @@ -25,7 +25,7 @@ struct bignum_st; -class BigNumber +class TC_COMMON_API BigNumber { public: BigNumber(); diff --git a/src/common/Cryptography/HmacHash.cpp b/src/common/Cryptography/HmacHash.cpp index d9bb28d3e0b..bd50a2fc708 100644 --- a/src/common/Cryptography/HmacHash.cpp +++ b/src/common/Cryptography/HmacHash.cpp @@ -62,5 +62,5 @@ uint8* HmacHash<HashCreator, DigestLength>::ComputeHash(BigNumber* bn) return _digest; } -template class HmacHash<EVP_sha1, SHA_DIGEST_LENGTH>; -template class HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH>; +template class TC_COMMON_API HmacHash<EVP_sha1, SHA_DIGEST_LENGTH>; +template class TC_COMMON_API HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH>; diff --git a/src/common/Cryptography/HmacHash.h b/src/common/Cryptography/HmacHash.h index f61bf251abc..5156d03a18a 100644 --- a/src/common/Cryptography/HmacHash.h +++ b/src/common/Cryptography/HmacHash.h @@ -31,7 +31,7 @@ class BigNumber; typedef EVP_MD const* (*HashCreateFn)(); template<HashCreateFn HashCreator, uint32 DigestLength> -class HmacHash +class TC_COMMON_API HmacHash { public: HmacHash(uint32 len, uint8 const* seed); diff --git a/src/common/Cryptography/OpenSSLCrypto.h b/src/common/Cryptography/OpenSSLCrypto.h index df1b14b5eda..65155df9af8 100644 --- a/src/common/Cryptography/OpenSSLCrypto.h +++ b/src/common/Cryptography/OpenSSLCrypto.h @@ -18,6 +18,8 @@ #ifndef OPENSSL_CRYPTO_H #define OPENSSL_CRYPTO_H +#include "Define.h" + /** * A group of functions which setup openssl crypto module to work properly in multithreaded enviroment * If not setup properly - it will crash @@ -25,9 +27,9 @@ namespace OpenSSLCrypto { /// Needs to be called before threads using openssl are spawned - void threadsSetup(); + TC_COMMON_API void threadsSetup(); /// Needs to be called after threads using openssl are despawned - void threadsCleanup(); + TC_COMMON_API void threadsCleanup(); } -#endif
\ No newline at end of file +#endif diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h index 944350265f4..f943e1d2de8 100644 --- a/src/common/Cryptography/SHA1.h +++ b/src/common/Cryptography/SHA1.h @@ -26,7 +26,7 @@ class BigNumber; -class SHA1Hash +class TC_COMMON_API SHA1Hash { public: typedef std::integral_constant<uint32, SHA_DIGEST_LENGTH> DigestLength; diff --git a/src/common/Cryptography/SHA256.h b/src/common/Cryptography/SHA256.h index 33f23f639a4..22d8a9870cf 100644 --- a/src/common/Cryptography/SHA256.h +++ b/src/common/Cryptography/SHA256.h @@ -25,7 +25,7 @@ class BigNumber; -class SHA256Hash +class TC_COMMON_API SHA256Hash { public: typedef std::integral_constant<uint32, SHA256_DIGEST_LENGTH> DigestLength; diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h index 37d247ada82..e4b3563ca96 100644 --- a/src/common/Debugging/Errors.h +++ b/src/common/Debugging/Errors.h @@ -23,18 +23,18 @@ namespace Trinity { - DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; - DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6); + DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; + DECLSPEC_NORETURN TC_COMMON_API void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6); - DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5); + DECLSPEC_NORETURN TC_COMMON_API void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5); - DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; + DECLSPEC_NORETURN TC_COMMON_API void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; - DECLSPEC_NORETURN void Abort(char const* file, int line, char const* function) ATTR_NORETURN; + DECLSPEC_NORETURN TC_COMMON_API void Abort(char const* file, int line, char const* function) ATTR_NORETURN; - void Warning(char const* file, int line, char const* function, char const* message); + TC_COMMON_API void Warning(char const* file, int line, char const* function, char const* message); - DECLSPEC_NORETURN void AbortHandler(int sigval) ATTR_NORETURN; + DECLSPEC_NORETURN TC_COMMON_API void AbortHandler(int sigval) ATTR_NORETURN; } // namespace Trinity diff --git a/src/common/Define.h b/src/common/Define.h index 061a6bc2f5e..07b79252074 100644 --- a/src/common/Define.h +++ b/src/common/Define.h @@ -95,6 +95,45 @@ #endif #endif //COMPILER == COMPILER_GNU +#ifdef TRINITY_API_USE_DYNAMIC_LINKING +# if COMPILER == COMPILER_MICROSOFT +# define TC_API_EXPORT __declspec(dllexport) +# define TC_API_IMPORT __declspec(dllimport) +# elif COMPILER == COMPILER_GNU +# define TC_API_EXPORT __attribute__((visibility("default"))) +# define TC_API_IMPORT +# else +# error compiler not supported! +# endif +#else +# define TC_API_EXPORT +# define TC_API_IMPORT +#endif + +#ifdef TRINITY_API_EXPORT_COMMON +# define TC_COMMON_API TC_API_EXPORT +#else +# define TC_COMMON_API TC_API_IMPORT +#endif + +#ifdef TRINITY_API_EXPORT_DATABASE +# define TC_DATABASE_API TC_API_EXPORT +#else +# define TC_DATABASE_API TC_API_IMPORT +#endif + +#ifdef TRINITY_API_EXPORT_SHARED +# define TC_SHARED_API TC_API_EXPORT +#else +# define TC_SHARED_API TC_API_IMPORT +#endif + +#ifdef TRINITY_API_EXPORT_GAME +# define TC_GAME_API TC_API_EXPORT +#else +# define TC_GAME_API TC_API_IMPORT +#endif + #define UI64FMTD "%" PRIu64 #define UI64LIT(N) UINT64_C(N) diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp index 3dd6b543013..2b4537db448 100644 --- a/src/common/GitRevision.cpp +++ b/src/common/GitRevision.cpp @@ -1,5 +1,4 @@ #include "GitRevision.h" -#include "CompilerDefs.h" #include "revision_data.h" char const* GitRevision::GetHash() diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h index c65c8fb6cff..ffe8884eb0a 100644 --- a/src/common/GitRevision.h +++ b/src/common/GitRevision.h @@ -19,23 +19,24 @@ #define __GITREVISION_H__ #include <string> +#include "Define.h" namespace GitRevision { - char const* GetHash(); - char const* GetDate(); - char const* GetBranch(); - char const* GetCMakeCommand(); - char const* GetBuildDirectory(); - char const* GetSourceDirectory(); - char const* GetMySQLExecutable(); - char const* GetFullDatabase(); - char const* GetHotfixesDatabase(); - char const* GetFullVersion(); - char const* GetCompanyNameStr(); - char const* GetLegalCopyrightStr(); - char const* GetFileVersionStr(); - char const* GetProductVersionStr(); + TC_COMMON_API char const* GetHash(); + TC_COMMON_API char const* GetDate(); + TC_COMMON_API char const* GetBranch(); + TC_COMMON_API char const* GetCMakeCommand(); + TC_COMMON_API char const* GetBuildDirectory(); + TC_COMMON_API char const* GetSourceDirectory(); + TC_COMMON_API char const* GetMySQLExecutable(); + TC_COMMON_API char const* GetFullDatabase(); + TC_COMMON_API char const* GetHotfixesDatabase(); + TC_COMMON_API char const* GetFullVersion(); + TC_COMMON_API char const* GetCompanyNameStr(); + TC_COMMON_API char const* GetLegalCopyrightStr(); + TC_COMMON_API char const* GetFileVersionStr(); + TC_COMMON_API char const* GetProductVersionStr(); } #endif diff --git a/src/common/Logging/Appender.h b/src/common/Logging/Appender.h index f0bfe423a66..22fe1112239 100644 --- a/src/common/Logging/Appender.h +++ b/src/common/Logging/Appender.h @@ -59,7 +59,7 @@ enum AppenderFlags APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender }; -struct LogMessage +struct TC_COMMON_API LogMessage { LogMessage(LogLevel _level, std::string const& _type, std::string&& _text) : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL)) @@ -85,7 +85,7 @@ struct LogMessage } }; -class Appender +class TC_COMMON_API Appender { public: Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE); @@ -123,7 +123,7 @@ Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, Appe return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs)); } -class InvalidAppenderArgsException : public std::length_error +class TC_COMMON_API InvalidAppenderArgsException : public std::length_error { public: explicit InvalidAppenderArgsException(std::string const& message) : std::length_error(message) { } diff --git a/src/common/Logging/AppenderConsole.h b/src/common/Logging/AppenderConsole.h index 5d7eae36b40..96d17207158 100644 --- a/src/common/Logging/AppenderConsole.h +++ b/src/common/Logging/AppenderConsole.h @@ -42,7 +42,7 @@ enum ColorTypes const uint8 MaxColors = uint8(WHITE) + 1; -class AppenderConsole : public Appender +class TC_COMMON_API AppenderConsole : public Appender { public: typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex; diff --git a/src/common/Logging/AppenderFile.h b/src/common/Logging/AppenderFile.h index 9ba5d59259c..956b7a70b93 100644 --- a/src/common/Logging/AppenderFile.h +++ b/src/common/Logging/AppenderFile.h @@ -21,7 +21,7 @@ #include <atomic> #include "Appender.h" -class AppenderFile : public Appender +class TC_COMMON_API AppenderFile : public Appender { public: typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex; diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h index 062f14d525c..6460e404c90 100644 --- a/src/common/Logging/Log.h +++ b/src/common/Logging/Log.h @@ -34,7 +34,7 @@ #define LOGGER_ROOT "root" -class Log +class TC_COMMON_API Log { typedef std::unordered_map<std::string, Logger> LoggerMap; diff --git a/src/common/Logging/LogOperation.h b/src/common/Logging/LogOperation.h index 618629b5423..56e2307d492 100644 --- a/src/common/Logging/LogOperation.h +++ b/src/common/Logging/LogOperation.h @@ -19,11 +19,12 @@ #define LOGOPERATION_H #include <memory> +#include "Define.h" class Logger; struct LogMessage; -class LogOperation +class TC_COMMON_API LogOperation { public: LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg) diff --git a/src/common/Logging/Logger.h b/src/common/Logging/Logger.h index 67eab4295a4..4ac2e4494cc 100644 --- a/src/common/Logging/Logger.h +++ b/src/common/Logging/Logger.h @@ -20,7 +20,7 @@ #include "Appender.h" -class Logger +class TC_COMMON_API Logger { public: Logger(); diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h index 9818712c0cb..e8a40ede4c7 100644 --- a/src/common/Utilities/Containers.h +++ b/src/common/Utilities/Containers.h @@ -20,6 +20,7 @@ #include "Define.h" #include "Random.h" +#include "Util.h" #include <algorithm> #include <functional> #include <list> diff --git a/src/common/Utilities/EventMap.h b/src/common/Utilities/EventMap.h index a1aaa9af269..bb40980181d 100644 --- a/src/common/Utilities/EventMap.h +++ b/src/common/Utilities/EventMap.h @@ -22,7 +22,7 @@ #include "Duration.h" #include "Util.h" -class EventMap +class TC_COMMON_API EventMap { /** * Internal storage type. diff --git a/src/common/Utilities/EventProcessor.h b/src/common/Utilities/EventProcessor.h index e5eafed79b9..e10558e6a21 100644 --- a/src/common/Utilities/EventProcessor.h +++ b/src/common/Utilities/EventProcessor.h @@ -25,7 +25,7 @@ // Note. All times are in milliseconds here. -class BasicEvent +class TC_COMMON_API BasicEvent { public: BasicEvent() @@ -55,7 +55,7 @@ class BasicEvent typedef std::multimap<uint64, BasicEvent*> EventList; -class EventProcessor +class TC_COMMON_API EventProcessor { public: EventProcessor(); diff --git a/src/common/Utilities/Random.h b/src/common/Utilities/Random.h index dee0bfbfcf0..da3df620af8 100644 --- a/src/common/Utilities/Random.h +++ b/src/common/Utilities/Random.h @@ -23,25 +23,25 @@ #include <random> /* Return a random number in the range min..max. */ -int32 irand(int32 min, int32 max); +TC_COMMON_API int32 irand(int32 min, int32 max); /* Return a random number in the range min..max (inclusive). */ -uint32 urand(uint32 min, uint32 max); +TC_COMMON_API uint32 urand(uint32 min, uint32 max); /* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */ -uint32 urandms(uint32 min, uint32 max); +TC_COMMON_API uint32 urandms(uint32 min, uint32 max); /* Return a random number in the range 0 .. UINT32_MAX. */ -uint32 rand32(); +TC_COMMON_API uint32 rand32(); /* Return a random number in the range min..max */ -float frand(float min, float max); +TC_COMMON_API float frand(float min, float max); /* Return a random double from 0.0 to 1.0 (exclusive). */ -double rand_norm(); +TC_COMMON_API double rand_norm(); /* Return a random double from 0.0 to 100.0 (exclusive). */ -double rand_chance(); +TC_COMMON_API double rand_chance(); /* Return true if a random roll fits in the specified chance (range 0-100). */ inline bool roll_chance_f(float chance) @@ -58,7 +58,7 @@ inline bool roll_chance_i(int chance) /* * SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms */ -class SFMTEngine +class TC_COMMON_API SFMTEngine { public: typedef uint32 result_type; diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h index 8cf5d914128..c5163ef33d5 100644 --- a/src/common/Utilities/TaskScheduler.h +++ b/src/common/Utilities/TaskScheduler.h @@ -46,7 +46,7 @@ class TaskContext; /// with the same duration or a new one. /// It also provides access to the repeat counter which is useful for task that repeat itself often /// but behave different every time (spoken event dialogs for example). -class TaskScheduler +class TC_COMMON_API TaskScheduler { friend class TaskContext; @@ -131,7 +131,7 @@ class TaskScheduler }; }; - class TaskQueue + class TC_COMMON_API TaskQueue { std::multiset<TaskContainer, Compare> container; @@ -408,7 +408,7 @@ private: void Dispatch(success_t const& callback); }; -class TaskContext +class TC_COMMON_API TaskContext { friend class TaskScheduler; diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index 79248544c20..ffc35a6894b 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -41,7 +41,7 @@ template<typename T, class S> struct Finder bool operator()(const std::pair<int, S> &obj) { return obj.second.*idMember_ == val_; } }; -class Tokenizer +class TC_COMMON_API Tokenizer { public: typedef std::vector<char const*> StorageType; @@ -69,15 +69,15 @@ private: StorageType m_storage; }; -void stripLineInvisibleChars(std::string &src); +TC_COMMON_API void stripLineInvisibleChars(std::string &src); -int64 MoneyStringToMoney(const std::string& moneyString); +TC_COMMON_API int64 MoneyStringToMoney(const std::string& moneyString); -struct tm* localtime_r(const time_t* time, struct tm *result); +TC_COMMON_API struct tm* localtime_r(const time_t* time, struct tm *result); -std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false); -uint32 TimeStringToSecs(const std::string& timestring); -std::string TimeToTimestampStr(time_t t); +TC_COMMON_API std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false); +TC_COMMON_API uint32 TimeStringToSecs(const std::string& timestring); +TC_COMMON_API std::string TimeToTimestampStr(time_t t); inline void ApplyPercentModFloatVar(float& var, float val, bool apply) { @@ -112,20 +112,23 @@ inline T RoundToInterval(T& num, T floor, T ceil) } // UTF8 handling -bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); +TC_COMMON_API bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); + // in wsize==max size of buffer, out wsize==real string size -bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize); +TC_COMMON_API bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize); + inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize) { return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize); } -bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str); +TC_COMMON_API bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str); // size==real string size -bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str); +TC_COMMON_API bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str); -size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence -void utf8truncate(std::string& utf8str, size_t len); +// set string to "" if invalid utf8 sequence +TC_COMMON_API size_t utf8length(std::string& utf8str); +TC_COMMON_API void utf8truncate(std::string& utf8str, size_t len); inline bool isBasicLatinCharacter(wchar_t wchar) { @@ -304,24 +307,24 @@ inline void wstrToLower(std::wstring& str) std::transform( str.begin(), str.end(), str.begin(), wcharToLower ); } -std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); +TC_COMMON_API std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); -bool utf8ToConsole(const std::string& utf8str, std::string& conStr); -bool consoleToUtf8(const std::string& conStr, std::string& utf8str); -bool Utf8FitTo(const std::string& str, std::wstring const& search); -void utf8printf(FILE* out, const char *str, ...); -void vutf8printf(FILE* out, const char *str, va_list* ap); -bool Utf8ToUpperOnlyLatin(std::string& utf8String); +TC_COMMON_API bool utf8ToConsole(const std::string& utf8str, std::string& conStr); +TC_COMMON_API bool consoleToUtf8(const std::string& conStr, std::string& utf8str); +TC_COMMON_API bool Utf8FitTo(const std::string& str, std::wstring const& search); +TC_COMMON_API void utf8printf(FILE* out, const char *str, ...); +TC_COMMON_API void vutf8printf(FILE* out, const char *str, va_list* ap); +TC_COMMON_API bool Utf8ToUpperOnlyLatin(std::string& utf8String); -bool IsIPAddress(char const* ipaddress); +TC_COMMON_API bool IsIPAddress(char const* ipaddress); -uint32 CreatePIDFile(std::string const& filename); -uint32 GetPID(); +TC_COMMON_API uint32 CreatePIDFile(std::string const& filename); +TC_COMMON_API uint32 GetPID(); -std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); -void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false); +TC_COMMON_API std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); +TC_COMMON_API void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false); -bool StringToBool(std::string const& str); +TC_COMMON_API bool StringToBool(std::string const& str); // simple class for not-modifyable list template <typename T> @@ -355,7 +358,7 @@ class HookList } }; -class flag128 +class TC_COMMON_API flag128 { private: uint32 part[4]; diff --git a/src/server/database/CMakeLists.txt b/src/server/database/CMakeLists.txt index 6d75ba963e7..06772cd5309 100644 --- a/src/server/database/CMakeLists.txt +++ b/src/server/database/CMakeLists.txt @@ -47,6 +47,8 @@ target_include_directories(database PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +add_definitions(-DTRINITY_API_EXPORT_DATABASE) + target_link_libraries(database PUBLIC common @@ -58,6 +60,18 @@ set_target_properties(database FOLDER "server") +if( BUILD_SHARED_LIBS ) + if( UNIX ) + install(TARGETS database + LIBRARY + DESTINATION lib) + elseif( WIN32 ) + install(TARGETS database + RUNTIME + DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() +endif() + # Generate precompiled header if (USE_COREPCH) add_cxx_pch(database ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) diff --git a/src/server/database/Database/AdhocStatement.h b/src/server/database/Database/AdhocStatement.h index ab85493a14e..9315038bce1 100644 --- a/src/server/database/Database/AdhocStatement.h +++ b/src/server/database/Database/AdhocStatement.h @@ -25,7 +25,7 @@ typedef std::future<QueryResult> QueryResultFuture; typedef std::promise<QueryResult> QueryResultPromise; /*! Raw, ad-hoc query. */ -class BasicStatementTask : public SQLOperation +class TC_DATABASE_API BasicStatementTask : public SQLOperation { public: BasicStatementTask(const char* sql, bool async = false); diff --git a/src/server/database/Database/DatabaseEnv.h b/src/server/database/Database/DatabaseEnv.h index 743341caf60..3d1700bfeba 100644 --- a/src/server/database/Database/DatabaseEnv.h +++ b/src/server/database/Database/DatabaseEnv.h @@ -40,12 +40,12 @@ #include "Implementation/HotfixDatabase.h" /// Accessor to the world database -extern WorldDatabaseWorkerPool WorldDatabase; +TC_DATABASE_API extern WorldDatabaseWorkerPool WorldDatabase; /// Accessor to the character database -extern CharacterDatabaseWorkerPool CharacterDatabase; +TC_DATABASE_API extern CharacterDatabaseWorkerPool CharacterDatabase; /// Accessor to the realm/login database -extern LoginDatabaseWorkerPool LoginDatabase; +TC_DATABASE_API extern LoginDatabaseWorkerPool LoginDatabase; /// Accessor to the hotfix database -extern HotfixDatabaseWorkerPool HotfixDatabase; +TC_DATABASE_API extern HotfixDatabaseWorkerPool HotfixDatabase; #endif diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp index 2cbf31dbef8..89428561524 100644 --- a/src/server/database/Database/DatabaseLoader.cpp +++ b/src/server/database/Database/DatabaseLoader.cpp @@ -177,11 +177,11 @@ bool DatabaseLoader::Process(std::queue<Predicate>& queue) return true; } -template -DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(DatabaseWorkerPool<LoginDatabaseConnection>& pool, std::string const& name); -template -DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(DatabaseWorkerPool<WorldDatabaseConnection>& pool, std::string const& name); -template -DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(DatabaseWorkerPool<CharacterDatabaseConnection>& pool, std::string const& name); -template -DatabaseLoader& DatabaseLoader::AddDatabase<HotfixDatabaseConnection>(DatabaseWorkerPool<HotfixDatabaseConnection>& pool, std::string const& name); +template TC_DATABASE_API +DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(LoginDatabaseWorkerPool&, std::string const&); +template TC_DATABASE_API +DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(CharacterDatabaseWorkerPool&, std::string const&); +template TC_DATABASE_API +DatabaseLoader& DatabaseLoader::AddDatabase<HotfixDatabaseConnection>(HotfixDatabaseWorkerPool&, std::string const&); +template TC_DATABASE_API +DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(WorldDatabaseWorkerPool&, std::string const&); diff --git a/src/server/database/Database/DatabaseLoader.h b/src/server/database/Database/DatabaseLoader.h index e40745f8cc3..4b0c670c3b7 100644 --- a/src/server/database/Database/DatabaseLoader.h +++ b/src/server/database/Database/DatabaseLoader.h @@ -27,7 +27,7 @@ // A helper class to initiate all database worker pools, // handles updating, delays preparing of statements and cleans up on failure. -class DatabaseLoader +class TC_DATABASE_API DatabaseLoader { public: DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask); diff --git a/src/server/database/Database/DatabaseWorker.h b/src/server/database/Database/DatabaseWorker.h index c21a3d2a343..d6b43943f7d 100644 --- a/src/server/database/Database/DatabaseWorker.h +++ b/src/server/database/Database/DatabaseWorker.h @@ -24,7 +24,7 @@ class MySQLConnection; class SQLOperation; -class DatabaseWorker +class TC_DATABASE_API DatabaseWorker { public: DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection); diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index 6c352bb11b8..daf54d271b2 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -317,7 +317,7 @@ T* DatabaseWorkerPool<T>::GetFreeConnection() return connection; } -template class DatabaseWorkerPool<LoginDatabaseConnection>; -template class DatabaseWorkerPool<WorldDatabaseConnection>; -template class DatabaseWorkerPool<CharacterDatabaseConnection>; -template class DatabaseWorkerPool<HotfixDatabaseConnection>; +template class TC_DATABASE_API DatabaseWorkerPool<LoginDatabaseConnection>; +template class TC_DATABASE_API DatabaseWorkerPool<WorldDatabaseConnection>; +template class TC_DATABASE_API DatabaseWorkerPool<CharacterDatabaseConnection>; +template class TC_DATABASE_API DatabaseWorkerPool<HotfixDatabaseConnection>; diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h index abbe9253c2f..cd05023f417 100644 --- a/src/server/database/Database/Field.h +++ b/src/server/database/Database/Field.h @@ -53,7 +53,7 @@ | SUM, AVG | DECIMAL | | COUNT | BIGINT | */ -class Field +class TC_DATABASE_API Field { friend class ResultSet; friend class PreparedResultSet; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index ebc63f1cb6e..192a7e5f8dd 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -595,7 +595,7 @@ enum CharacterDatabaseStatements MAX_CHARACTERDATABASE_STATEMENTS }; -class CharacterDatabaseConnection : public MySQLConnection +class TC_DATABASE_API CharacterDatabaseConnection : public MySQLConnection { public: typedef CharacterDatabaseStatements Statements; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index 35f08d98c77..438485156d5 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -281,7 +281,7 @@ enum HotfixDatabaseStatements MAX_HOTFIXDATABASE_STATEMENTS }; -class HotfixDatabaseConnection : public MySQLConnection +class TC_DATABASE_API HotfixDatabaseConnection : public MySQLConnection { public: typedef HotfixDatabaseStatements Statements; diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 749e7c2c9bb..94111d66388 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -147,7 +147,7 @@ enum LoginDatabaseStatements MAX_LOGINDATABASE_STATEMENTS }; -class LoginDatabaseConnection : public MySQLConnection +class TC_DATABASE_API LoginDatabaseConnection : public MySQLConnection { public: typedef LoginDatabaseStatements Statements; diff --git a/src/server/database/Database/Implementation/WorldDatabase.h b/src/server/database/Database/Implementation/WorldDatabase.h index 0cc876c4a6d..60ac17b5f4a 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.h +++ b/src/server/database/Database/Implementation/WorldDatabase.h @@ -103,7 +103,7 @@ enum WorldDatabaseStatements MAX_WORLDDATABASE_STATEMENTS }; -class WorldDatabaseConnection : public MySQLConnection +class TC_DATABASE_API WorldDatabaseConnection : public MySQLConnection { public: typedef WorldDatabaseStatements Statements; diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h index a0b908593df..566995988c0 100644 --- a/src/server/database/Database/MySQLConnection.h +++ b/src/server/database/Database/MySQLConnection.h @@ -35,7 +35,7 @@ enum ConnectionFlags CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH }; -struct MySQLConnectionInfo +struct TC_DATABASE_API MySQLConnectionInfo { explicit MySQLConnectionInfo(std::string const& infoString) { @@ -62,7 +62,7 @@ struct MySQLConnectionInfo typedef std::map<uint32 /*index*/, std::pair<std::string /*query*/, ConnectionFlags /*sync/async*/> > PreparedStatementMap; -class MySQLConnection +class TC_DATABASE_API MySQLConnection { template <class T> friend class DatabaseWorkerPool; friend class PingOperation; diff --git a/src/server/database/Database/MySQLThreading.h b/src/server/database/Database/MySQLThreading.h index 1cfa11d7e5b..b6083500989 100644 --- a/src/server/database/Database/MySQLThreading.h +++ b/src/server/database/Database/MySQLThreading.h @@ -20,7 +20,7 @@ #include "Log.h" -class MySQL +class TC_DATABASE_API MySQL { public: static void Library_Init() diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h index 2079a5b78b8..d7508dbae1f 100644 --- a/src/server/database/Database/PreparedStatement.h +++ b/src/server/database/Database/PreparedStatement.h @@ -71,7 +71,7 @@ struct PreparedStatementData class MySQLPreparedStatement; //- Upper-level class that is used in code -class PreparedStatement +class TC_DATABASE_API PreparedStatement { friend class PreparedStatementTask; friend class MySQLPreparedStatement; @@ -111,7 +111,7 @@ class PreparedStatement //- Class of which the instances are unique per MySQLConnection //- access to these class objects is only done when a prepared statement task //- is executed. -class MySQLPreparedStatement +class TC_DATABASE_API MySQLPreparedStatement { friend class MySQLConnection; friend class PreparedStatement; @@ -159,7 +159,7 @@ typedef std::future<PreparedQueryResult> PreparedQueryResultFuture; typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise; //- Lower-level class, enqueuable operation -class PreparedStatementTask : public SQLOperation +class TC_DATABASE_API PreparedStatementTask : public SQLOperation { public: PreparedStatementTask(PreparedStatement* stmt, bool async = false); diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h index f78f88f4c1e..34887767dea 100644 --- a/src/server/database/Database/QueryHolder.h +++ b/src/server/database/Database/QueryHolder.h @@ -20,7 +20,7 @@ #include <future> -class SQLQueryHolder +class TC_DATABASE_API SQLQueryHolder { friend class SQLQueryHolderTask; private: @@ -46,7 +46,7 @@ class SQLQueryHolder typedef std::future<SQLQueryHolder*> QueryResultHolderFuture; typedef std::promise<SQLQueryHolder*> QueryResultHolderPromise; -class SQLQueryHolderTask : public SQLOperation +class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation { private: SQLQueryHolder* m_holder; diff --git a/src/server/database/Database/QueryResult.h b/src/server/database/Database/QueryResult.h index d4d63b5ec85..3b1691db1a6 100644 --- a/src/server/database/Database/QueryResult.h +++ b/src/server/database/Database/QueryResult.h @@ -27,7 +27,7 @@ #endif #include <mysql.h> -class ResultSet +class TC_DATABASE_API ResultSet { public: ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount); @@ -60,7 +60,7 @@ class ResultSet typedef std::shared_ptr<ResultSet> QueryResult; -class PreparedResultSet +class TC_DATABASE_API PreparedResultSet { public: PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount); diff --git a/src/server/database/Database/SQLOperation.h b/src/server/database/Database/SQLOperation.h index f0500d1f232..5b3032eab87 100644 --- a/src/server/database/Database/SQLOperation.h +++ b/src/server/database/Database/SQLOperation.h @@ -53,7 +53,7 @@ union SQLResultSetUnion class MySQLConnection; -class SQLOperation +class TC_DATABASE_API SQLOperation { public: SQLOperation(): m_conn(NULL) { } diff --git a/src/server/database/Database/Transaction.h b/src/server/database/Database/Transaction.h index 5780c0363d9..7b5b6addfe4 100644 --- a/src/server/database/Database/Transaction.h +++ b/src/server/database/Database/Transaction.h @@ -25,7 +25,7 @@ class PreparedStatement; /*! Transactions, high level class. */ -class Transaction +class TC_DATABASE_API Transaction { friend class TransactionTask; friend class MySQLConnection; @@ -58,7 +58,7 @@ class Transaction typedef std::shared_ptr<Transaction> SQLTransaction; /*! Low level class*/ -class TransactionTask : public SQLOperation +class TC_DATABASE_API TransactionTask : public SQLOperation { template <class T> friend class DatabaseWorkerPool; friend class DatabaseWorker; diff --git a/src/server/database/Logging/AppenderDB.h b/src/server/database/Logging/AppenderDB.h index a6acc66b48c..225ae969802 100644 --- a/src/server/database/Logging/AppenderDB.h +++ b/src/server/database/Logging/AppenderDB.h @@ -20,7 +20,7 @@ #include "Appender.h" -class AppenderDB: public Appender +class TC_DATABASE_API AppenderDB: public Appender { public: typedef std::integral_constant<AppenderType, APPENDER_DB>::type TypeIndex; diff --git a/src/server/database/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp index ab4b767b104..ef4a0d407cb 100644 --- a/src/server/database/Updater/DBUpdater.cpp +++ b/src/server/database/Updater/DBUpdater.cpp @@ -468,7 +468,7 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos } } -template class DBUpdater<LoginDatabaseConnection>; -template class DBUpdater<WorldDatabaseConnection>; -template class DBUpdater<CharacterDatabaseConnection>; -template class DBUpdater<HotfixDatabaseConnection>; +template class TC_DATABASE_API DBUpdater<LoginDatabaseConnection>; +template class TC_DATABASE_API DBUpdater<WorldDatabaseConnection>; +template class TC_DATABASE_API DBUpdater<CharacterDatabaseConnection>; +template class TC_DATABASE_API DBUpdater<HotfixDatabaseConnection>; diff --git a/src/server/database/Updater/DBUpdater.h b/src/server/database/Updater/DBUpdater.h index dbb897d2527..cc5d3aad68b 100644 --- a/src/server/database/Updater/DBUpdater.h +++ b/src/server/database/Updater/DBUpdater.h @@ -23,7 +23,7 @@ #include <string> #include <boost/filesystem.hpp> -class UpdateException : public std::exception +class TC_DATABASE_API UpdateException : public std::exception { public: UpdateException(std::string const& msg) : _msg(msg) { } @@ -41,7 +41,7 @@ enum BaseLocation LOCATION_DOWNLOAD }; -struct UpdateResult +struct TC_DATABASE_API UpdateResult { UpdateResult() : updated(0), recent(0), archived(0) { } @@ -66,7 +66,7 @@ private: }; template <class T> -class DBUpdater +class TC_DATABASE_API DBUpdater { public: using Path = boost::filesystem::path; diff --git a/src/server/database/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h index c87efea2b02..a17658818ce 100644 --- a/src/server/database/Updater/UpdateFetcher.h +++ b/src/server/database/Updater/UpdateFetcher.h @@ -25,7 +25,7 @@ #include <memory> #include <vector> -class UpdateFetcher +class TC_DATABASE_API UpdateFetcher { typedef boost::filesystem::path Path; diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index 55b91b6969e..f1718fbdb6a 100644 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -25,7 +25,7 @@ class Creature; -class AggressorAI : public CreatureAI +class TC_GAME_API AggressorAI : public CreatureAI { public: explicit AggressorAI(Creature* c) : CreatureAI(c) { } @@ -36,7 +36,7 @@ class AggressorAI : public CreatureAI typedef std::vector<uint32> SpellVct; -class CombatAI : public CreatureAI +class TC_GAME_API CombatAI : public CreatureAI { public: explicit CombatAI(Creature* c) : CreatureAI(c) { } @@ -55,7 +55,7 @@ class CombatAI : public CreatureAI SpellVct spells; }; -class CasterAI : public CombatAI +class TC_GAME_API CasterAI : public CombatAI { public: explicit CasterAI(Creature* c) : CombatAI(c) { m_attackDist = MELEE_RANGE; } @@ -67,7 +67,7 @@ class CasterAI : public CombatAI float m_attackDist; }; -struct ArcherAI : public CreatureAI +struct TC_GAME_API ArcherAI : public CreatureAI { public: explicit ArcherAI(Creature* c); @@ -80,7 +80,7 @@ struct ArcherAI : public CreatureAI float m_minRange; }; -struct TurretAI : public CreatureAI +struct TC_GAME_API TurretAI : public CreatureAI { public: explicit TurretAI(Creature* c); @@ -97,7 +97,7 @@ struct TurretAI : public CreatureAI #define VEHICLE_CONDITION_CHECK_TIME 1000 #define VEHICLE_DISMISS_TIME 5000 -struct VehicleAI : public CreatureAI +struct TC_GAME_API VehicleAI : public CreatureAI { public: explicit VehicleAI(Creature* creature); diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index 4f256a5de31..7a2f23ac804 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -26,7 +26,7 @@ #include "GameObject.h" #include "CreatureAI.h" -class GameObjectAI +class TC_GAME_API GameObjectAI { protected: GameObject* const go; @@ -63,7 +63,7 @@ class GameObjectAI virtual void EventInform(uint32 /*eventId*/) { } }; -class NullGameObjectAI : public GameObjectAI +class TC_GAME_API NullGameObjectAI : public GameObjectAI { public: explicit NullGameObjectAI(GameObject* g); diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h index 63f2750a5d4..a6aa4b6624a 100644 --- a/src/server/game/AI/CoreAI/GuardAI.h +++ b/src/server/game/AI/CoreAI/GuardAI.h @@ -23,7 +23,7 @@ class Creature; -class GuardAI : public ScriptedAI +class TC_GAME_API GuardAI : public ScriptedAI { public: explicit GuardAI(Creature* creature); diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h index bd72cd7fbe7..5a6dba7046d 100644 --- a/src/server/game/AI/CoreAI/PassiveAI.h +++ b/src/server/game/AI/CoreAI/PassiveAI.h @@ -21,7 +21,7 @@ #include "CreatureAI.h" -class PassiveAI : public CreatureAI +class TC_GAME_API PassiveAI : public CreatureAI { public: explicit PassiveAI(Creature* c); @@ -33,7 +33,7 @@ class PassiveAI : public CreatureAI static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; -class PossessedAI : public CreatureAI +class TC_GAME_API PossessedAI : public CreatureAI { public: explicit PossessedAI(Creature* c); @@ -49,7 +49,7 @@ class PossessedAI : public CreatureAI static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; -class NullCreatureAI : public CreatureAI +class TC_GAME_API NullCreatureAI : public CreatureAI { public: explicit NullCreatureAI(Creature* c); @@ -63,7 +63,7 @@ class NullCreatureAI : public CreatureAI static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; -class CritterAI : public PassiveAI +class TC_GAME_API CritterAI : public PassiveAI { public: explicit CritterAI(Creature* c) : PassiveAI(c) { } @@ -72,7 +72,7 @@ class CritterAI : public PassiveAI void EnterEvadeMode(EvadeReason why) override; }; -class TriggerAI : public NullCreatureAI +class TC_GAME_API TriggerAI : public NullCreatureAI { public: explicit TriggerAI(Creature* c) : NullCreatureAI(c) { } diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index 9c33baa9a9f..3ad34047b01 100644 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -25,7 +25,7 @@ class Creature; class Spell; -class PetAI : public CreatureAI +class TC_GAME_API PetAI : public CreatureAI { public: diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index e5abaac2f00..d281ca11fdf 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -23,7 +23,7 @@ class Unit; -class ReactorAI : public CreatureAI +class TC_GAME_API ReactorAI : public CreatureAI { public: diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h index e1d1618037f..a0e796ed7e0 100644 --- a/src/server/game/AI/CoreAI/TotemAI.h +++ b/src/server/game/AI/CoreAI/TotemAI.h @@ -25,7 +25,7 @@ class Creature; class Totem; -class TotemAI : public CreatureAI +class TC_GAME_API TotemAI : public CreatureAI { public: diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index b43e61b6c6e..ea001ceda32 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -40,7 +40,7 @@ enum SelectAggroTarget }; // default predicate function to select target based on distance, player and/or aura criteria -struct DefaultTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API DefaultTargetSelector : public std::unary_function<Unit*, bool> { const Unit* me; float m_dist; @@ -90,7 +90,7 @@ struct DefaultTargetSelector : public std::unary_function<Unit*, bool> // Target selector for spell casts checking range, auras and attributes /// @todo Add more checks from Spell::CheckCast -struct SpellTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API SpellTargetSelector : public std::unary_function<Unit*, bool> { public: SpellTargetSelector(Unit* caster, uint32 spellId); @@ -104,7 +104,7 @@ struct SpellTargetSelector : public std::unary_function<Unit*, bool> // Very simple target selector, will just skip main target // NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection // because tank will not be in the temporary list -struct NonTankTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API NonTankTargetSelector : public std::unary_function<Unit*, bool> { public: NonTankTargetSelector(Creature* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { } @@ -115,7 +115,7 @@ struct NonTankTargetSelector : public std::unary_function<Unit*, bool> bool _playerOnly; }; -class UnitAI +class TC_GAME_API UnitAI { protected: Unit* const me; @@ -264,7 +264,7 @@ class UnitAI UnitAI& operator=(UnitAI const& right) = delete; }; -class PlayerAI : public UnitAI +class TC_GAME_API PlayerAI : public UnitAI { protected: Player* const me; @@ -274,7 +274,7 @@ class PlayerAI : public UnitAI void OnCharmed(bool apply) override; }; -class SimpleCharmedAI : public PlayerAI +class TC_GAME_API SimpleCharmedAI : public PlayerAI { public: void UpdateAI(uint32 diff) override; diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index f250a79ea25..59f954c691d 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -65,7 +65,7 @@ enum SCEquip }; typedef std::set<AreaBoundary const*> CreatureBoundary; -class CreatureAI : public UnitAI +class TC_GAME_API CreatureAI : public UnitAI { protected: Creature* const me; diff --git a/src/server/game/AI/CreatureAISelector.h b/src/server/game/AI/CreatureAISelector.h index 7c7bc705ade..0e3be1a8604 100644 --- a/src/server/game/AI/CreatureAISelector.h +++ b/src/server/game/AI/CreatureAISelector.h @@ -27,9 +27,9 @@ class GameObject; namespace FactorySelector { - CreatureAI* selectAI(Creature*); - MovementGenerator* selectMovementGenerator(Creature*); - GameObjectAI* SelectGameObjectAI(GameObject*); + TC_GAME_API CreatureAI* selectAI(Creature*); + TC_GAME_API MovementGenerator* selectMovementGenerator(Creature*); + TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject*); } #endif diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 0e6836ca538..87c7f2083af 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -608,27 +608,27 @@ void WorldBossAI::UpdateAI(uint32 diff) } // SD2 grid searchers. -Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/) +TC_GAME_API Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive /*= true*/) { return source->FindNearestCreature(entry, maxSearchRange, alive); } -GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange) +TC_GAME_API GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange) { return source->FindNearestGameObject(entry, maxSearchRange); } -void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange) +TC_GAME_API void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange) { source->GetCreatureListWithEntryInGrid(list, entry, maxSearchRange); } -void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange) +TC_GAME_API void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange) { source->GetGameObjectListWithEntryInGrid(list, entry, maxSearchRange); } -void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange) +TC_GAME_API void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange) { source->GetPlayerListInGrid(list, maxSearchRange); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index d3e20e8b886..56e4b8bf780 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -38,7 +38,7 @@ T* EnsureAI(U* ai) class InstanceScript; -class SummonList +class TC_GAME_API SummonList { public: typedef GuidList StorageType; @@ -123,7 +123,7 @@ private: StorageType storage_; }; -class EntryCheckPredicate +class TC_GAME_API EntryCheckPredicate { public: EntryCheckPredicate(uint32 entry) : _entry(entry) { } @@ -133,13 +133,13 @@ class EntryCheckPredicate uint32 _entry; }; -class DummyEntryCheckPredicate +class TC_GAME_API DummyEntryCheckPredicate { public: bool operator()(ObjectGuid) { return true; } }; -struct ScriptedAI : public CreatureAI +struct TC_GAME_API ScriptedAI : public CreatureAI { explicit ScriptedAI(Creature* creature); virtual ~ScriptedAI() { } @@ -331,7 +331,7 @@ struct ScriptedAI : public CreatureAI bool _isHeroic; }; -class BossAI : public ScriptedAI +class TC_GAME_API BossAI : public ScriptedAI { public: BossAI(Creature* creature, uint32 bossId); @@ -374,7 +374,7 @@ class BossAI : public ScriptedAI uint32 const _bossId; }; -class WorldBossAI : public ScriptedAI +class TC_GAME_API WorldBossAI : public ScriptedAI { public: WorldBossAI(Creature* creature); @@ -405,10 +405,10 @@ class WorldBossAI : public ScriptedAI }; // SD2 grid searchers. -Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true); -GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange); -void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange); -void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange); -void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange); +TC_GAME_API Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true); +TC_GAME_API GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange); +TC_GAME_API void GetCreatureListWithEntryInGrid(std::list<Creature*>& list, WorldObject* source, uint32 entry, float maxSearchRange); +TC_GAME_API void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& list, WorldObject* source, uint32 entry, float maxSearchRange); +TC_GAME_API void GetPlayerListInGrid(std::list<Player*>& list, WorldObject* source, float maxSearchRange); #endif // SCRIPTEDCREATURE_H_ diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h index 673f3e671a0..37a1464d812 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h @@ -49,7 +49,7 @@ enum eEscortState STATE_ESCORT_PAUSED = 0x004 //will not proceed with waypoints before state is removed }; -struct npc_escortAI : public ScriptedAI +struct TC_GAME_API npc_escortAI : public ScriptedAI { public: explicit npc_escortAI(Creature* creature); diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h index d1c976b45c8..e17fb7c8507 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h @@ -32,7 +32,7 @@ enum eFollowState STATE_FOLLOW_POSTEVENT = 0x020 //can be set at complete and allow post event to run }; -class FollowerAI : public ScriptedAI +class TC_GAME_API FollowerAI : public ScriptedAI { public: explicit FollowerAI(Creature* creature); diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 3abe1e5774c..aa7c9ace0b3 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -42,7 +42,7 @@ enum SmartEscortVars SMART_MAX_AID_DIST = SMART_ESCORT_MAX_PLAYER_DIST / 2 }; -class SmartAI : public CreatureAI +class TC_GAME_API SmartAI : public CreatureAI { public: ~SmartAI(){ } @@ -230,7 +230,7 @@ class SmartAI : public CreatureAI bool mJustReset; }; -class SmartGameObjectAI : public GameObjectAI +class TC_GAME_API SmartGameObjectAI : public GameObjectAI { public: SmartGameObjectAI(GameObject* g) : GameObjectAI(g) { } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 95792fead3c..0ea3afa08f9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -28,7 +28,7 @@ #include "SmartScriptMgr.h" //#include "SmartAI.h" -class SmartScript +class TC_GAME_API SmartScript { public: SmartScript(); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 5f627e4021d..87d23b077b1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1435,7 +1435,7 @@ public: }; typedef std::unordered_map<uint32, ObjectGuidList*> ObjectListMap; -class SmartWaypointMgr +class TC_GAME_API SmartWaypointMgr { private: SmartWaypointMgr() { } @@ -1467,7 +1467,7 @@ typedef std::unordered_map<int64, SmartAIEventList> SmartAIEventMap; typedef std::map<uint32 /*entry*/, std::pair<uint32 /*spellId*/, SpellEffIndex /*effIndex*/> > CacheSpellContainer; typedef std::pair<CacheSpellContainer::const_iterator, CacheSpellContainer::const_iterator> CacheSpellContainerBounds; -class SmartAIMgr +class TC_GAME_API SmartAIMgr { private: SmartAIMgr() { } diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index 09ab140d07c..d0a80f983db 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -50,7 +50,7 @@ typedef std::map<uint32, rbac::RBACPermission*> RBACPermissionsContainer; typedef std::map<uint8, rbac::RBACPermissionContainer> RBACDefaultPermissionsContainer; } -class AccountMgr +class TC_GAME_API AccountMgr { private: AccountMgr(); diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h index ef47a3e5c93..1888e782616 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.h +++ b/src/server/game/Accounts/BattlenetAccountMgr.h @@ -29,18 +29,18 @@ namespace Battlenet { namespace AccountMgr { - AccountOpResult CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount = true); - AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); - bool CheckPassword(uint32 accountId, std::string password); - AccountOpResult LinkWithGameAccount(std::string const& email, std::string const& gameAccountName); - AccountOpResult UnlinkGameAccount(std::string const& gameAccountName); - - uint32 GetId(std::string const& username); - bool GetName(uint32 accountId, std::string& name); - uint32 GetIdByGameAccount(uint32 gameAccountId); - uint8 GetMaxIndex(uint32 accountId); - - std::string CalculateShaPassHash(std::string const& name, std::string const& password); + TC_GAME_API AccountOpResult CreateBattlenetAccount(std::string email, std::string password, bool withGameAccount = true); + TC_GAME_API AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); + TC_GAME_API bool CheckPassword(uint32 accountId, std::string password); + TC_GAME_API AccountOpResult LinkWithGameAccount(std::string const& email, std::string const& gameAccountName); + TC_GAME_API AccountOpResult UnlinkGameAccount(std::string const& gameAccountName); + + TC_GAME_API uint32 GetId(std::string const& username); + TC_GAME_API bool GetName(uint32 accountId, std::string& name); + TC_GAME_API uint32 GetIdByGameAccount(uint32 gameAccountId); + TC_GAME_API uint8 GetMaxIndex(uint32 accountId); + + TC_GAME_API std::string CalculateShaPassHash(std::string const& name, std::string const& password); } } diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 5dc0c0867ea..07ad2a2fd4b 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -745,7 +745,7 @@ enum RBACCommandResult typedef std::set<uint32> RBACPermissionContainer; -class RBACPermission +class TC_GAME_API RBACPermission { public: RBACPermission(uint32 id = 0, std::string const& name = ""): @@ -780,7 +780,7 @@ class RBACPermission * - Granted permissions: through linked permissions and directly assigned * - Denied permissions: through linked permissions and directly assigned */ -class RBACData +class TC_GAME_API RBACData { public: RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel = 255): diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 7a70b23077f..219745e0444 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -488,13 +488,7 @@ void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /* // Not needed } -template<class T> -void AchievementMgr<T>::DeleteFromDB(ObjectGuid /*guid*/) -{ -} - -template<> -void AchievementMgr<Player>::DeleteFromDB(ObjectGuid guid) +void DeletePlayerAchievementsFromDB(ObjectGuid guid) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -509,8 +503,7 @@ void AchievementMgr<Player>::DeleteFromDB(ObjectGuid guid) CharacterDatabase.CommitTransaction(trans); } -template<> -void AchievementMgr<Guild>::DeleteFromDB(ObjectGuid guid) +void DeleteGuildAchievementsFromDB(ObjectGuid guid) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -529,6 +522,7 @@ template<class T> void AchievementMgr<T>::SaveToDB(SQLTransaction& /*trans*/) { } + template<> void AchievementMgr<Player>::SaveToDB(SQLTransaction& trans) { @@ -2584,6 +2578,9 @@ bool AchievementMgr<T>::AdditionalRequirementsSatisfied(ModifierTreeNode const* return true; } +template class TC_GAME_API AchievementMgr<Player>; +template class TC_GAME_API AchievementMgr<Guild>; + char const* AchievementGlobalMgr::GetCriteriaTypeString(uint32 type) { return GetCriteriaTypeString(AchievementCriteriaTypes(type)); @@ -2887,9 +2884,6 @@ char const* AchievementGlobalMgr::GetCriteriaTypeString(AchievementCriteriaTypes return "MISSING_TYPE"; } -template class AchievementMgr<Guild>; -template class AchievementMgr<Player>; - AchievementGlobalMgr* AchievementGlobalMgr::instance() { static AchievementGlobalMgr instance; diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 5ee8574559a..16f4d20614a 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -30,6 +30,7 @@ class Unit; class Player; +class Guild; class WorldPacket; struct ModifierTreeNode @@ -233,7 +234,7 @@ struct AchievementCriteriaData bool Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscValue1 = 0) const; }; -struct AchievementCriteriaDataSet +struct TC_GAME_API AchievementCriteriaDataSet { AchievementCriteriaDataSet() : criteria_id(0) { } typedef std::vector<AchievementCriteriaData> Storage; @@ -284,15 +285,41 @@ enum ProgressType PROGRESS_HIGHEST }; +// Hackfix to solve an unresolved issue in clang that the visibility +// flag is ignored in some explicit template specializations, +// which prevents clang from exporting the `DeleteFromDB` symbol. +// https://llvm.org/bugs/show_bug.cgi?id=24815 +// https://llvm.org/bugs/show_bug.cgi?id=23667 +TC_GAME_API void DeletePlayerAchievementsFromDB(ObjectGuid guid); +TC_GAME_API void DeleteGuildAchievementsFromDB(ObjectGuid guid); + +template<typename T> +struct AchievementMgrDeleterBase; + +template<> +struct AchievementMgrDeleterBase<Player> +{ + static void DeleteFromDB(ObjectGuid lowguid) { DeletePlayerAchievementsFromDB(lowguid); } +}; + +template<> +struct AchievementMgrDeleterBase<Guild> +{ + static void DeleteFromDB(ObjectGuid lowguid) { DeleteGuildAchievementsFromDB(lowguid); } +}; + template<class T> -class AchievementMgr +class TC_GAME_API AchievementMgr + : public AchievementMgrDeleterBase<T> { public: AchievementMgr(T* owner); ~AchievementMgr(); void Reset(); - static void DeleteFromDB(ObjectGuid lowguid); + + using AchievementMgrDeleterBase<T>::DeleteFromDB; + void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(SQLTransaction& trans); void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); @@ -335,7 +362,7 @@ class AchievementMgr uint32 _achievementPoints; }; -class AchievementGlobalMgr +class TC_GAME_API AchievementGlobalMgr { AchievementGlobalMgr() { } ~AchievementGlobalMgr(); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 62b6838a6e6..ae9a6c1e894 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -64,7 +64,7 @@ enum MailAuctionAnswers AUCTION_SALE_PENDING = 6 }; -struct AuctionEntry +struct TC_GAME_API AuctionEntry { uint32 Id; ObjectGuid::LowType auctioneer; // creature low guid @@ -97,7 +97,7 @@ struct AuctionEntry }; //this class is used as auctionhouse instance -class AuctionHouseObject +class TC_GAME_API AuctionHouseObject { public: ~AuctionHouseObject() @@ -135,7 +135,7 @@ class AuctionHouseObject AuctionEntryMap AuctionsMap; }; -class AuctionHouseMgr +class TC_GAME_API AuctionHouseMgr { private: AuctionHouseMgr(); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h index 8f90e8fa76f..1a438e01cdb 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h @@ -196,7 +196,7 @@ enum AuctionBotConfigFloatValues }; // All basic config data used by other AHBot classes for self-configure. -class AuctionBotConfig +class TC_GAME_API AuctionBotConfig { private: AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) {} @@ -270,7 +270,7 @@ typedef AuctionHouseBotStatusInfoPerType AuctionHouseBotStatusInfo[MAX_AUCTION_H // This class handle both Selling and Buying method // (holder of AuctionBotBuyer and AuctionBotSeller objects) -class AuctionHouseBot +class TC_GAME_API AuctionHouseBot { private: AuctionHouseBot(); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h index e1b6b425c48..979f73c0099 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h @@ -67,7 +67,7 @@ private: // This class handle all Buyer method // (holder of AuctionBotConfig for each auction house type) -class AuctionBotBuyer : public AuctionBotAgent +class TC_GAME_API AuctionBotBuyer : public AuctionBotAgent { public: AuctionBotBuyer(); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h index 05782ee84b8..3e6f263707f 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h @@ -115,7 +115,7 @@ private: // This class handle all Selling method // (holder of AHB_Seller_Config data for each auction house type) -class AuctionBotSeller : public AuctionBotAgent +class TC_GAME_API AuctionBotSeller : public AuctionBotAgent { public: typedef std::vector<uint32> ItemPool; diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 0159ba95eeb..ad5770e2ad0 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -78,7 +78,7 @@ class BfGraveyard; typedef std::vector<BfGraveyard*> GraveyardVect; typedef std::map<ObjectGuid, time_t> PlayerTimerMap; -class BfCapturePoint +class TC_GAME_API BfCapturePoint { public: BfCapturePoint(Battlefield* bf); @@ -146,7 +146,7 @@ class BfCapturePoint ObjectGuid m_capturePointGUID; }; -class BfGraveyard +class TC_GAME_API BfGraveyard { public: BfGraveyard(Battlefield* Bf); @@ -193,7 +193,7 @@ class BfGraveyard Battlefield* m_Bf; }; -class Battlefield : public ZoneScript +class TC_GAME_API Battlefield : public ZoneScript { friend class BattlefieldMgr; diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index 2d3b9d06470..623f1dadb91 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -24,7 +24,7 @@ class Player; class ZoneScript; // class to handle player enter / leave / areatrigger / GO use events -class BattlefieldMgr +class TC_GAME_API BattlefieldMgr { public: static BattlefieldMgr* instance(); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 087f20e9224..e849c2f33d1 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -266,7 +266,7 @@ class WintergraspCapturePoint : public BfCapturePoint * WinterGrasp Battlefield * * ######################### */ -class BattlefieldWG : public Battlefield +class TC_GAME_API BattlefieldWG : public Battlefield { public: ~BattlefieldWG(); @@ -1098,7 +1098,7 @@ StaticWintergraspWorkshopInfo const WorkshopData[WG_MAX_WORKSHOP] = // ******************************************************************** // Structure for different buildings that can be destroyed during battle -struct BfWGGameObjectBuilding +struct TC_GAME_API BfWGGameObjectBuilding { private: // WG object @@ -1150,7 +1150,7 @@ public: }; // Structure for the 6 workshop -struct WintergraspWorkshop +struct TC_GAME_API WintergraspWorkshop { private: BattlefieldWG* _wg; // Pointer to wintergrasp diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h index d0ed3a86af7..80745d2658c 100644 --- a/src/server/game/Battlegrounds/Arena.h +++ b/src/server/game/Battlegrounds/Arena.h @@ -36,7 +36,7 @@ enum ArenaWorldStates ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD = 3601 }; -class Arena : public Battleground +class TC_GAME_API Arena : public Battleground { protected: Arena(); diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index 683b216dd42..c9a9419dc2c 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -23,7 +23,7 @@ #include "Player.h" #include "ObjectAccessor.h" -struct ArenaScore : public BattlegroundScore +struct TC_GAME_API ArenaScore : public BattlegroundScore { friend class Arena; @@ -43,7 +43,7 @@ struct ArenaScore : public BattlegroundScore uint8 TeamId; // BattlegroundTeamId }; -struct ArenaTeamScore +struct TC_GAME_API ArenaTeamScore { friend class Arena; friend class Battleground; diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index db5d63a8915..df966a632cb 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -81,7 +81,7 @@ enum ArenaTeamTypes ARENA_TEAM_5v5 = 5 }; -struct ArenaTeamMember +struct TC_GAME_API ArenaTeamMember { ObjectGuid Guid; std::string Name; @@ -109,7 +109,7 @@ struct ArenaTeamStats #define MAX_ARENA_SLOT 3 // 0..2 slots -class ArenaTeam +class TC_GAME_API ArenaTeam { public: ArenaTeam(); diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h index 23197ad869f..131a2cc8899 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.h +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h @@ -20,7 +20,7 @@ #include "ArenaTeam.h" -class ArenaTeamMgr +class TC_GAME_API ArenaTeamMgr { private: ArenaTeamMgr(); diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 1f33b0d5d7c..cb2fb68d9dd 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -232,7 +232,7 @@ This class is used to: 3. some certain cases, same for all battlegrounds 4. It has properties same for all battlegrounds */ -class Battleground +class TC_GAME_API Battleground { public: Battleground(); diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 85a2358c9d1..d35b239a725 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -67,7 +67,7 @@ namespace WorldPackets } } -class BattlegroundMgr +class TC_GAME_API BattlegroundMgr { private: BattlegroundMgr(); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h index 9291adf9e8d..5eac6a8f51a 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.h +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h @@ -72,7 +72,7 @@ enum BattlegroundQueueInvitationType }; class Battleground; -class BattlegroundQueue +class TC_GAME_API BattlegroundQueue { public: BattlegroundQueue(); @@ -142,7 +142,7 @@ class BattlegroundQueue This class is used to invite player to BG again, when minute lasts from his first invitation it is capable to solve all possibilities */ -class BGQueueInviteEvent : public BasicEvent +class TC_GAME_API BGQueueInviteEvent : public BasicEvent { public: BGQueueInviteEvent(ObjectGuid pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) : @@ -165,7 +165,7 @@ class BGQueueInviteEvent : public BasicEvent We must store removeInvite time in case player left queue and joined and is invited again We must store bgQueueTypeId, because battleground can be deleted already, when player entered it */ -class BGQueueRemoveEvent : public BasicEvent +class TC_GAME_API BGQueueRemoveEvent : public BasicEvent { public: BGQueueRemoveEvent(ObjectGuid pl_guid, uint32 bgInstanceGUID, BattlegroundTypeId BgTypeId, uint8 arenaType, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime) diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index bba0614d421..06d4c403909 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -21,6 +21,8 @@ endif () GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) +add_definitions(-DTRINITY_API_EXPORT_GAME) + add_library(game ${PRIVATE_SOURCES} ${PRIVATE_PCH_SOURCE} @@ -48,6 +50,18 @@ set_target_properties(game FOLDER "server") +if( BUILD_SHARED_LIBS ) + if( UNIX ) + install(TARGETS game + LIBRARY + DESTINATION lib) + elseif( WIN32 ) + install(TARGETS game + RUNTIME + DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() +endif() + # Generate precompiled header if (USE_COREPCH) add_cxx_pch(game ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 3eae74a02b5..e7594823d51 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -128,7 +128,7 @@ enum CalendarError #define CALENDAR_MAX_INVITES 100 #define CALENDAR_DEFAULT_RESPONSE_TIME 946684800 // 01/01/2000 00:00:00 -struct CalendarInvite +struct TC_GAME_API CalendarInvite { public: CalendarInvite(CalendarInvite const& calendarInvite, uint64 inviteId, uint64 eventId) @@ -188,7 +188,7 @@ struct CalendarInvite std::string _note; }; -struct CalendarEvent +struct TC_GAME_API CalendarEvent { public: CalendarEvent(CalendarEvent const& calendarEvent, uint64 eventId) @@ -268,7 +268,7 @@ typedef std::vector<CalendarInvite*> CalendarInviteStore; typedef std::set<CalendarEvent*> CalendarEventStore; typedef std::map<uint64 /* eventID */, CalendarInviteStore > CalendarEventInviteStore; -class CalendarMgr +class TC_GAME_API CalendarMgr { private: CalendarMgr(); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 5683a876f6d..f309f3c7936 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -123,7 +123,7 @@ enum ChannelMemberFlags // 0x80 }; -class Channel +class TC_GAME_API Channel { struct PlayerInfo { diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index 835a4cdcaaa..cdaf6b8565c 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -24,7 +24,7 @@ #define MAX_CHANNEL_NAME_STR 0x31 #define MAX_CHANNEL_PASS_STR 31 -class ChannelMgr +class TC_GAME_API ChannelMgr { typedef std::map<std::wstring, Channel*> ChannelMap; diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 63166b6ae91..226ec1fe6ad 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -37,7 +37,7 @@ class WorldObject; struct GameTele; -class ChatCommand +class TC_GAME_API ChatCommand { typedef bool(*pHandler)(ChatHandler*, char const*); @@ -53,7 +53,7 @@ class ChatCommand std::vector<ChatCommand> ChildCommands; }; -class ChatHandler +class TC_GAME_API ChatHandler { public: WorldSession* GetSession() { return m_session; } @@ -154,7 +154,7 @@ class ChatHandler bool sentErrorMessage; }; -class CliHandler : public ChatHandler +class TC_GAME_API CliHandler : public ChatHandler { public: typedef void Print(void*, char const*); diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index 1a0310118d2..ae6932b5d27 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -35,7 +35,7 @@ class Quest; /////////////////////////////////////////////////////////////////////////////////////////////////// // ChatLink - abstract base class for various links -class ChatLink +class TC_GAME_API ChatLink { public: ChatLink() : _color(0), _startPos(0), _endPos(0) { } @@ -55,7 +55,7 @@ protected: }; // ItemChatLink - link to item -class ItemChatLink : public ChatLink +class TC_GAME_API ItemChatLink : public ChatLink { public: ItemChatLink() : ChatLink(), _item(NULL), _suffix(NULL), _property(NULL) @@ -76,7 +76,7 @@ protected: }; // QuestChatLink - link to quest -class QuestChatLink : public ChatLink +class TC_GAME_API QuestChatLink : public ChatLink { public: QuestChatLink() : ChatLink(), _quest(nullptr), _questLevel(0) { } @@ -89,7 +89,7 @@ protected: }; // SpellChatLink - link to quest -class SpellChatLink : public ChatLink +class TC_GAME_API SpellChatLink : public ChatLink { public: SpellChatLink() : ChatLink(), _spell(nullptr) { } @@ -101,7 +101,7 @@ protected: }; // AchievementChatLink - link to quest -class AchievementChatLink : public ChatLink +class TC_GAME_API AchievementChatLink : public ChatLink { public: AchievementChatLink() : ChatLink(), _guid(0), _achievement(NULL) @@ -118,7 +118,7 @@ protected: }; // TradeChatLink - link to trade info -class TradeChatLink : public SpellChatLink +class TC_GAME_API TradeChatLink : public SpellChatLink { public: TradeChatLink() : SpellChatLink(), _minSkillLevel(0), _maxSkillLevel(0), _guid(0) { } @@ -131,7 +131,7 @@ private: }; // TalentChatLink - link to talent -class TalentChatLink : public SpellChatLink +class TC_GAME_API TalentChatLink : public SpellChatLink { public: TalentChatLink() : SpellChatLink(), _talentId(0), _rankId(0) { } @@ -143,7 +143,7 @@ private: }; // EnchantmentChatLink - link to enchantment -class EnchantmentChatLink : public SpellChatLink +class TC_GAME_API EnchantmentChatLink : public SpellChatLink { public: EnchantmentChatLink() : SpellChatLink() { } @@ -151,7 +151,7 @@ public: }; // GlyphChatLink - link to glyph -class GlyphChatLink : public SpellChatLink +class TC_GAME_API GlyphChatLink : public SpellChatLink { public: GlyphChatLink() : SpellChatLink(), _slotId(0), _glyph(NULL) { } @@ -161,7 +161,7 @@ private: GlyphPropertiesEntry const* _glyph; }; -class LinkExtractor +class TC_GAME_API LinkExtractor { public: explicit LinkExtractor(const char* msg); diff --git a/src/server/game/Combat/HostileRefManager.h b/src/server/game/Combat/HostileRefManager.h index 96152ed46f7..855f9e3d272 100644 --- a/src/server/game/Combat/HostileRefManager.h +++ b/src/server/game/Combat/HostileRefManager.h @@ -29,7 +29,7 @@ class SpellInfo; //================================================= -class HostileRefManager : public RefManager<Unit, ThreatManager> +class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager> { private: Unit* iOwner; diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h index 7d20e99c128..8b28779569a 100644 --- a/src/server/game/Combat/ThreatManager.h +++ b/src/server/game/Combat/ThreatManager.h @@ -39,14 +39,14 @@ class SpellInfo; //============================================================== // Class to calculate the real threat based -struct ThreatCalcHelper +struct TC_GAME_API ThreatCalcHelper { static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL); static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = NULL); }; //============================================================== -class HostileReference : public Reference<Unit, ThreatManager> +class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager> { public: HostileReference(Unit* refUnit, ThreatManager* threatManager, float threat); @@ -141,7 +141,7 @@ class HostileReference : public Reference<Unit, ThreatManager> //============================================================== class ThreatManager; -class ThreatContainer +class TC_GAME_API ThreatContainer { friend class ThreatManager; @@ -198,7 +198,7 @@ class ThreatContainer //================================================= -class ThreatManager +class TC_GAME_API ThreatManager { public: friend class HostileReference; diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h index e501cdaa4a2..f50edcf3c7d 100644 --- a/src/server/game/Combat/UnitEvents.h +++ b/src/server/game/Combat/UnitEvents.h @@ -81,7 +81,7 @@ class UnitBaseEvent //============================================================== -class ThreatRefStatusChangeEvent : public UnitBaseEvent +class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent { private: HostileReference* iHostileReference; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index e973d56dade..db5b78215b3 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -178,7 +178,7 @@ enum MaxConditionTargets MAX_CONDITION_TARGETS = 3 }; -struct ConditionSourceInfo +struct TC_GAME_API ConditionSourceInfo { WorldObject* mConditionTargets[MAX_CONDITION_TARGETS]; // an array of targets available for conditions Condition const* mLastFailedCondition; @@ -191,7 +191,7 @@ struct ConditionSourceInfo } }; -struct Condition +struct TC_GAME_API Condition { ConditionSourceType SourceType; //SourceTypeOrReferenceId uint32 SourceGroup; @@ -243,7 +243,7 @@ typedef std::unordered_map<uint32, ConditionsByEntryMap> ConditionEntriesByCreat typedef std::unordered_map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionsByEntryMap> SmartEventConditionContainer; typedef std::unordered_map<uint32, ConditionContainer> ConditionReferenceContainer;//only used for references -class ConditionMgr +class TC_GAME_API ConditionMgr { private: ConditionMgr(); diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index e74b7a9c319..cae1e0329e8 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -57,11 +57,11 @@ enum MMapDisableTypes namespace DisableMgr { - void LoadDisables(); - bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0); - void CheckQuestDisables(); - bool IsVMAPDisabledFor(uint32 entry, uint8 flags); - bool IsPathfindingEnabled(uint32 mapId); + TC_GAME_API void LoadDisables(); + TC_GAME_API bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0); + TC_GAME_API void CheckQuestDisables(); + TC_GAME_API bool IsVMAPDisabledFor(uint32 entry, uint8 flags); + TC_GAME_API bool IsPathfindingEnabled(uint32 mapId); } #endif //TRINITY_DISABLEMGR_H diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index aec278e7675..5088b750de4 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -24,96 +24,96 @@ #include <boost/regex.hpp> #include <array> -extern DB2Storage<AchievementEntry> sAchievementStore; -extern DB2Storage<AuctionHouseEntry> sAuctionHouseStore; -extern DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore; -extern DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore; -extern DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore; -extern DB2Storage<BattlePetSpeciesEntry> sBattlePetSpeciesStore; -extern DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore; -extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore; -extern DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore; -extern DB2Storage<CinematicSequencesEntry> sCinematicSequencesStore; -extern DB2Storage<CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; -extern DB2Storage<CreatureTypeEntry> sCreatureTypeStore; -extern DB2Storage<CriteriaEntry> sCriteriaStore; -extern DB2Storage<CriteriaTreeEntry> sCriteriaTreeStore; -extern DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore; -extern DB2Storage<DestructibleModelDataEntry> sDestructibleModelDataStore; -extern DB2Storage<DurabilityQualityEntry> sDurabilityQualityStore; -extern DB2Storage<GameObjectsEntry> sGameObjectsStore; -extern DB2Storage<GameTablesEntry> sGameTablesStore; -extern DB2Storage<GarrAbilityEntry> sGarrAbilityStore; -extern DB2Storage<GarrBuildingEntry> sGarrBuildingStore; -extern DB2Storage<GarrBuildingPlotInstEntry> sGarrBuildingPlotInstStore; -extern DB2Storage<GarrClassSpecEntry> sGarrClassSpecStore; -extern DB2Storage<GarrFollowerEntry> sGarrFollowerStore; -extern DB2Storage<GarrFollowerXAbilityEntry> sGarrFollowerXAbilityStore; -extern DB2Storage<GarrPlotBuildingEntry> sGarrPlotBuildingStore; -extern DB2Storage<GarrPlotEntry> sGarrPlotStore; -extern DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore; -extern DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore; -extern DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore; -extern DB2Storage<GlyphSlotEntry> sGlyphSlotStore; -extern DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore; -extern DB2Storage<HeirloomEntry> sHeirloomStore; -extern DB2Storage<HolidaysEntry> sHolidaysStore; -extern DB2Storage<ImportPriceArmorEntry> sImportPriceArmorStore; -extern DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore; -extern DB2Storage<ImportPriceShieldEntry> sImportPriceShieldStore; -extern DB2Storage<ImportPriceWeaponEntry> sImportPriceWeaponStore; -extern DB2Storage<ItemClassEntry> sItemClassStore; -extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore; -extern DB2Storage<ItemDisenchantLootEntry> sItemDisenchantLootStore; -extern DB2Storage<ItemEffectEntry> sItemEffectStore; -extern DB2Storage<ItemEntry> sItemStore; -extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore; -extern DB2Storage<ItemLimitCategoryEntry> sItemLimitCategoryStore; -extern DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore; -extern DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore; -extern DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore; -extern DB2Storage<ItemSparseEntry> sItemSparseStore; -extern DB2Storage<ItemSpecEntry> sItemSpecStore; -extern DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore; -extern DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore; -extern DB2Storage<MailTemplateEntry> sMailTemplateStore; -extern DB2Storage<ModifierTreeEntry> sModifierTreeStore; -extern DB2Storage<MountCapabilityEntry> sMountCapabilityStore; -extern DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore; -extern DB2Storage<PlayerConditionEntry> sPlayerConditionStore; -extern DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore; -extern DB2Storage<QuestSortEntry> sQuestSortStore; -extern DB2Storage<QuestXPEntry> sQuestXPStore; -extern DB2Storage<ScalingStatDistributionEntry> sScalingStatDistributionStore; -extern DB2Storage<SoundEntriesEntry> sSoundEntriesStore; -extern DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore; -extern DB2Storage<SpellCastTimesEntry> sSpellCastTimesStore; -extern DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore; -extern DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore; -extern DB2Storage<SpellDurationEntry> sSpellDurationStore; -extern DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore; -extern DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore; -extern DB2Storage<SpellMiscEntry> sSpellMiscStore; -extern DB2Storage<SpellPowerEntry> sSpellPowerStore; -extern DB2Storage<SpellRadiusEntry> sSpellRadiusStore; -extern DB2Storage<SpellRangeEntry> sSpellRangeStore; -extern DB2Storage<SpellReagentsEntry> sSpellReagentsStore; -extern DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore; -extern DB2Storage<SpellTotemsEntry> sSpellTotemsStore; -extern DB2Storage<SpellXSpellVisualEntry> sSpellXSpellVisualStore; -extern DB2Storage<TaxiNodesEntry> sTaxiNodesStore; -extern DB2Storage<TaxiPathEntry> sTaxiPathStore; -extern DB2Storage<TotemCategoryEntry> sTotemCategoryStore; -extern DB2Storage<ToyEntry> sToyStore; -extern DB2Storage<UnitPowerBarEntry> sUnitPowerBarStore; -extern DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore; - -extern TaxiMask sTaxiNodesMask; -extern TaxiMask sOldContinentsNodesMask; -extern TaxiMask sHordeTaxiNodesMask; -extern TaxiMask sAllianceTaxiNodesMask; -extern TaxiPathSetBySource sTaxiPathSetBySource; -extern TaxiPathNodesByPath sTaxiPathNodesByPath; +TC_GAME_API extern DB2Storage<AchievementEntry> sAchievementStore; +TC_GAME_API extern DB2Storage<AuctionHouseEntry> sAuctionHouseStore; +TC_GAME_API extern DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore; +TC_GAME_API extern DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore; +TC_GAME_API extern DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore; +TC_GAME_API extern DB2Storage<BattlePetSpeciesEntry> sBattlePetSpeciesStore; +TC_GAME_API extern DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore; +TC_GAME_API extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore; +TC_GAME_API extern DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore; +TC_GAME_API extern DB2Storage<CinematicSequencesEntry> sCinematicSequencesStore; +TC_GAME_API extern DB2Storage<CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; +TC_GAME_API extern DB2Storage<CreatureTypeEntry> sCreatureTypeStore; +TC_GAME_API extern DB2Storage<CriteriaEntry> sCriteriaStore; +TC_GAME_API extern DB2Storage<CriteriaTreeEntry> sCriteriaTreeStore; +TC_GAME_API extern DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore; +TC_GAME_API extern DB2Storage<DestructibleModelDataEntry> sDestructibleModelDataStore; +TC_GAME_API extern DB2Storage<DurabilityQualityEntry> sDurabilityQualityStore; +TC_GAME_API extern DB2Storage<GameObjectsEntry> sGameObjectsStore; +TC_GAME_API extern DB2Storage<GameTablesEntry> sGameTablesStore; +TC_GAME_API extern DB2Storage<GarrAbilityEntry> sGarrAbilityStore; +TC_GAME_API extern DB2Storage<GarrBuildingEntry> sGarrBuildingStore; +TC_GAME_API extern DB2Storage<GarrBuildingPlotInstEntry> sGarrBuildingPlotInstStore; +TC_GAME_API extern DB2Storage<GarrClassSpecEntry> sGarrClassSpecStore; +TC_GAME_API extern DB2Storage<GarrFollowerEntry> sGarrFollowerStore; +TC_GAME_API extern DB2Storage<GarrFollowerXAbilityEntry> sGarrFollowerXAbilityStore; +TC_GAME_API extern DB2Storage<GarrPlotBuildingEntry> sGarrPlotBuildingStore; +TC_GAME_API extern DB2Storage<GarrPlotEntry> sGarrPlotStore; +TC_GAME_API extern DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore; +TC_GAME_API extern DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore; +TC_GAME_API extern DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore; +TC_GAME_API extern DB2Storage<GlyphSlotEntry> sGlyphSlotStore; +TC_GAME_API extern DB2Storage<GuildPerkSpellsEntry> sGuildPerkSpellsStore; +TC_GAME_API extern DB2Storage<HeirloomEntry> sHeirloomStore; +TC_GAME_API extern DB2Storage<HolidaysEntry> sHolidaysStore; +TC_GAME_API extern DB2Storage<ImportPriceArmorEntry> sImportPriceArmorStore; +TC_GAME_API extern DB2Storage<ImportPriceQualityEntry> sImportPriceQualityStore; +TC_GAME_API extern DB2Storage<ImportPriceShieldEntry> sImportPriceShieldStore; +TC_GAME_API extern DB2Storage<ImportPriceWeaponEntry> sImportPriceWeaponStore; +TC_GAME_API extern DB2Storage<ItemClassEntry> sItemClassStore; +TC_GAME_API extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore; +TC_GAME_API extern DB2Storage<ItemDisenchantLootEntry> sItemDisenchantLootStore; +TC_GAME_API extern DB2Storage<ItemEffectEntry> sItemEffectStore; +TC_GAME_API extern DB2Storage<ItemEntry> sItemStore; +TC_GAME_API extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore; +TC_GAME_API extern DB2Storage<ItemLimitCategoryEntry> sItemLimitCategoryStore; +TC_GAME_API extern DB2Storage<ItemPriceBaseEntry> sItemPriceBaseStore; +TC_GAME_API extern DB2Storage<ItemRandomPropertiesEntry> sItemRandomPropertiesStore; +TC_GAME_API extern DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore; +TC_GAME_API extern DB2Storage<ItemSparseEntry> sItemSparseStore; +TC_GAME_API extern DB2Storage<ItemSpecEntry> sItemSpecStore; +TC_GAME_API extern DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore; +TC_GAME_API extern DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore; +TC_GAME_API extern DB2Storage<MailTemplateEntry> sMailTemplateStore; +TC_GAME_API extern DB2Storage<ModifierTreeEntry> sModifierTreeStore; +TC_GAME_API extern DB2Storage<MountCapabilityEntry> sMountCapabilityStore; +TC_GAME_API extern DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore; +TC_GAME_API extern DB2Storage<PlayerConditionEntry> sPlayerConditionStore; +TC_GAME_API extern DB2Storage<QuestMoneyRewardEntry> sQuestMoneyRewardStore; +TC_GAME_API extern DB2Storage<QuestSortEntry> sQuestSortStore; +TC_GAME_API extern DB2Storage<QuestXPEntry> sQuestXPStore; +TC_GAME_API extern DB2Storage<ScalingStatDistributionEntry> sScalingStatDistributionStore; +TC_GAME_API extern DB2Storage<SoundEntriesEntry> sSoundEntriesStore; +TC_GAME_API extern DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore; +TC_GAME_API extern DB2Storage<SpellCastTimesEntry> sSpellCastTimesStore; +TC_GAME_API extern DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore; +TC_GAME_API extern DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore; +TC_GAME_API extern DB2Storage<SpellDurationEntry> sSpellDurationStore; +TC_GAME_API extern DB2Storage<SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore; +TC_GAME_API extern DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore; +TC_GAME_API extern DB2Storage<SpellMiscEntry> sSpellMiscStore; +TC_GAME_API extern DB2Storage<SpellPowerEntry> sSpellPowerStore; +TC_GAME_API extern DB2Storage<SpellRadiusEntry> sSpellRadiusStore; +TC_GAME_API extern DB2Storage<SpellRangeEntry> sSpellRangeStore; +TC_GAME_API extern DB2Storage<SpellReagentsEntry> sSpellReagentsStore; +TC_GAME_API extern DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore; +TC_GAME_API extern DB2Storage<SpellTotemsEntry> sSpellTotemsStore; +TC_GAME_API extern DB2Storage<SpellXSpellVisualEntry> sSpellXSpellVisualStore; +TC_GAME_API extern DB2Storage<TaxiNodesEntry> sTaxiNodesStore; +TC_GAME_API extern DB2Storage<TaxiPathEntry> sTaxiPathStore; +TC_GAME_API extern DB2Storage<TotemCategoryEntry> sTotemCategoryStore; +TC_GAME_API extern DB2Storage<ToyEntry> sToyStore; +TC_GAME_API extern DB2Storage<UnitPowerBarEntry> sUnitPowerBarStore; +TC_GAME_API extern DB2Storage<WorldMapOverlayEntry> sWorldMapOverlayStore; + +TC_GAME_API extern TaxiMask sTaxiNodesMask; +TC_GAME_API extern TaxiMask sOldContinentsNodesMask; +TC_GAME_API extern TaxiMask sHordeTaxiNodesMask; +TC_GAME_API extern TaxiMask sAllianceTaxiNodesMask; +TC_GAME_API extern TaxiPathSetBySource sTaxiPathSetBySource; +TC_GAME_API extern TaxiPathNodesByPath sTaxiPathNodesByPath; struct HotfixNotify { @@ -131,7 +131,7 @@ typedef std::vector<HotfixNotify> HotfixData; static bool Compare(structure const* left, structure const* right); \ }; -class DB2Manager +class TC_GAME_API DB2Manager { public: DEFINE_DB2_SET_COMPARATOR(ChrClassesXPowerTypesEntry); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index d8af7418be4..2f30a00d3c0 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -25,50 +25,50 @@ #include "SharedDefines.h" // CharSections -CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color); +TC_GAME_API CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color); // ChrClasses -char const* GetClassName(uint8 class_, uint8 locale); +TC_GAME_API char const* GetClassName(uint8 class_, uint8 locale); // ChrRaces -char const* GetRaceName(uint8 race, uint8 locale); +TC_GAME_API char const* GetRaceName(uint8 race, uint8 locale); // ChrSpecialization typedef ChrSpecializationEntry const* ChrSpecializationByIndexArray[MAX_CLASSES][MAX_SPECIALIZATIONS]; // CreatureFamilty -char const* GetCreatureFamilyPetName(uint32 petfamily, uint32 locale); +TC_GAME_API char const* GetCreatureFamilyPetName(uint32 petfamily, uint32 locale); // Faction -std::vector<uint32> const* GetFactionTeamList(uint32 faction); +TC_GAME_API std::vector<uint32> const* GetFactionTeamList(uint32 faction); // ItemSetSpells typedef std::vector<ItemSetSpellEntry const*> ItemSetSpells; typedef std::unordered_map<uint32, ItemSetSpells> ItemSetSpellsStore; // LfgDungeons -LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); +TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty); // Light -uint32 GetDefaultMapLight(uint32 mapId); +TC_GAME_API uint32 GetDefaultMapLight(uint32 mapId); // LiquidType -uint32 GetLiquidFlags(uint32 liquidType); +TC_GAME_API uint32 GetLiquidFlags(uint32 liquidType); // MapDifficulty typedef std::unordered_map<uint32, std::unordered_map<uint32, MapDifficultyEntry const*>> MapDifficultyMap; -MapDifficultyEntry const* GetDefaultMapDifficulty(uint32 mapId, Difficulty* difficulty = nullptr); -MapDifficultyEntry const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); -MapDifficultyEntry const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty); +TC_GAME_API MapDifficultyEntry const* GetDefaultMapDifficulty(uint32 mapId, Difficulty* difficulty = nullptr); +TC_GAME_API MapDifficultyEntry const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); +TC_GAME_API MapDifficultyEntry const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty); // PvpDifficulty -PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level); -PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id); +TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level); +TC_GAME_API PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundBracketId id); // SkillRaceClassInfo typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap; typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds; -SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); +TC_GAME_API SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); // SpellEffectScaling typedef std::unordered_map<uint32, uint32> SpellEffectScallingByEffectId; @@ -77,21 +77,21 @@ typedef std::unordered_map<uint32, uint32> SpellEffectScallingByEffectId; typedef std::vector<TalentEntry const*> TalentsByPosition[MAX_CLASSES][MAX_TALENT_TIERS][MAX_TALENT_COLUMNS]; // TotemCategory -bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); +TC_GAME_API bool IsTotemCategoryCompatibleWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); // WMOAreaTable -WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid); +TC_GAME_API WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid); // WorldMapArea -uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); -void Zone2MapCoordinates(float &x, float &y, uint32 worldMapAreaId); -void Map2ZoneCoordinates(float &x, float &y, uint32 worldMapAreaId); +TC_GAME_API uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); +TC_GAME_API void Zone2MapCoordinates(float &x, float &y, uint32 worldMapAreaId); +TC_GAME_API void Map2ZoneCoordinates(float &x, float &y, uint32 worldMapAreaId); // WorldMapTransforms -void DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId = nullptr, DBCPosition2D* newPos = nullptr); +TC_GAME_API void DeterminaAlternateMapPosition(uint32 mapId, float x, float y, float z, uint32* newMapId = nullptr, DBCPosition2D* newPos = nullptr); -uint32 GetMaxLevelForExpansion(uint32 expansion); -uint32 GetExpansionForLevel(uint32 level); +TC_GAME_API uint32 GetMaxLevelForExpansion(uint32 expansion); +TC_GAME_API uint32 GetExpansionForLevel(uint32 level); template<class T> class GameTable @@ -121,111 +121,111 @@ private: GameTablesEntry const* _gtEntry; }; -extern DBCStorage<AnimKitEntry> sAnimKitStore; -extern DBCStorage<AreaTableEntry> sAreaTableStore; -extern DBCStorage<AreaTriggerEntry> sAreaTriggerStore; -extern DBCStorage<ArmorLocationEntry> sArmorLocationStore; -extern DBCStorage<BankBagSlotPricesEntry> sBankBagSlotPricesStore; -extern DBCStorage<BannedAddOnsEntry> sBannedAddOnsStore; -extern DBCStorage<BattlemasterListEntry> sBattlemasterListStore; -extern DBCStorage<CharSectionsEntry> sCharSectionsStore; -extern DBCStorage<CharTitlesEntry> sCharTitlesStore; -extern DBCStorage<ChatChannelsEntry> sChatChannelsStore; -extern DBCStorage<ChrClassesEntry> sChrClassesStore; -extern DBCStorage<ChrRacesEntry> sChrRacesStore; -extern DBCStorage<ChrSpecializationEntry> sChrSpecializationStore; -extern ChrSpecializationByIndexArray sChrSpecializationByIndexStore; -extern DBCStorage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; -extern DBCStorage<CreatureFamilyEntry> sCreatureFamilyStore; -extern DBCStorage<CreatureModelDataEntry> sCreatureModelDataStore; -extern DBCStorage<DifficultyEntry> sDifficultyStore; -extern DBCStorage<DungeonEncounterEntry> sDungeonEncounterStore; -extern DBCStorage<DurabilityCostsEntry> sDurabilityCostsStore; -extern DBCStorage<EmotesEntry> sEmotesStore; -extern DBCStorage<EmotesTextEntry> sEmotesTextStore; -extern DBCStorage<FactionEntry> sFactionStore; -extern DBCStorage<FactionTemplateEntry> sFactionTemplateStore; -extern DBCStorage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore; -extern DBCStorage<GemPropertiesEntry> sGemPropertiesStore; -extern DBCStorage<GlyphPropertiesEntry> sGlyphPropertiesStore; -extern DBCStorage<GuildColorBackgroundEntry> sGuildColorBackgroundStore; -extern DBCStorage<GuildColorBorderEntry> sGuildColorBorderStore; -extern DBCStorage<GuildColorEmblemEntry> sGuildColorEmblemStore; -extern DBCStorage<ItemArmorQualityEntry> sItemArmorQualityStore; -extern DBCStorage<ItemArmorShieldEntry> sItemArmorShieldStore; -extern DBCStorage<ItemArmorTotalEntry> sItemArmorTotalStore; -extern DBCStorage<ItemBagFamilyEntry> sItemBagFamilyStore; -extern DBCStorage<ItemDamageEntry> sItemDamageAmmoStore; -extern DBCStorage<ItemDamageEntry> sItemDamageOneHandCasterStore; -extern DBCStorage<ItemDamageEntry> sItemDamageOneHandStore; -extern DBCStorage<ItemDamageEntry> sItemDamageRangedStore; -extern DBCStorage<ItemDamageEntry> sItemDamageThrownStore; -extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandCasterStore; -extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandStore; -extern DBCStorage<ItemDamageEntry> sItemDamageWandStore; -extern DBCStorage<ItemSetEntry> sItemSetStore; -extern DBCStorage<ItemSetSpellEntry> sItemSetSpellStore; -extern ItemSetSpellsStore sItemSetSpellsStore; -extern DBCStorage<LFGDungeonEntry> sLFGDungeonStore; -extern DBCStorage<LiquidTypeEntry> sLiquidTypeStore; -extern DBCStorage<LockEntry> sLockStore; -extern DBCStorage<MapEntry> sMapStore; -extern MapDifficultyMap sMapDifficultyMap; -extern DBCStorage<MovieEntry> sMovieStore; -extern DBCStorage<PhaseEntry> sPhaseStore; -extern DBCStorage<PowerDisplayEntry> sPowerDisplayStore; -extern DBCStorage<QuestFactionRewEntry> sQuestFactionRewardStore; -extern DBCStorage<RandomPropertiesPointsEntry> sRandomPropertiesPointsStore; -extern DBCStorage<SkillLineAbilityEntry> sSkillLineAbilityStore; -extern DBCStorage<SkillLineEntry> sSkillLineStore; -extern DBCStorage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore; -extern DBCStorage<SpellAuraOptionsEntry> sSpellAuraOptionsStore; -extern DBCStorage<SpellCategoriesEntry> sSpellCategoriesStore; -extern DBCStorage<SpellCategoryEntry> sSpellCategoryStore; -extern DBCStorage<SpellCooldownsEntry> sSpellCooldownsStore; -extern DBCStorage<SpellEffectEntry> sSpellEffectStore; -extern DBCStorage<SpellEffectScalingEntry> sSpellEffectScalingStore; -extern SpellEffectScallingByEffectId sSpellEffectScallingByEffectId; -extern DBCStorage<SpellEntry> sSpellStore; -extern DBCStorage<SpellEquippedItemsEntry> sSpellEquippedItemsStore; -extern DBCStorage<SpellFocusObjectEntry> sSpellFocusObjectStore; -extern DBCStorage<SpellInterruptsEntry> sSpellInterruptsStore; -extern DBCStorage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore; -extern DBCStorage<SpellLevelsEntry> sSpellLevelsStore; -extern DBCStorage<SpellScalingEntry> sSpellScalingStore; -extern DBCStorage<SpellShapeshiftEntry> sSpellShapeshiftStore; -extern DBCStorage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore; -extern DBCStorage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore; -extern DBCStorage<SummonPropertiesEntry> sSummonPropertiesStore; -extern DBCStorage<TalentEntry> sTalentStore; -extern TalentsByPosition sTalentByPos; -extern DBCStorage<VehicleEntry> sVehicleStore; -extern DBCStorage<VehicleSeatEntry> sVehicleSeatStore; -extern DBCStorage<WMOAreaTableEntry> sWMOAreaTableStore; -extern DBCStorage<WorldSafeLocsEntry> sWorldSafeLocsStore; - -extern GameTable<GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore; -extern GameTable<GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore; -extern GameTable<GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore; -extern GameTable<GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore; -extern GameTable<GtChanceToSpellCritEntry> sGtChanceToSpellCritStore; -extern GameTable<GtCombatRatingsEntry> sGtCombatRatingsStore; -extern GameTable<GtItemSocketCostPerLevelEntry> sGtItemSocketCostPerLevelStore; -extern GameTable<GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore; -extern GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore; -extern GameTable<GtNpcTotalHpExp1Entry> sGtNpcTotalHpExp1Store; -extern GameTable<GtNpcTotalHpExp2Entry> sGtNpcTotalHpExp2Store; -extern GameTable<GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store; -extern GameTable<GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store; -extern GameTable<GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store; -extern GameTable<GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore; -extern GameTable<GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore; -extern GameTable<GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore; -extern GameTable<GtRegenMPPerSptEntry> sGtRegenMPPerSptStore; -extern GameTable<GtSpellScalingEntry> sGtSpellScalingStore; -extern GameTable<GtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore; - -void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale); -void LoadGameTables(const std::string& dataPath, uint32 defaultLocale); +TC_GAME_API extern DBCStorage<AnimKitEntry> sAnimKitStore; +TC_GAME_API extern DBCStorage<AreaTableEntry> sAreaTableStore; +TC_GAME_API extern DBCStorage<AreaTriggerEntry> sAreaTriggerStore; +TC_GAME_API extern DBCStorage<ArmorLocationEntry> sArmorLocationStore; +TC_GAME_API extern DBCStorage<BankBagSlotPricesEntry> sBankBagSlotPricesStore; +TC_GAME_API extern DBCStorage<BannedAddOnsEntry> sBannedAddOnsStore; +TC_GAME_API extern DBCStorage<BattlemasterListEntry> sBattlemasterListStore; +TC_GAME_API extern DBCStorage<CharSectionsEntry> sCharSectionsStore; +TC_GAME_API extern DBCStorage<CharTitlesEntry> sCharTitlesStore; +TC_GAME_API extern DBCStorage<ChatChannelsEntry> sChatChannelsStore; +TC_GAME_API extern DBCStorage<ChrClassesEntry> sChrClassesStore; +TC_GAME_API extern DBCStorage<ChrRacesEntry> sChrRacesStore; +TC_GAME_API extern DBCStorage<ChrSpecializationEntry> sChrSpecializationStore; +TC_GAME_API extern ChrSpecializationByIndexArray sChrSpecializationByIndexStore; +TC_GAME_API extern DBCStorage<CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore; +TC_GAME_API extern DBCStorage<CreatureFamilyEntry> sCreatureFamilyStore; +TC_GAME_API extern DBCStorage<CreatureModelDataEntry> sCreatureModelDataStore; +TC_GAME_API extern DBCStorage<DifficultyEntry> sDifficultyStore; +TC_GAME_API extern DBCStorage<DungeonEncounterEntry> sDungeonEncounterStore; +TC_GAME_API extern DBCStorage<DurabilityCostsEntry> sDurabilityCostsStore; +TC_GAME_API extern DBCStorage<EmotesEntry> sEmotesStore; +TC_GAME_API extern DBCStorage<EmotesTextEntry> sEmotesTextStore; +TC_GAME_API extern DBCStorage<FactionEntry> sFactionStore; +TC_GAME_API extern DBCStorage<FactionTemplateEntry> sFactionTemplateStore; +TC_GAME_API extern DBCStorage<GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore; +TC_GAME_API extern DBCStorage<GemPropertiesEntry> sGemPropertiesStore; +TC_GAME_API extern DBCStorage<GlyphPropertiesEntry> sGlyphPropertiesStore; +TC_GAME_API extern DBCStorage<GuildColorBackgroundEntry> sGuildColorBackgroundStore; +TC_GAME_API extern DBCStorage<GuildColorBorderEntry> sGuildColorBorderStore; +TC_GAME_API extern DBCStorage<GuildColorEmblemEntry> sGuildColorEmblemStore; +TC_GAME_API extern DBCStorage<ItemArmorQualityEntry> sItemArmorQualityStore; +TC_GAME_API extern DBCStorage<ItemArmorShieldEntry> sItemArmorShieldStore; +TC_GAME_API extern DBCStorage<ItemArmorTotalEntry> sItemArmorTotalStore; +TC_GAME_API extern DBCStorage<ItemBagFamilyEntry> sItemBagFamilyStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageAmmoStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageOneHandCasterStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageOneHandStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageRangedStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageThrownStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandCasterStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageTwoHandStore; +TC_GAME_API extern DBCStorage<ItemDamageEntry> sItemDamageWandStore; +TC_GAME_API extern DBCStorage<ItemSetEntry> sItemSetStore; +TC_GAME_API extern DBCStorage<ItemSetSpellEntry> sItemSetSpellStore; +TC_GAME_API extern ItemSetSpellsStore sItemSetSpellsStore; +TC_GAME_API extern DBCStorage<LFGDungeonEntry> sLFGDungeonStore; +TC_GAME_API extern DBCStorage<LiquidTypeEntry> sLiquidTypeStore; +TC_GAME_API extern DBCStorage<LockEntry> sLockStore; +TC_GAME_API extern DBCStorage<MapEntry> sMapStore; +TC_GAME_API extern MapDifficultyMap sMapDifficultyMap; +TC_GAME_API extern DBCStorage<MovieEntry> sMovieStore; +TC_GAME_API extern DBCStorage<PhaseEntry> sPhaseStore; +TC_GAME_API extern DBCStorage<PowerDisplayEntry> sPowerDisplayStore; +TC_GAME_API extern DBCStorage<QuestFactionRewEntry> sQuestFactionRewardStore; +TC_GAME_API extern DBCStorage<RandomPropertiesPointsEntry> sRandomPropertiesPointsStore; +TC_GAME_API extern DBCStorage<SkillLineAbilityEntry> sSkillLineAbilityStore; +TC_GAME_API extern DBCStorage<SkillLineEntry> sSkillLineStore; +TC_GAME_API extern DBCStorage<SkillRaceClassInfoEntry> sSkillRaceClassInfoStore; +TC_GAME_API extern DBCStorage<SpellAuraOptionsEntry> sSpellAuraOptionsStore; +TC_GAME_API extern DBCStorage<SpellCategoriesEntry> sSpellCategoriesStore; +TC_GAME_API extern DBCStorage<SpellCategoryEntry> sSpellCategoryStore; +TC_GAME_API extern DBCStorage<SpellCooldownsEntry> sSpellCooldownsStore; +TC_GAME_API extern DBCStorage<SpellEffectEntry> sSpellEffectStore; +TC_GAME_API extern DBCStorage<SpellEffectScalingEntry> sSpellEffectScalingStore; +TC_GAME_API extern SpellEffectScallingByEffectId sSpellEffectScallingByEffectId; +TC_GAME_API extern DBCStorage<SpellEntry> sSpellStore; +TC_GAME_API extern DBCStorage<SpellEquippedItemsEntry> sSpellEquippedItemsStore; +TC_GAME_API extern DBCStorage<SpellFocusObjectEntry> sSpellFocusObjectStore; +TC_GAME_API extern DBCStorage<SpellInterruptsEntry> sSpellInterruptsStore; +TC_GAME_API extern DBCStorage<SpellItemEnchantmentEntry> sSpellItemEnchantmentStore; +TC_GAME_API extern DBCStorage<SpellLevelsEntry> sSpellLevelsStore; +TC_GAME_API extern DBCStorage<SpellScalingEntry> sSpellScalingStore; +TC_GAME_API extern DBCStorage<SpellShapeshiftEntry> sSpellShapeshiftStore; +TC_GAME_API extern DBCStorage<SpellShapeshiftFormEntry> sSpellShapeshiftFormStore; +TC_GAME_API extern DBCStorage<SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore; +TC_GAME_API extern DBCStorage<SummonPropertiesEntry> sSummonPropertiesStore; +TC_GAME_API extern DBCStorage<TalentEntry> sTalentStore; +TC_GAME_API extern TalentsByPosition sTalentByPos; +TC_GAME_API extern DBCStorage<VehicleEntry> sVehicleStore; +TC_GAME_API extern DBCStorage<VehicleSeatEntry> sVehicleSeatStore; +TC_GAME_API extern DBCStorage<WMOAreaTableEntry> sWMOAreaTableStore; +TC_GAME_API extern DBCStorage<WorldSafeLocsEntry> sWorldSafeLocsStore; + +TC_GAME_API extern GameTable<GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore; +TC_GAME_API extern GameTable<GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore; +TC_GAME_API extern GameTable<GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore; +TC_GAME_API extern GameTable<GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore; +TC_GAME_API extern GameTable<GtChanceToSpellCritEntry> sGtChanceToSpellCritStore; +TC_GAME_API extern GameTable<GtCombatRatingsEntry> sGtCombatRatingsStore; +TC_GAME_API extern GameTable<GtItemSocketCostPerLevelEntry> sGtItemSocketCostPerLevelStore; +TC_GAME_API extern GameTable<GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore; +TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sGtNpcTotalHpStore; +TC_GAME_API extern GameTable<GtNpcTotalHpExp1Entry> sGtNpcTotalHpExp1Store; +TC_GAME_API extern GameTable<GtNpcTotalHpExp2Entry> sGtNpcTotalHpExp2Store; +TC_GAME_API extern GameTable<GtNpcTotalHpExp3Entry> sGtNpcTotalHpExp3Store; +TC_GAME_API extern GameTable<GtNpcTotalHpExp4Entry> sGtNpcTotalHpExp4Store; +TC_GAME_API extern GameTable<GtNpcTotalHpExp5Entry> sGtNpcTotalHpExp5Store; +TC_GAME_API extern GameTable<GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore; +TC_GAME_API extern GameTable<GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore; +TC_GAME_API extern GameTable<GtOCTLevelExperienceEntry> sGtOCTLevelExperienceStore; +TC_GAME_API extern GameTable<GtRegenMPPerSptEntry> sGtRegenMPPerSptStore; +TC_GAME_API extern GameTable<GtSpellScalingEntry> sGtSpellScalingStore; +TC_GAME_API extern GameTable<GtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore; + +TC_GAME_API void LoadDBCStores(const std::string& dataPath, uint32 defaultLocale); +TC_GAME_API void LoadGameTables(const std::string& dataPath, uint32 defaultLocale); #endif diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index 9aae994f168..b76c5e08d32 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -99,7 +99,7 @@ enum LfgAnswer LFG_ANSWER_AGREE = 1 }; -struct LfgLockInfoData +struct TC_GAME_API LfgLockInfoData { LfgLockInfoData(uint32 _lockStatus = 0, uint16 _requiredItemLevel = 0, float _currentItemLevel = 0) : lockStatus(_lockStatus), requiredItemLevel(_requiredItemLevel), currentItemLevel(_currentItemLevel) { } @@ -115,9 +115,9 @@ typedef std::map<ObjectGuid, LfgLockMap> LfgLockPartyMap; typedef std::map<ObjectGuid, uint8> LfgRolesMap; typedef std::map<ObjectGuid, ObjectGuid> LfgGroupsMap; -std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); -std::string GetRolesString(uint8 roles); -std::string GetStateString(LfgState state); +TC_GAME_API std::string ConcatenateDungeons(LfgDungeonSet const& dungeons); +TC_GAME_API std::string GetRolesString(uint8 roles); +TC_GAME_API std::string GetStateString(LfgState state); } // namespace lfg diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 7ae4777cd4d..62a41b6b350 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -31,7 +31,7 @@ enum LfgGroupEnum /** Stores all lfg data needed about a group. */ -class LfgGroupData +class TC_GAME_API LfgGroupData { public: LfgGroupData(); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 813be0afa4f..f38812549a6 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -295,7 +295,7 @@ struct LFGDungeonData uint32 Entry() const { return id + (type << 24); } }; -class LFGMgr +class TC_GAME_API LFGMgr { private: LFGMgr(); diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h index 859317ca956..91e4153a6d5 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.h +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -26,7 +26,7 @@ namespace lfg /** Stores all lfg data needed about the player. */ -class LfgPlayerData +class TC_GAME_API LfgPlayerData { public: LfgPlayerData(); diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index c9e2af7f480..c69b3cecb64 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -83,7 +83,7 @@ typedef std::map<ObjectGuid, LfgQueueData> LfgQueueDataContainer; /** Stores all data related to queue */ -class LFGQueue +class TC_GAME_API LFGQueue { public: diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 377614bc55d..ec64604a282 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -29,7 +29,7 @@ class Group; namespace lfg { -class LFGPlayerScript : public PlayerScript +class TC_GAME_API LFGPlayerScript : public PlayerScript { public: LFGPlayerScript(); @@ -40,7 +40,7 @@ class LFGPlayerScript : public PlayerScript void OnMapChanged(Player* player) override; }; -class LFGGroupScript : public GroupScript +class TC_GAME_API LFGGroupScript : public GroupScript { public: LFGGroupScript(); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 7a6581e13c4..e3caa6d2e95 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -23,7 +23,7 @@ class Unit; class SpellInfo; -class AreaTrigger : public WorldObject, public GridObject<AreaTrigger> +class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigger> { public: AreaTrigger(); diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index 4d2775789eb..f961a966796 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -46,7 +46,7 @@ enum CorpseFlags CORPSE_FLAG_LOOTABLE = 0x20 }; -class Corpse : public WorldObject, public GridObject<Corpse> +class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse> { public: explicit Corpse(CorpseType type = CORPSE_BONES); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 8ea2c3aa77e..96b04b32f84 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -74,7 +74,7 @@ enum CreatureFlagsExtra #define MAX_CREATURE_DIFFICULTIES 3 // from `creature_template` table -struct CreatureTemplate +struct TC_GAME_API CreatureTemplate { uint32 Entry; uint32 DifficultyEntry[MAX_CREATURE_DIFFICULTIES]; @@ -213,7 +213,7 @@ typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; #pragma pack(push, 1) // Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). -struct CreatureBaseStats +struct TC_GAME_API CreatureBaseStats { uint32 BaseHealth[MAX_EXPANSIONS]; uint32 BaseMana; @@ -440,7 +440,7 @@ struct TrainerSpell typedef std::unordered_map<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap; -struct TrainerSpellData +struct TC_GAME_API TrainerSpellData { TrainerSpellData() : trainerType(0) { } ~TrainerSpellData() { spellList.clear(); } @@ -462,7 +462,7 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns; typedef std::vector<uint8> CreatureTextRepeatIds; typedef std::unordered_map<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup; -class Creature : public Unit, public GridObject<Creature>, public MapObject +class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public MapObject { public: @@ -783,7 +783,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject CreatureTextRepeatGroup m_textRepeat; }; -class AssistDelayEvent : public BasicEvent +class TC_GAME_API AssistDelayEvent : public BasicEvent { public: AssistDelayEvent(ObjectGuid victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { } @@ -798,7 +798,7 @@ class AssistDelayEvent : public BasicEvent Unit& m_owner; }; -class ForcedDespawnDelayEvent : public BasicEvent +class TC_GAME_API ForcedDespawnDelayEvent : public BasicEvent { public: ForcedDespawnDelayEvent(Creature& owner) : BasicEvent(), m_owner(owner) { } diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 207cf6c2c95..36e72b66753 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -38,7 +38,7 @@ struct FormationInfo typedef std::unordered_map<ObjectGuid::LowType/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType; -class FormationMgr +class TC_GAME_API FormationMgr { private: FormationMgr() { } @@ -53,7 +53,7 @@ class FormationMgr CreatureGroupInfoType CreatureGroupMap; }; -class CreatureGroup +class TC_GAME_API CreatureGroup { private: Creature* m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index ba5a2e1f6ba..ebd3045be67 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -158,7 +158,7 @@ struct QuestMenuItem typedef std::vector<QuestMenuItem> QuestMenuItemList; -class GossipMenu +class TC_GAME_API GossipMenu { public: GossipMenu(); @@ -216,7 +216,7 @@ class GossipMenu LocaleConstant _locale; }; -class QuestMenu +class TC_GAME_API QuestMenu { public: QuestMenu(); @@ -233,7 +233,7 @@ class QuestMenu QuestMenuItemList _questMenuItems; }; -class PlayerMenu +class TC_GAME_API PlayerMenu { public: explicit PlayerMenu(WorldSession* session); diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index f3c7b0eda2e..d43e7fcf626 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -37,7 +37,7 @@ struct TempSummonData uint32 time; ///< Despawn time, usable only with certain temp summon types }; -class TempSummon : public Creature +class TC_GAME_API TempSummon : public Creature { public: explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); @@ -63,7 +63,7 @@ class TempSummon : public Creature ObjectGuid m_summonerGUID; }; -class Minion : public TempSummon +class TC_GAME_API Minion : public TempSummon { public: Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); @@ -80,7 +80,7 @@ class Minion : public TempSummon float m_followAngle; }; -class Guardian : public Minion +class TC_GAME_API Guardian : public Minion { public: Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); @@ -104,7 +104,7 @@ class Guardian : public Minion float m_statFromOwner[MAX_STATS]; }; -class Puppet : public Minion +class TC_GAME_API Puppet : public Minion { public: Puppet(SummonPropertiesEntry const* properties, Unit* owner); @@ -114,7 +114,7 @@ class Puppet : public Minion void RemoveFromWorld() override; }; -class ForcedUnsummonDelayEvent : public BasicEvent +class TC_GAME_API ForcedUnsummonDelayEvent : public BasicEvent { public: ForcedUnsummonDelayEvent(TempSummon& owner) : BasicEvent(), m_owner(owner) { } diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index 78ef5ca935f..09426a3c044 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -32,7 +32,7 @@ enum DynamicObjectType DYNAMIC_OBJECT_FARSIGHT_FOCUS = 0x2 }; -class DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MapObject +class TC_GAME_API DynamicObject : public WorldObject, public GridObject<DynamicObject>, public MapObject { public: DynamicObject(bool isWorldObject); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 010ea09347f..47d06e1492b 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -877,7 +877,7 @@ class GameObjectModel; // 5 sec for bobber catch #define FISHING_BOBBER_READY_TIME 5 -class GameObject : public WorldObject, public GridObject<GameObject>, public MapObject +class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>, public MapObject { public: explicit GameObject(); diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index 449301ee5ce..128213af4b4 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -25,7 +25,7 @@ #include "Item.h" #include "ItemTemplate.h" -class Bag : public Item +class TC_GAME_API Bag : public Item { public: diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 7d1c3761430..4836c7b7246 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -256,7 +256,7 @@ struct BonusData void AddBonus(uint32 type, int32 const (&values)[2]); }; -class Item : public Object +class TC_GAME_API Item : public Object { public: static Item* CreateItem(uint32 itemEntry, uint32 count, Player const* player = NULL); diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 99fe78bea2f..daf3473c5a8 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -44,7 +44,7 @@ typedef std::unordered_map<uint32, EnchStoreList> EnchantmentStore; static EnchantmentStore RandomItemEnch; -void LoadRandomEnchantmentsTable() +TC_GAME_API void LoadRandomEnchantmentsTable() { uint32 oldMSTime = getMSTime(); @@ -77,7 +77,7 @@ void LoadRandomEnchantmentsTable() TC_LOG_ERROR("server.loading", ">> Loaded 0 Item Enchantment definitions. DB table `item_enchantment_template` is empty."); } -uint32 GetItemEnchantMod(int32 entry) +TC_GAME_API uint32 GetItemEnchantMod(int32 entry) { if (!entry) return 0; @@ -118,7 +118,7 @@ uint32 GetItemEnchantMod(int32 entry) return 0; } -uint32 GenerateEnchSuffixFactor(uint32 item_id) +TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id) { ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); @@ -130,7 +130,7 @@ uint32 GenerateEnchSuffixFactor(uint32 item_id) return GetRandomPropertyPoints(itemProto->GetBaseItemLevel(), itemProto->GetQuality(), itemProto->GetInventoryType(), itemProto->GetSubClass()); } -uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass) +TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass) { uint32 propIndex; diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.h b/src/server/game/Entities/Item/ItemEnchantmentMgr.h index 25278caa512..ec84b13dec5 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.h +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.h @@ -21,9 +21,9 @@ #include "Common.h" -void LoadRandomEnchantmentsTable(); -uint32 GetItemEnchantMod(int32 entry); -uint32 GenerateEnchSuffixFactor(uint32 item_id); -uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subclass); +TC_GAME_API void LoadRandomEnchantmentsTable(); +TC_GAME_API uint32 GetItemEnchantMod(int32 entry); +TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id); +TC_GAME_API uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subclass); #endif diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 46584e1b5d3..aa65fdd3d6e 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -644,7 +644,7 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = class Player; -struct ItemTemplate +struct TC_GAME_API ItemTemplate { ItemEntry const* BasicData; ItemSparseEntry const* ExtendedData; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 4d54de20277..e3f22a41275 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -92,7 +92,7 @@ class ZoneScript; typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType; -class Object +class TC_GAME_API Object { public: virtual ~Object(); @@ -395,7 +395,7 @@ enum MapObjectCellMoveState MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move }; -class MapObject +class TC_GAME_API MapObject { friend class Map; //map for moving creatures friend class ObjectGridLoader; //grid loader for loading creatures @@ -420,7 +420,7 @@ class MapObject } }; -class WorldObject : public Object, public WorldLocation +class TC_GAME_API WorldObject : public Object, public WorldLocation { protected: explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index 5d7c19d48e7..6d063a901bd 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -177,3 +177,29 @@ void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high) TC_LOG_ERROR("misc", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high)); World::StopNow(ERROR_EXIT_CODE); } + +#define GUID_TRAIT_INSTANTIATE_GUID( HIGH_GUID ) \ + template class TC_GAME_API ObjectGuidGenerator< HIGH_GUID >; + +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Player) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Item) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Transport) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Guild) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Conversation) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Creature) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vehicle) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Pet) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::GameObject) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicObject) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AreaTrigger) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Corpse) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::LootObject) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::SceneObject) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Scenario) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AIGroup) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::DynamicDoor) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::Vignette) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::CallForHelp) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AIResource) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AILock) +GUID_TRAIT_INSTANTIATE_GUID(HighGuid::AILockTicket) diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index def19abca78..8bc2ee4df28 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -180,11 +180,11 @@ class PackedGuid; #pragma pack(push, 1) -class ObjectGuid +class TC_GAME_API ObjectGuid { - friend std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid); - friend ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); - friend ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid); + friend TC_GAME_API std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid); + friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); + friend TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid); public: static ObjectGuid const Empty; @@ -332,9 +332,9 @@ typedef std::unordered_set<ObjectGuid> GuidUnorderedSet; // maximum buffer size for packed guid is 18 bytes #define PACKED_GUID_MIN_BUFFER_SIZE 18 -class PackedGuid +class TC_GAME_API PackedGuid { - friend ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); + friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); public: explicit PackedGuid() : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid << uint16(0); } @@ -348,7 +348,7 @@ class PackedGuid ByteBuffer _packedGuid; }; -class ObjectGuidGeneratorBase +class TC_GAME_API ObjectGuidGeneratorBase { public: ObjectGuidGeneratorBase(ObjectGuid::LowType start = UI64LIT(1)) : _nextGuid(start) { } @@ -363,7 +363,7 @@ protected: }; template<HighGuid high> -class ObjectGuidGenerator : public ObjectGuidGeneratorBase +class TC_GAME_API ObjectGuidGenerator : public ObjectGuidGeneratorBase { public: explicit ObjectGuidGenerator(ObjectGuid::LowType start = UI64LIT(1)) : ObjectGuidGeneratorBase(start) { } @@ -376,12 +376,12 @@ public: } }; -ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); -ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid); -ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); -std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid); +TC_GAME_API std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid); namespace std { diff --git a/src/server/game/Entities/Object/ObjectPosSelector.h b/src/server/game/Entities/Object/ObjectPosSelector.h index 26a23678009..84c694abf08 100644 --- a/src/server/game/Entities/Object/ObjectPosSelector.h +++ b/src/server/game/Entities/Object/ObjectPosSelector.h @@ -30,7 +30,7 @@ inline UsedPosType operator ~(UsedPosType uptype) return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS; } -struct ObjectPosSelector +struct TC_GAME_API ObjectPosSelector { struct UsedPos { diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h index cc528b973f8..a941a2141f1 100644 --- a/src/server/game/Entities/Object/Position.h +++ b/src/server/game/Entities/Object/Position.h @@ -24,7 +24,7 @@ class ByteBuffer; -struct Position +struct TC_GAME_API Position { Position(float x = 0, float y = 0, float z = 0, float o = 0) : m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { } @@ -225,7 +225,7 @@ public: #define MAPID_INVALID 0xFFFFFFFF -class WorldLocation : public Position +class TC_GAME_API WorldLocation : public Position { public: explicit WorldLocation(uint32 mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f) @@ -256,11 +256,11 @@ public: uint32 m_mapId; }; -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); #endif // Trinity_game_Position_h__ diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h index 6d0d2fecca5..046916ea9d1 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h +++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h @@ -37,17 +37,17 @@ enum UpdatefieldFlags UF_FLAG_URGENT_SELF_ONLY = 0x400 }; -extern uint32 ItemUpdateFieldFlags[CONTAINER_END]; -extern uint32 ItemDynamicUpdateFieldFlags[CONTAINER_DYNAMIC_END]; -extern uint32 UnitUpdateFieldFlags[PLAYER_END]; -extern uint32 UnitDynamicUpdateFieldFlags[PLAYER_DYNAMIC_END]; -extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END]; -extern uint32 GameObjectDynamicUpdateFieldFlags[GAMEOBJECT_DYNAMIC_END]; -extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END]; -extern uint32 CorpseUpdateFieldFlags[CORPSE_END]; -extern uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END]; -extern uint32 SceneObjectUpdateFieldFlags[SCENEOBJECT_END]; -extern uint32 ConversationUpdateFieldFlags[CONVERSATION_END]; -extern uint32 ConversationDynamicUpdateFieldFlags[CONVERSATION_DYNAMIC_END]; +TC_GAME_API extern uint32 ItemUpdateFieldFlags[CONTAINER_END]; +TC_GAME_API extern uint32 ItemDynamicUpdateFieldFlags[CONTAINER_DYNAMIC_END]; +TC_GAME_API extern uint32 UnitUpdateFieldFlags[PLAYER_END]; +TC_GAME_API extern uint32 UnitDynamicUpdateFieldFlags[PLAYER_DYNAMIC_END]; +TC_GAME_API extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END]; +TC_GAME_API extern uint32 GameObjectDynamicUpdateFieldFlags[GAMEOBJECT_DYNAMIC_END]; +TC_GAME_API extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END]; +TC_GAME_API extern uint32 CorpseUpdateFieldFlags[CORPSE_END]; +TC_GAME_API extern uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END]; +TC_GAME_API extern uint32 SceneObjectUpdateFieldFlags[SCENEOBJECT_END]; +TC_GAME_API extern uint32 ConversationUpdateFieldFlags[CONVERSATION_END]; +TC_GAME_API extern uint32 ConversationDynamicUpdateFieldFlags[CONVERSATION_DYNAMIC_END]; #endif // _UPDATEFIELDFLAGS_H diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index bc989b515eb..170b881fa50 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -43,7 +43,7 @@ typedef std::vector<uint32> AutoSpellList; class Player; -class Pet : public Guardian +class TC_GAME_API Pet : public Guardian { public: explicit Pet(Player* owner, PetType type = MAX_PET_TYPE); diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h index 6870cd5732d..aa2f70d4df9 100644 --- a/src/server/game/Entities/Player/CollectionMgr.h +++ b/src/server/game/Entities/Player/CollectionMgr.h @@ -45,7 +45,7 @@ struct HeirloomData typedef std::map<uint32, bool> ToyBoxContainer; typedef std::map<uint32, HeirloomData> HeirloomContainer; -class CollectionMgr +class TC_GAME_API CollectionMgr { public: explicit CollectionMgr(WorldSession* owner) : _owner(owner) { } diff --git a/src/server/game/Entities/Player/KillRewarder.h b/src/server/game/Entities/Player/KillRewarder.h index 08530de900c..210e5ff0246 100644 --- a/src/server/game/Entities/Player/KillRewarder.h +++ b/src/server/game/Entities/Player/KillRewarder.h @@ -24,7 +24,7 @@ class Player; class Unit; class Group; -class KillRewarder +class TC_GAME_API KillRewarder { public: KillRewarder(Player* killer, Unit* victim, bool isBattleGround); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a381c2dd351..3fc5a7d76fd 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -115,7 +115,7 @@ struct PlayerSpell bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks }; -extern uint32 const MasterySpells[MAX_CLASSES]; +TC_GAME_API extern uint32 const MasterySpells[MAX_CLASSES]; enum TalentSpecialization // talent tabs { @@ -1012,7 +1012,7 @@ enum PlayerDelayedOperations // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) // Maximum money amount : 2^31 - 1 -extern uint64 const MAX_MONEY_AMOUNT; +TC_GAME_API extern uint64 const MAX_MONEY_AMOUNT; struct InstancePlayerBind { @@ -1146,7 +1146,7 @@ struct ResurrectionData static uint32 const DefaultTalentRowLevels[MAX_TALENT_TIERS] = { 15, 30, 45, 60, 75, 90, 100 }; static uint32 const DKTalentRowLevels[MAX_TALENT_TIERS] = { 57, 58, 59, 60, 75, 90, 100 }; -struct PlayerTalentInfo +struct TC_GAME_API PlayerTalentInfo { PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), @@ -1182,7 +1182,7 @@ private: PlayerTalentInfo(PlayerTalentInfo const&); }; -class Player : public Unit, public GridObject<Player> +class TC_GAME_API Player : public Unit, public GridObject<Player> { friend class WorldSession; friend void Item::AddToUpdateQueueOf(Player* player); @@ -2837,8 +2837,8 @@ class Player : public Unit, public GridObject<Player> WorldLocation _corpseLocation; }; -void AddItemsSetItem(Player* player, Item* item); -void RemoveItemsSetItem(Player* player, ItemTemplate const* proto); +TC_GAME_API void AddItemsSetItem(Player* player, Item* item); +TC_GAME_API void RemoveItemsSetItem(Player* player, ItemTemplate const* proto); // "the bodies of template functions must be made available in a header file" template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell* spell) diff --git a/src/server/game/Entities/Player/PlayerTaxi.h b/src/server/game/Entities/Player/PlayerTaxi.h index fb73042cb84..13aeed19ef8 100644 --- a/src/server/game/Entities/Player/PlayerTaxi.h +++ b/src/server/game/Entities/Player/PlayerTaxi.h @@ -6,7 +6,7 @@ #include "WorldSession.h" #include <map> -class PlayerTaxi +class TC_GAME_API PlayerTaxi { public: PlayerTaxi() { m_taximask.fill(0); } diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index aa022d383d9..df409106bdc 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -100,7 +100,7 @@ enum FriendsResult : uint8 #define SOCIALMGR_FRIEND_LIMIT 50u #define SOCIALMGR_IGNORE_LIMIT 50u -class PlayerSocial +class TC_GAME_API PlayerSocial { friend class SocialMgr; diff --git a/src/server/game/Entities/Player/TradeData.h b/src/server/game/Entities/Player/TradeData.h index 0dfded6c4aa..365f7a9fa82 100644 --- a/src/server/game/Entities/Player/TradeData.h +++ b/src/server/game/Entities/Player/TradeData.h @@ -31,7 +31,7 @@ enum TradeSlots class Item; class Player; -class TradeData +class TC_GAME_API TradeData { public: TradeData(Player* player, Player* trader) : diff --git a/src/server/game/Entities/Taxi/TaxiPathGraph.h b/src/server/game/Entities/Taxi/TaxiPathGraph.h index 434440acaef..24ec3ce9a7e 100644 --- a/src/server/game/Entities/Taxi/TaxiPathGraph.h +++ b/src/server/game/Entities/Taxi/TaxiPathGraph.h @@ -25,7 +25,7 @@ class Player; struct TaxiNodesEntry; -class TaxiPathGraph +class TC_GAME_API TaxiPathGraph { public: static TaxiPathGraph& Instance(); diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h index f0a4af3a3d7..14bb60f916f 100644 --- a/src/server/game/Entities/Totem/Totem.h +++ b/src/server/game/Entities/Totem/Totem.h @@ -35,7 +35,7 @@ enum TotemSpells SPELL_TOTEMIC_WRATH = 77747 }; -class Totem : public Minion +class TC_GAME_API Totem : public Minion { public: Totem(SummonPropertiesEntry const* properties, Unit* owner); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 9385d262ad8..f4d2866fbb3 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -25,7 +25,7 @@ struct CreatureData; -class Transport : public GameObject, public TransportBase +class TC_GAME_API Transport : public GameObject, public TransportBase { friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint32, uint32); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a371f08ce70..d6e3d01b09a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -609,8 +609,8 @@ enum UnitMoveType #define MAX_MOVE_TYPE 9 -extern float baseMoveSpeed[MAX_MOVE_TYPE]; -extern float playerBaseMoveSpeed[MAX_MOVE_TYPE]; +TC_GAME_API extern float baseMoveSpeed[MAX_MOVE_TYPE]; +TC_GAME_API extern float playerBaseMoveSpeed[MAX_MOVE_TYPE]; enum WeaponAttackType : uint16 { @@ -918,7 +918,7 @@ struct CleanDamage struct CalcDamageInfo; -class DamageInfo +class TC_GAME_API DamageInfo { private: Unit* const m_attacker; @@ -981,7 +981,7 @@ public: SpellSchoolMask GetSchoolMask() const { return _schoolMask; }; }; -class ProcEventInfo +class TC_GAME_API ProcEventInfo { public: ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, @@ -1039,7 +1039,7 @@ struct CalcDamageInfo }; // Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode -struct SpellNonMeleeDamage +struct TC_GAME_API SpellNonMeleeDamage { SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, uint32 _schoolMask); @@ -1198,7 +1198,7 @@ enum ActionBarIndex #define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) -struct CharmInfo +struct TC_GAME_API CharmInfo { public: explicit CharmInfo(Unit* unit); @@ -1302,7 +1302,7 @@ enum PlayerTotemType struct SpellProcEventEntry; // used only privately -class Unit : public WorldObject +class TC_GAME_API Unit : public WorldObject { public: typedef std::set<Unit*> AttackerSet; diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 10341a7c029..dbaaa3b7b9f 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -29,7 +29,7 @@ struct VehicleEntry; class Unit; class VehicleJoinEvent; -class Vehicle : public TransportBase +class TC_GAME_API Vehicle : public TransportBase { protected: friend bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry, bool); @@ -118,7 +118,7 @@ class Vehicle : public TransportBase PendingJoinEventContainer _pendingJoinEvents; ///< Collection of delayed join events for prospective passengers }; -class VehicleJoinEvent : public BasicEvent +class TC_GAME_API VehicleJoinEvent : public BasicEvent { friend class Vehicle; protected: diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index a01d361fc68..312f4de4b80 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -94,7 +94,7 @@ class Player; class Creature; class Quest; -class GameEventMgr +class TC_GAME_API GameEventMgr { private: GameEventMgr(); @@ -183,8 +183,8 @@ class GameEventMgr #define sGameEventMgr GameEventMgr::instance() -bool IsHolidayActive(HolidayIds id); -bool IsEventActive(uint16 event_id); +TC_GAME_API bool IsHolidayActive(HolidayIds id); +TC_GAME_API bool IsEventActive(uint16 event_id); #endif diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h index e35df29997b..2aa38ee6ad3 100644 --- a/src/server/game/Garrison/Garrison.h +++ b/src/server/game/Garrison/Garrison.h @@ -80,7 +80,7 @@ enum GarrisonFollowerStatus class GameObject; class Map; -class Garrison +class TC_GAME_API Garrison { public: struct Building diff --git a/src/server/game/Garrison/GarrisonMap.h b/src/server/game/Garrison/GarrisonMap.h index 57bc114970c..c04cf9d9a24 100644 --- a/src/server/game/Garrison/GarrisonMap.h +++ b/src/server/game/Garrison/GarrisonMap.h @@ -23,7 +23,7 @@ class Garrison; class Player; -class GarrisonMap : public Map +class TC_GAME_API GarrisonMap : public Map { public: GarrisonMap(uint32 id, time_t, uint32 instanceId, Map* parent, ObjectGuid const& owner); diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h index d09cb9c0930..6130fd67b25 100644 --- a/src/server/game/Garrison/GarrisonMgr.h +++ b/src/server/game/Garrison/GarrisonMgr.h @@ -38,7 +38,7 @@ struct GarrAbilities std::unordered_set<GarrAbilityEntry const*> Traits; }; -class GarrisonMgr +class TC_GAME_API GarrisonMgr { public: static GarrisonMgr& Instance(); diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 695591fb1c7..7cb21321f04 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -34,6 +34,48 @@ #include <boost/thread/shared_mutex.hpp> #include <boost/thread/locks.hpp> +template<class T> +void HashMapHolder<T>::Insert(T* o) +{ + boost::unique_lock<boost::shared_mutex> lock(*GetLock()); + + GetContainer()[o->GetGUID()] = o; +} + +template<class T> +void HashMapHolder<T>::Remove(T* o) +{ + boost::unique_lock<boost::shared_mutex> lock(*GetLock()); + + GetContainer().erase(o->GetGUID()); +} + +template<class T> +T* HashMapHolder<T>::Find(ObjectGuid guid) +{ + boost::shared_lock<boost::shared_mutex> lock(*GetLock()); + + typename MapType::iterator itr = GetContainer().find(guid); + return (itr != GetContainer().end()) ? itr->second : NULL; +} + +template<class T> +auto HashMapHolder<T>::GetContainer() -> MapType& +{ + static MapType _objectMap; + return _objectMap; +} + +template<class T> +boost::shared_mutex* HashMapHolder<T>::GetLock() +{ + static boost::shared_mutex _lock; + return &_lock; +} + +template class TC_GAME_API HashMapHolder<Player>; +template class TC_GAME_API HashMapHolder<Transport>; + WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid) { switch (guid.GetHigh()) @@ -226,12 +268,3 @@ void ObjectAccessor::SaveAllPlayers() for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) itr->second->SaveToDB(); } - -/// Define the static members of HashMapHolder - -template <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::_objectMap; -template <class T> boost::shared_mutex HashMapHolder<T>::_lock; - -/// Global definitions for the hashmap storage -template class HashMapHolder<Player>; -template class HashMapHolder<Transport>; diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 1c1ec6b3451..83bbdf42239 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -42,77 +42,57 @@ class WorldRunnable; class Transport; template <class T> -class HashMapHolder +class TC_GAME_API HashMapHolder { - public: - static_assert(std::is_same<Player, T>::value - || std::is_same<Transport, T>::value, - "Only Player and Transport can be registered in global HashMapHolder"); + //Non instanceable only static + HashMapHolder() { } - typedef std::unordered_map<ObjectGuid, T*> MapType; +public: + static_assert(std::is_same<Player, T>::value + || std::is_same<Transport, T>::value, + "Only Player and Transport can be registered in global HashMapHolder"); - static void Insert(T* o) - { - boost::unique_lock<boost::shared_mutex> lock(_lock); + typedef std::unordered_map<ObjectGuid, T*> MapType; - _objectMap[o->GetGUID()] = o; - } + static void Insert(T* o); - static void Remove(T* o) - { - boost::unique_lock<boost::shared_mutex> lock(_lock); + static void Remove(T* o); - _objectMap.erase(o->GetGUID()); - } + static T* Find(ObjectGuid guid); - static T* Find(ObjectGuid guid) - { - boost::shared_lock<boost::shared_mutex> lock(_lock); + static MapType& GetContainer(); - typename MapType::iterator itr = _objectMap.find(guid); - return (itr != _objectMap.end()) ? itr->second : NULL; - } - - static MapType& GetContainer() { return _objectMap; } - - static boost::shared_mutex* GetLock() { return &_lock; } - - private: - //Non instanceable only static - HashMapHolder() { } - - static boost::shared_mutex _lock; - static MapType _objectMap; + static boost::shared_mutex* GetLock(); }; namespace ObjectAccessor { // these functions return objects only if in map of specified object - WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&); - Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask); - Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid); - GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid); - Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid); - DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid); - AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid); - Unit* GetUnit(WorldObject const&, ObjectGuid const& guid); - Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid); - Pet* GetPet(WorldObject const&, ObjectGuid const& guid); - Player* GetPlayer(Map const*, ObjectGuid const& guid); - Player* GetPlayer(WorldObject const&, ObjectGuid const& guid); - Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&); + TC_GAME_API WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&); + TC_GAME_API Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask); + TC_GAME_API Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API Unit* GetUnit(WorldObject const&, ObjectGuid const& guid); + TC_GAME_API Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid); + TC_GAME_API Pet* GetPet(WorldObject const&, ObjectGuid const& guid); + TC_GAME_API Player* GetPlayer(Map const*, ObjectGuid const& guid); + TC_GAME_API Player* GetPlayer(WorldObject const&, ObjectGuid const& guid); + TC_GAME_API Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&); // these functions return objects if found in whole world // ACCESS LIKE THAT IS NOT THREAD SAFE - Player* FindPlayer(ObjectGuid const&); - Player* FindPlayerByName(std::string const& name); + TC_GAME_API Player* FindPlayer(ObjectGuid const&); + TC_GAME_API Player* FindPlayerByName(std::string const& name); // this returns Player even if he is not in world, for example teleporting - Player* FindConnectedPlayer(ObjectGuid const&); - Player* FindConnectedPlayerByName(std::string const& name); + TC_GAME_API Player* FindConnectedPlayer(ObjectGuid const&); + TC_GAME_API Player* FindConnectedPlayerByName(std::string const& name); // when using this, you must use the hashmapholder's lock - HashMapHolder<Player>::MapType const& GetPlayers(); + TC_GAME_API HashMapHolder<Player>::MapType const& GetPlayers(); template<class T> void AddObject(T* object) @@ -126,7 +106,8 @@ namespace ObjectAccessor HashMapHolder<T>::Remove(object); } - void SaveAllPlayers(); + TC_GAME_API void SaveAllPlayers(); }; #endif + diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 3bbbb2e7b19..f67d753cf7c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -376,15 +376,15 @@ typedef std::multimap<uint32, ScriptInfo> ScriptMap; typedef std::map<uint32, ScriptMap > ScriptMapMap; typedef std::multimap<uint32, uint32> SpellScriptsContainer; typedef std::pair<SpellScriptsContainer::iterator, SpellScriptsContainer::iterator> SpellScriptsBounds; -extern ScriptMapMap sSpellScripts; -extern ScriptMapMap sEventScripts; -extern ScriptMapMap sWaypointScripts; +TC_GAME_API extern ScriptMapMap sSpellScripts; +TC_GAME_API extern ScriptMapMap sEventScripts; +TC_GAME_API extern ScriptMapMap sWaypointScripts; std::string GetScriptsTableNameByType(ScriptsType type); ScriptMapMap* GetScriptsMapByType(ScriptsType type); std::string GetScriptCommandName(ScriptCommands command); -struct SpellClickInfo +struct TC_GAME_API SpellClickInfo { uint32 spellId; uint8 castFlags; @@ -646,7 +646,7 @@ SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const* rcEntry); #define MAX_PET_NAME 12 // max allowed by client name length #define MAX_CHARTER_NAME 24 // max allowed by client name length -bool normalizePlayerName(std::string& name); +TC_GAME_API bool normalizePlayerName(std::string& name); struct ExtendedPlayerName { @@ -664,7 +664,7 @@ struct LanguageDesc uint32 skill_id; }; -extern LanguageDesc lang_description[LANGUAGES_COUNT]; +TC_GAME_API extern LanguageDesc lang_description[LANGUAGES_COUNT]; LanguageDesc const* GetLanguageDescByID(uint32 lang); enum EncounterCreditType @@ -699,7 +699,7 @@ typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> PhaseInfo; // p class PlayerDumpReader; -class ObjectMgr +class TC_GAME_API ObjectMgr { friend class PlayerDumpReader; diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h index 9420bef4b9d..b567da43b69 100644 --- a/src/server/game/Grids/GridStates.h +++ b/src/server/game/Grids/GridStates.h @@ -24,32 +24,32 @@ class Map; -class GridState +class TC_GAME_API GridState { public: virtual ~GridState() { }; virtual void Update(Map &, NGridType&, GridInfo &, uint32 t_diff) const = 0; }; -class InvalidState : public GridState +class TC_GAME_API InvalidState : public GridState { public: void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; -class ActiveState : public GridState +class TC_GAME_API ActiveState : public GridState { public: void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; -class IdleState : public GridState +class TC_GAME_API IdleState : public GridState { public: void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; -class RemovalState : public GridState +class TC_GAME_API RemovalState : public GridState { public: void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 553de2f1a1f..66540add24b 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -40,7 +40,7 @@ class Player; namespace Trinity { - struct VisibleNotifier + struct TC_GAME_API VisibleNotifier { Player &i_player; UpdateData i_data; @@ -63,7 +63,7 @@ namespace Trinity void Visit(DynamicObjectMapType &); }; - struct PlayerRelocationNotifier : public VisibleNotifier + struct TC_GAME_API PlayerRelocationNotifier : public VisibleNotifier { PlayerRelocationNotifier(Player &player) : VisibleNotifier(player) { } @@ -72,7 +72,7 @@ namespace Trinity void Visit(PlayerMapType &); }; - struct CreatureRelocationNotifier + struct TC_GAME_API CreatureRelocationNotifier { Creature &i_creature; CreatureRelocationNotifier(Creature &c) : i_creature(c) { } @@ -81,7 +81,7 @@ namespace Trinity void Visit(PlayerMapType &); }; - struct DelayedUnitRelocation + struct TC_GAME_API DelayedUnitRelocation { Map &i_map; Cell &cell; @@ -94,7 +94,7 @@ namespace Trinity void Visit(PlayerMapType &); }; - struct AIRelocationNotifier + struct TC_GAME_API AIRelocationNotifier { Unit &i_unit; bool isCreature; @@ -123,7 +123,7 @@ namespace Trinity void Visit(AreaTriggerMapType &m) { updateObjects<AreaTrigger>(m); } }; - struct MessageDistDeliverer + struct TC_GAME_API MessageDistDeliverer { WorldObject* i_source; WorldPacket const* i_message; @@ -580,7 +580,7 @@ namespace Trinity // WorldObject check classes - class AnyDeadUnitObjectInRangeCheck + class TC_GAME_API AnyDeadUnitObjectInRangeCheck { public: AnyDeadUnitObjectInRangeCheck(Unit* searchObj, float range) : i_searchObj(searchObj), i_range(range) { } @@ -593,7 +593,7 @@ namespace Trinity float i_range; }; - class AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck + class TC_GAME_API AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck { public: AnyDeadUnitSpellTargetInRangeCheck(Unit* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check) diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index 11a54a3e7b0..d70f830ea68 100644 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -27,7 +27,7 @@ class ObjectWorldLoader; -class ObjectGridLoader +class TC_GAME_API ObjectGridLoader { friend class ObjectWorldLoader; @@ -56,7 +56,7 @@ class ObjectGridLoader }; //Stop the creatures before unloading the NGrid -class ObjectGridStoper +class TC_GAME_API ObjectGridStoper { public: void Visit(CreatureMapType &m); @@ -64,7 +64,7 @@ class ObjectGridStoper }; //Move the foreign creatures back to respawn positions before unloading the NGrid -class ObjectGridEvacuator +class TC_GAME_API ObjectGridEvacuator { public: void Visit(CreatureMapType &m); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index ba11dcff200..3c75bf6739f 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -188,7 +188,7 @@ struct RaidMarker /** request member stats checken **/ /// @todo uninvite people that not accepted invite -class Group +class TC_GAME_API Group { public: struct MemberSlot diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h index d9f39c1fbd9..f3031493782 100644 --- a/src/server/game/Groups/GroupMgr.h +++ b/src/server/game/Groups/GroupMgr.h @@ -20,7 +20,7 @@ #include "Group.h" -class GroupMgr +class TC_GAME_API GroupMgr { private: GroupMgr(); diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h index 4718dda1832..6e7373de7d7 100644 --- a/src/server/game/Groups/GroupReference.h +++ b/src/server/game/Groups/GroupReference.h @@ -24,7 +24,7 @@ class Group; class Player; -class GroupReference : public Reference<Group, Player> +class TC_GAME_API GroupReference : public Reference<Group, Player> { protected: uint8 iSubGroup; diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index e5ecef91649..d41a4f7c726 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -261,7 +261,7 @@ const uint32 GuildChallengeMaxLevelGoldReward[GUILD_CHALLENGES_TYPES] = { 0, 125 const uint32 GuildChallengesMaxCount[GUILD_CHALLENGES_TYPES] = { 0, 7, 1, 3, 0, 3 }; // Emblem info -class EmblemInfo +class TC_GAME_API EmblemInfo { public: EmblemInfo() : m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { } @@ -317,7 +317,7 @@ typedef std::vector <GuildBankRightsAndSlots> GuildBankRightsAndSlotsVec; typedef std::set <uint8> SlotIds; -class Guild +class TC_GAME_API Guild { private: // Class representing guild member diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index 16786757a6d..66aed6ad1a7 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -20,7 +20,7 @@ #include "Guild.h" -class GuildMgr +class TC_GAME_API GuildMgr { private: GuildMgr(); diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 699b6aec574..21b5c3ca5c3 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -41,7 +41,7 @@ class Group; - player-instance binds for permanent heroic/raid saves - group-instance binds (both solo and permanent) cache the player binds for the group leader */ -class InstanceSave +class TC_GAME_API InstanceSave { friend class InstanceSaveManager; public: @@ -147,7 +147,7 @@ class InstanceSave typedef std::unordered_map<uint64 /*PAIR64(map, difficulty)*/, time_t /*resetTime*/> ResetTimeByMapDifficultyMap; -class InstanceSaveManager +class TC_GAME_API InstanceSaveManager { friend class InstanceSave; diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index e2620c85504..2bb2f14ca12 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -83,7 +83,7 @@ struct BossBoundaryEntry AreaBoundary const* Boundary; }; -struct BossBoundaryData +struct TC_GAME_API BossBoundaryData { typedef std::vector<BossBoundaryEntry> StorageType; typedef StorageType::const_iterator const_iterator; @@ -138,7 +138,7 @@ typedef std::map<uint32 /*entry*/, MinionInfo> MinionInfoMap; typedef std::map<uint32 /*type*/, ObjectGuid /*guid*/> ObjectGuidMap; typedef std::map<uint32 /*entry*/, uint32 /*type*/> ObjectInfoMap; -class InstanceScript : public ZoneScript +class TC_GAME_API InstanceScript : public ZoneScript { public: explicit InstanceScript(Map* map) : instance(map), completedEncounters(0) { } diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index e57bf681b8a..a7e11e81970 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -1877,3 +1877,20 @@ void LoadLootTemplates_Reference() TC_LOG_INFO("server.loading", ">> Loaded refence loot templates in %u ms", GetMSTimeDiffToNow(oldMSTime)); } + +void LoadLootTables() +{ + LoadLootTemplates_Creature(); + LoadLootTemplates_Fishing(); + LoadLootTemplates_Gameobject(); + LoadLootTemplates_Item(); + LoadLootTemplates_Mail(); + LoadLootTemplates_Milling(); + LoadLootTemplates_Pickpocketing(); + LoadLootTemplates_Skinning(); + LoadLootTemplates_Disenchant(); + LoadLootTemplates_Prospecting(); + LoadLootTemplates_Spell(); + + LoadLootTemplates_Reference(); +} diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 05e045f4a2f..db12250f443 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -131,7 +131,7 @@ enum LootSlotType class Player; class LootStore; -struct LootStoreItem +struct TC_GAME_API LootStoreItem { uint32 itemid; // id of the item uint32 reference; // referenced TemplateleId @@ -154,7 +154,7 @@ struct LootStoreItem bool IsValid(LootStore const& store, uint32 entry) const; // Checks correctness of values }; -struct LootItem +struct TC_GAME_API LootItem { uint32 itemid; uint32 randomSuffix; @@ -210,7 +210,7 @@ typedef std::unordered_map<uint32, LootTemplate*> LootTemplateMap; typedef std::set<uint32> LootIdSet; -class LootStore +class TC_GAME_API LootStore { public: explicit LootStore(char const* name, char const* entryName, bool ratesAllowed) @@ -247,7 +247,7 @@ class LootStore bool m_ratesAllowed; }; -class LootTemplate +class TC_GAME_API LootTemplate { class LootGroup; // A set of loot definitions for items (refs are not allowed inside) typedef std::vector<LootGroup*> LootGroups; @@ -311,7 +311,7 @@ class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef> //===================================================== -struct Loot +struct TC_GAME_API Loot { QuestItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } QuestItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } @@ -414,48 +414,33 @@ private: uint32 _difficultyBonusTreeMod; }; -extern LootStore LootTemplates_Creature; -extern LootStore LootTemplates_Fishing; -extern LootStore LootTemplates_Gameobject; -extern LootStore LootTemplates_Item; -extern LootStore LootTemplates_Mail; -extern LootStore LootTemplates_Milling; -extern LootStore LootTemplates_Pickpocketing; -extern LootStore LootTemplates_Reference; -extern LootStore LootTemplates_Skinning; -extern LootStore LootTemplates_Disenchant; -extern LootStore LootTemplates_Prospecting; -extern LootStore LootTemplates_Spell; - -void LoadLootTemplates_Creature(); -void LoadLootTemplates_Fishing(); -void LoadLootTemplates_Gameobject(); -void LoadLootTemplates_Item(); -void LoadLootTemplates_Mail(); -void LoadLootTemplates_Milling(); -void LoadLootTemplates_Pickpocketing(); -void LoadLootTemplates_Skinning(); -void LoadLootTemplates_Disenchant(); -void LoadLootTemplates_Prospecting(); - -void LoadLootTemplates_Spell(); -void LoadLootTemplates_Reference(); - -inline void LoadLootTables() -{ - LoadLootTemplates_Creature(); - LoadLootTemplates_Fishing(); - LoadLootTemplates_Gameobject(); - LoadLootTemplates_Item(); - LoadLootTemplates_Mail(); - LoadLootTemplates_Milling(); - LoadLootTemplates_Pickpocketing(); - LoadLootTemplates_Skinning(); - LoadLootTemplates_Disenchant(); - LoadLootTemplates_Prospecting(); - LoadLootTemplates_Spell(); - - LoadLootTemplates_Reference(); -} +TC_GAME_API extern LootStore LootTemplates_Creature; +TC_GAME_API extern LootStore LootTemplates_Fishing; +TC_GAME_API extern LootStore LootTemplates_Gameobject; +TC_GAME_API extern LootStore LootTemplates_Item; +TC_GAME_API extern LootStore LootTemplates_Mail; +TC_GAME_API extern LootStore LootTemplates_Milling; +TC_GAME_API extern LootStore LootTemplates_Pickpocketing; +TC_GAME_API extern LootStore LootTemplates_Reference; +TC_GAME_API extern LootStore LootTemplates_Skinning; +TC_GAME_API extern LootStore LootTemplates_Disenchant; +TC_GAME_API extern LootStore LootTemplates_Prospecting; +TC_GAME_API extern LootStore LootTemplates_Spell; + +TC_GAME_API void LoadLootTemplates_Creature(); +TC_GAME_API void LoadLootTemplates_Fishing(); +TC_GAME_API void LoadLootTemplates_Gameobject(); +TC_GAME_API void LoadLootTemplates_Item(); +TC_GAME_API void LoadLootTemplates_Mail(); +TC_GAME_API void LoadLootTemplates_Milling(); +TC_GAME_API void LoadLootTemplates_Pickpocketing(); +TC_GAME_API void LoadLootTemplates_Skinning(); +TC_GAME_API void LoadLootTemplates_Disenchant(); +TC_GAME_API void LoadLootTemplates_Prospecting(); + +TC_GAME_API void LoadLootTemplates_Spell(); +TC_GAME_API void LoadLootTemplates_Reference(); + +TC_GAME_API void LoadLootTables(); #endif diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h index 8bbd378f5d7..0031d3f7c3e 100644 --- a/src/server/game/Mails/Mail.h +++ b/src/server/game/Mails/Mail.h @@ -80,7 +80,7 @@ enum MailShowFlags MAIL_SHOW_RETURN = 0x0010 }; -class MailSender +class TC_GAME_API MailSender { public: // Constructors MailSender(MailMessageType messageType, ObjectGuid::LowType sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_DEFAULT) @@ -101,7 +101,7 @@ class MailSender MailStationery m_stationery; }; -class MailReceiver +class TC_GAME_API MailReceiver { public: // Constructors explicit MailReceiver(ObjectGuid::LowType receiver_lowguid) : m_receiver(NULL), m_receiver_lowguid(receiver_lowguid) { } @@ -115,7 +115,7 @@ class MailReceiver ObjectGuid::LowType m_receiver_lowguid; }; -class MailDraft +class TC_GAME_API MailDraft { typedef std::map<ObjectGuid::LowType, Item*> MailItemMap; @@ -163,7 +163,7 @@ struct MailItemInfo }; typedef std::vector<MailItemInfo> MailItemInfoVec; -struct Mail +struct TC_GAME_API Mail { uint32 messageID; uint8 messageType; diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h index a134b783ca6..a8780ddb60f 100644 --- a/src/server/game/Maps/AreaBoundary.h +++ b/src/server/game/Maps/AreaBoundary.h @@ -20,7 +20,7 @@ #include "Position.h" -class AreaBoundary +class TC_GAME_API AreaBoundary { public: enum BoundaryType @@ -66,7 +66,7 @@ class AreaBoundary bool m_isInvertedBoundary; }; -class RectangleBoundary : public AreaBoundary +class TC_GAME_API RectangleBoundary : public AreaBoundary { public: // X axis is north/south, Y axis is east/west, larger values are northwest @@ -79,7 +79,7 @@ class RectangleBoundary : public AreaBoundary const float _minX, _maxX, _minY, _maxY; }; -class CircleBoundary : public AreaBoundary +class TC_GAME_API CircleBoundary : public AreaBoundary { public: CircleBoundary(Position const& center, double radius, bool isInverted = false); @@ -95,7 +95,7 @@ class CircleBoundary : public AreaBoundary const double _radiusSq; }; -class EllipseBoundary : public AreaBoundary +class TC_GAME_API EllipseBoundary : public AreaBoundary { public: EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted = false); @@ -109,7 +109,7 @@ class EllipseBoundary : public AreaBoundary const double _radiusYSq, _scaleXSq; }; -class TriangleBoundary : public AreaBoundary +class TC_GAME_API TriangleBoundary : public AreaBoundary { public: TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted = false); @@ -123,7 +123,7 @@ class TriangleBoundary : public AreaBoundary const double _abx, _bcx, _cax, _aby, _bcy, _cay; }; -class ParallelogramBoundary : public AreaBoundary +class TC_GAME_API ParallelogramBoundary : public AreaBoundary { public: // Note: AB must be orthogonal to AD @@ -138,7 +138,7 @@ class ParallelogramBoundary : public AreaBoundary const double _abx, _dax, _aby, _day; }; -class ZRangeBoundary : public AreaBoundary +class TC_GAME_API ZRangeBoundary : public AreaBoundary { public: ZRangeBoundary(float minZ, float maxZ, bool isInverted = false); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index d1beee19ac3..d1d13e428f9 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3019,17 +3019,17 @@ void Map::RemoveFromActive(DynamicObject* obj) RemoveFromActiveHelper(obj); } -template bool Map::AddToMap(Corpse*); -template bool Map::AddToMap(Creature*); -template bool Map::AddToMap(GameObject*); -template bool Map::AddToMap(DynamicObject*); -template bool Map::AddToMap(AreaTrigger*); - -template void Map::RemoveFromMap(Corpse*, bool); -template void Map::RemoveFromMap(Creature*, bool); -template void Map::RemoveFromMap(GameObject*, bool); -template void Map::RemoveFromMap(DynamicObject*, bool); -template void Map::RemoveFromMap(AreaTrigger*, bool); +template TC_GAME_API bool Map::AddToMap(Corpse*); +template TC_GAME_API bool Map::AddToMap(Creature*); +template TC_GAME_API bool Map::AddToMap(GameObject*); +template TC_GAME_API bool Map::AddToMap(DynamicObject*); +template TC_GAME_API bool Map::AddToMap(AreaTrigger*); + +template TC_GAME_API void Map::RemoveFromMap(Corpse*, bool); +template TC_GAME_API void Map::RemoveFromMap(Creature*, bool); +template TC_GAME_API void Map::RemoveFromMap(GameObject*, bool); +template TC_GAME_API void Map::RemoveFromMap(DynamicObject*, bool); +template TC_GAME_API void Map::RemoveFromMap(AreaTrigger*, bool); /* ******* Dungeon Instance Maps ******* */ diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index d51f05bc32a..75d184b19a6 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -156,7 +156,7 @@ struct LiquidData float depth_level; }; -class GridMap +class TC_GAME_API GridMap { uint32 _flags; union{ @@ -256,7 +256,7 @@ typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMa typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer; -class Map : public GridRefManager<NGridType> +class TC_GAME_API Map : public GridRefManager<NGridType> { friend class MapReference; public: @@ -280,6 +280,7 @@ class Map : public GridRefManager<NGridType> virtual bool AddPlayerToMap(Player* player, bool initPlayer = true); virtual void RemovePlayerFromMap(Player*, bool); + template<class T> bool AddToMap(T *); template<class T> void RemoveFromMap(T *, bool); @@ -295,7 +296,8 @@ class Map : public GridRefManager<NGridType> void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true); void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation); - template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor); + template<class T, class CONTAINER> + void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor); bool IsRemovalGrid(float x, float y) const { @@ -753,7 +755,7 @@ enum InstanceResetMethod INSTANCE_RESET_RESPAWN_DELAY }; -class InstanceMap : public Map +class TC_GAME_API InstanceMap : public Map { public: InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent); @@ -782,7 +784,7 @@ class InstanceMap : public Map uint32 i_script_id; }; -class BattlegroundMap : public Map +class TC_GAME_API BattlegroundMap : public Map { public: BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode); diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h index 4fb334cb0ce..7d89d446846 100644 --- a/src/server/game/Maps/MapInstanced.h +++ b/src/server/game/Maps/MapInstanced.h @@ -25,7 +25,7 @@ class GarrisonMap; -class MapInstanced : public Map +class TC_GAME_API MapInstanced : public Map { friend class MapManager; public: diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 5d679cbe4d9..a4075f73563 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -28,7 +28,7 @@ class Transport; struct TransportCreatureProto; -class MapManager +class TC_GAME_API MapManager { public: static MapManager* instance(); diff --git a/src/server/game/Maps/MapUpdater.h b/src/server/game/Maps/MapUpdater.h index fce4a26c36a..7fdcc24d530 100644 --- a/src/server/game/Maps/MapUpdater.h +++ b/src/server/game/Maps/MapUpdater.h @@ -28,7 +28,7 @@ class MapUpdateRequest; class Map; -class MapUpdater +class TC_GAME_API MapUpdater { public: diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index b034751a6b4..d058c0bb111 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -83,7 +83,7 @@ struct TransportTemplate typedef std::map<uint32, TransportAnimationEntry const*> TransportPathContainer; typedef std::map<uint32, TransportRotationEntry const*> TransportPathRotationContainer; -struct TransportAnimation +struct TC_GAME_API TransportAnimation { TransportAnimation() : TotalTime(0) { } @@ -97,7 +97,7 @@ struct TransportAnimation typedef std::map<uint32, TransportAnimation> TransportAnimationContainer; -class TransportMgr +class TC_GAME_API TransportMgr { friend void DB2Manager::LoadStores(std::string const&, uint32); diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 3cb56e7d9d9..da1f9ef90f3 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -79,7 +79,7 @@ enum RotateDirection // assume it is 25 yard per 0.6 second #define SPEED_CHARGE 42.0f -class MotionMaster //: private std::stack<MovementGenerator *> +class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *> { private: //typedef std::stack<MovementGenerator *> Impl; diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 56e5dc7058a..d9dd17fabc2 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -27,7 +27,7 @@ class Unit; -class MovementGenerator +class TC_GAME_API MovementGenerator { public: virtual ~MovementGenerator(); diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index 9aa778c5651..161f9e3e970 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -32,7 +32,7 @@ class IdleMovementGenerator : public MovementGenerator MovementGeneratorType GetMovementGeneratorType() const override { return IDLE_MOTION_TYPE; } }; -extern IdleMovementGenerator si_idleMovement; +TC_GAME_API extern IdleMovementGenerator si_idleMovement; class RotateMovementGenerator : public MovementGenerator { diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index 71e0e88f0b2..3cad62abf25 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -49,7 +49,7 @@ enum PathType PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length }; -class PathGenerator +class TC_GAME_API PathGenerator { public: explicit PathGenerator(Unit const* owner); diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index 439cd9a14a4..24a6d85fcbc 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -46,7 +46,7 @@ namespace Movement // MoveSpline represents smooth catmullrom or linear curve and point that moves belong it // curve can be cyclic - in this case movement will be cyclic // point can have vertical acceleration motion component (used in fall, parabolic movement) - class MoveSpline + class TC_GAME_API MoveSpline { friend class WorldPackets::Movement::CommonMovement; friend class WorldPackets::Movement::MonsterMove; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index c968f660f58..421a8d6b06c 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -35,7 +35,7 @@ namespace Movement }; // Transforms coordinates from global to transport offsets - class TransportPathTransform + class TC_GAME_API TransportPathTransform { public: TransportPathTransform(Unit* owner, bool transformForTransport) @@ -49,7 +49,7 @@ namespace Movement /* Initializes and launches spline movement */ - class MoveSplineInit + class TC_GAME_API MoveSplineInit { public: diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index 927707bfd56..56d8842e700 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -77,10 +77,10 @@ namespace Movement typedef counter<uint32, 0xFFFFFFFF> UInt32Counter; - extern float gravity; - extern UInt32Counter splineIdGen; - extern std::string MovementFlags_ToString(uint32 flags); - extern std::string MovementFlagsExtra_ToString(uint32 flags); + TC_GAME_API extern float gravity; + TC_GAME_API extern UInt32Counter splineIdGen; + TC_GAME_API extern std::string MovementFlags_ToString(uint32 flags); + TC_GAME_API extern std::string MovementFlagsExtra_ToString(uint32 flags); } #endif // TRINITYSERVER_TYPEDEFS_H diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index a1f98c52b0b..63dc4184308 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -44,7 +44,7 @@ struct WaypointData typedef std::vector<WaypointData*> WaypointPath; typedef std::unordered_map<uint32, WaypointPath> WaypointPathContainer; -class WaypointMgr +class TC_GAME_API WaypointMgr { public: static WaypointMgr* instance(); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index 2be74279ae7..5996b4126e4 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -84,7 +84,7 @@ class Unit; struct GossipMenuItems; class OutdoorPvP; -class OPvPCapturePoint +class TC_GAME_API OPvPCapturePoint { public: @@ -185,7 +185,7 @@ class OPvPCapturePoint }; // base class for specific outdoor pvp handlers -class OutdoorPvP : public ZoneScript +class TC_GAME_API OutdoorPvP : public ZoneScript { friend class OutdoorPvPMgr; diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index b1158075c57..e53a78ac271 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -35,7 +35,7 @@ struct OutdoorPvPData }; // class to handle player enter / leave / areatrigger / GO use events -class OutdoorPvPMgr +class TC_GAME_API OutdoorPvPMgr { private: OutdoorPvPMgr(); diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 3461813f7c4..4e51641c502 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -60,6 +60,11 @@ bool ActivePoolData::IsActiveObject<Quest>(uint64 quest_id) const return mActiveQuests.find(quest_id) != mActiveQuests.end(); } +template TC_GAME_API bool ActivePoolData::IsActiveObject<Creature>(uint64) const; +template TC_GAME_API bool ActivePoolData::IsActiveObject<GameObject>(uint64) const; +template TC_GAME_API bool ActivePoolData::IsActiveObject<Pool>(uint64) const; +template TC_GAME_API bool ActivePoolData::IsActiveObject<Quest>(uint64) const; + template<> void ActivePoolData::ActivateObject<Creature>(uint64 db_guid, uint32 pool_id) { diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h index 5491d7d2069..b38d27f9c94 100644 --- a/src/server/game/Pools/PoolMgr.h +++ b/src/server/game/Pools/PoolMgr.h @@ -43,7 +43,7 @@ class Pool // for Pool of Pool typedef std::set<uint64> ActivePoolObjects; typedef std::map<uint64, uint32> ActivePoolPools; -class ActivePoolData +class TC_GAME_API ActivePoolData { public: template<typename T> @@ -66,7 +66,7 @@ class ActivePoolData }; template <class T> -class PoolGroup +class TC_GAME_API PoolGroup { typedef std::vector<PoolObject> PoolObjectList; public: @@ -101,7 +101,7 @@ typedef std::multimap<uint32, uint32> PooledQuestRelation; typedef std::pair<PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator> PooledQuestRelationBounds; typedef std::pair<PooledQuestRelation::iterator, PooledQuestRelation::iterator> PooledQuestRelationBoundsNC; -class PoolMgr +class TC_GAME_API PoolMgr { private: PoolMgr(); diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 8b27be40c20..b0df26f1ca5 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -276,7 +276,7 @@ typedef std::vector<QuestObjective> QuestObjectives; // This Quest class provides a convenient way to access a few pretotaled (cached) quest details, // all base quest information, and any utility functions such as generating the amount of // xp to give -class Quest +class TC_GAME_API Quest { friend class ObjectMgr; friend class Player; diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index 224a928bbac..f2a5f3ba1f3 100644 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -61,7 +61,7 @@ typedef std::map<uint32, ReputationRank> ForcedReactions; class Player; -class ReputationMgr +class TC_GAME_API ReputationMgr { public: // constructors and global modifiers explicit ReputationMgr(Player* owner) : _player(owner), diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 2184899de02..9b403e608c1 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1691,32 +1691,32 @@ template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::Scripts; template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0; // Specialize for each script type class like so: -template class ScriptRegistry<SpellScriptLoader>; -template class ScriptRegistry<ServerScript>; -template class ScriptRegistry<WorldScript>; -template class ScriptRegistry<FormulaScript>; -template class ScriptRegistry<WorldMapScript>; -template class ScriptRegistry<InstanceMapScript>; -template class ScriptRegistry<BattlegroundMapScript>; -template class ScriptRegistry<ItemScript>; -template class ScriptRegistry<CreatureScript>; -template class ScriptRegistry<GameObjectScript>; -template class ScriptRegistry<AreaTriggerScript>; -template class ScriptRegistry<BattlegroundScript>; -template class ScriptRegistry<OutdoorPvPScript>; -template class ScriptRegistry<CommandScript>; -template class ScriptRegistry<WeatherScript>; -template class ScriptRegistry<AuctionHouseScript>; -template class ScriptRegistry<ConditionScript>; -template class ScriptRegistry<VehicleScript>; -template class ScriptRegistry<DynamicObjectScript>; -template class ScriptRegistry<TransportScript>; -template class ScriptRegistry<AchievementCriteriaScript>; -template class ScriptRegistry<PlayerScript>; -template class ScriptRegistry<GuildScript>; -template class ScriptRegistry<GroupScript>; -template class ScriptRegistry<UnitScript>; -template class ScriptRegistry<AccountScript>; +template class TC_GAME_API ScriptRegistry<SpellScriptLoader>; +template class TC_GAME_API ScriptRegistry<ServerScript>; +template class TC_GAME_API ScriptRegistry<WorldScript>; +template class TC_GAME_API ScriptRegistry<FormulaScript>; +template class TC_GAME_API ScriptRegistry<WorldMapScript>; +template class TC_GAME_API ScriptRegistry<InstanceMapScript>; +template class TC_GAME_API ScriptRegistry<BattlegroundMapScript>; +template class TC_GAME_API ScriptRegistry<ItemScript>; +template class TC_GAME_API ScriptRegistry<CreatureScript>; +template class TC_GAME_API ScriptRegistry<GameObjectScript>; +template class TC_GAME_API ScriptRegistry<AreaTriggerScript>; +template class TC_GAME_API ScriptRegistry<BattlegroundScript>; +template class TC_GAME_API ScriptRegistry<OutdoorPvPScript>; +template class TC_GAME_API ScriptRegistry<CommandScript>; +template class TC_GAME_API ScriptRegistry<WeatherScript>; +template class TC_GAME_API ScriptRegistry<AuctionHouseScript>; +template class TC_GAME_API ScriptRegistry<ConditionScript>; +template class TC_GAME_API ScriptRegistry<VehicleScript>; +template class TC_GAME_API ScriptRegistry<DynamicObjectScript>; +template class TC_GAME_API ScriptRegistry<TransportScript>; +template class TC_GAME_API ScriptRegistry<AchievementCriteriaScript>; +template class TC_GAME_API ScriptRegistry<PlayerScript>; +template class TC_GAME_API ScriptRegistry<GuildScript>; +template class TC_GAME_API ScriptRegistry<GroupScript>; +template class TC_GAME_API ScriptRegistry<UnitScript>; +template class TC_GAME_API ScriptRegistry<AccountScript>; // Undefine utility macros. #undef GET_SCRIPT_RET diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 79c1bc3f60f..f75446048ff 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -146,7 +146,7 @@ struct OutdoorPvPData; event on all registered scripts of that type. */ -class ScriptObject +class TC_GAME_API ScriptObject { friend class ScriptMgr; @@ -185,7 +185,7 @@ template<class TObject> class UpdatableScript virtual void OnUpdate(TObject* /*obj*/, uint32 /*diff*/) { } }; -class SpellScriptLoader : public ScriptObject +class TC_GAME_API SpellScriptLoader : public ScriptObject { protected: @@ -200,7 +200,7 @@ class SpellScriptLoader : public ScriptObject virtual AuraScript* GetAuraScript() const { return NULL; } }; -class ServerScript : public ScriptObject +class TC_GAME_API ServerScript : public ScriptObject { protected: @@ -330,14 +330,14 @@ template<class TMap> class MapScript : public UpdatableScript<TMap> virtual void OnPlayerLeave(TMap* /*map*/, Player* /*player*/) { } }; -class WorldMapScript : public ScriptObject, public MapScript<Map> +class TC_GAME_API WorldMapScript : public ScriptObject, public MapScript<Map> { protected: WorldMapScript(const char* name, uint32 mapId); }; -class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap> +class TC_GAME_API InstanceMapScript : public ScriptObject, public MapScript<InstanceMap> { protected: @@ -349,14 +349,14 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap> virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; } }; -class BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap> +class TC_GAME_API BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap> { protected: BattlegroundMapScript(const char* name, uint32 mapId); }; -class ItemScript : public ScriptObject +class TC_GAME_API ItemScript : public ScriptObject { protected: @@ -380,7 +380,7 @@ class ItemScript : public ScriptObject virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; } }; -class UnitScript : public ScriptObject +class TC_GAME_API UnitScript : public ScriptObject { protected: @@ -403,7 +403,7 @@ class UnitScript : public ScriptObject virtual void ModifySpellDamageTaken(Unit* /*target*/, Unit* /*attacker*/, int32& /*damage*/) { } }; -class CreatureScript : public UnitScript, public UpdatableScript<Creature> +class TC_GAME_API CreatureScript : public UnitScript, public UpdatableScript<Creature> { protected: @@ -439,7 +439,7 @@ class CreatureScript : public UnitScript, public UpdatableScript<Creature> virtual CreatureAI* GetAI(Creature* /*creature*/) const { return NULL; } }; -class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject> +class TC_GAME_API GameObjectScript : public ScriptObject, public UpdatableScript<GameObject> { protected: @@ -484,7 +484,7 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject> virtual GameObjectAI* GetAI(GameObject* /*go*/) const { return NULL; } }; -class AreaTriggerScript : public ScriptObject +class TC_GAME_API AreaTriggerScript : public ScriptObject { protected: @@ -496,7 +496,7 @@ class AreaTriggerScript : public ScriptObject virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/, bool /*entered*/) { return false; } }; -class BattlegroundScript : public ScriptObject +class TC_GAME_API BattlegroundScript : public ScriptObject { protected: @@ -508,7 +508,7 @@ class BattlegroundScript : public ScriptObject virtual Battleground* GetBattleground() const = 0; }; -class OutdoorPvPScript : public ScriptObject +class TC_GAME_API OutdoorPvPScript : public ScriptObject { protected: @@ -520,7 +520,7 @@ class OutdoorPvPScript : public ScriptObject virtual OutdoorPvP* GetOutdoorPvP() const = 0; }; -class CommandScript : public ScriptObject +class TC_GAME_API CommandScript : public ScriptObject { protected: @@ -532,7 +532,7 @@ class CommandScript : public ScriptObject virtual std::vector<ChatCommand> GetCommands() const = 0; }; -class WeatherScript : public ScriptObject, public UpdatableScript<Weather> +class TC_GAME_API WeatherScript : public ScriptObject, public UpdatableScript<Weather> { protected: @@ -544,7 +544,7 @@ class WeatherScript : public ScriptObject, public UpdatableScript<Weather> virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { } }; -class AuctionHouseScript : public ScriptObject +class TC_GAME_API AuctionHouseScript : public ScriptObject { protected: @@ -565,7 +565,7 @@ class AuctionHouseScript : public ScriptObject virtual void OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { } }; -class ConditionScript : public ScriptObject +class TC_GAME_API ConditionScript : public ScriptObject { protected: @@ -577,7 +577,7 @@ class ConditionScript : public ScriptObject virtual bool OnConditionCheck(Condition const* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; } }; -class VehicleScript : public ScriptObject +class TC_GAME_API VehicleScript : public ScriptObject { protected: @@ -604,14 +604,14 @@ class VehicleScript : public ScriptObject virtual void OnRemovePassenger(Vehicle* /*veh*/, Unit* /*passenger*/) { } }; -class DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject> +class TC_GAME_API DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject> { protected: DynamicObjectScript(const char* name); }; -class TransportScript : public ScriptObject, public UpdatableScript<Transport> +class TC_GAME_API TransportScript : public ScriptObject, public UpdatableScript<Transport> { protected: @@ -632,7 +632,7 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport> virtual void OnRelocate(Transport* /*transport*/, uint32 /*waypointId*/, uint32 /*mapId*/, float /*x*/, float /*y*/, float /*z*/) { } }; -class AchievementCriteriaScript : public ScriptObject +class TC_GAME_API AchievementCriteriaScript : public ScriptObject { protected: @@ -644,7 +644,7 @@ class AchievementCriteriaScript : public ScriptObject virtual bool OnCheck(Player* source, Unit* target) = 0; }; -class PlayerScript : public UnitScript +class TC_GAME_API PlayerScript : public UnitScript { protected: @@ -741,7 +741,7 @@ class PlayerScript : public UnitScript virtual void OnQuestStatusChange(Player* /*player*/, uint32 /*questId*/, QuestStatus /*status*/) { } }; -class AccountScript : public ScriptObject +class TC_GAME_API AccountScript : public ScriptObject { protected: @@ -768,7 +768,7 @@ class AccountScript : public ScriptObject virtual void OnFailedPasswordChange(uint32 /*accountId*/) {} }; -class GuildScript : public ScriptObject +class TC_GAME_API GuildScript : public ScriptObject { protected: @@ -809,7 +809,7 @@ class GuildScript : public ScriptObject virtual void OnBankEvent(Guild* /*guild*/, uint8 /*eventType*/, uint8 /*tabId*/, ObjectGuid::LowType /*playerGuid*/, uint64 /*itemOrMoney*/, uint16 /*itemStackCount*/, uint8 /*destTabId*/) { } }; -class GroupScript : public ScriptObject +class TC_GAME_API GroupScript : public ScriptObject { protected: @@ -839,11 +839,11 @@ class GroupScript : public ScriptObject // namespace // { typedef std::list<std::string> UnusedScriptNamesContainer; - extern UnusedScriptNamesContainer UnusedScriptNames; + TC_GAME_API extern UnusedScriptNamesContainer UnusedScriptNames; // } // Manages registration, loading, and execution of scripts. -class ScriptMgr +class TC_GAME_API ScriptMgr { friend class ScriptObject; diff --git a/src/server/game/Scripting/ScriptSystem.cpp b/src/server/game/Scripting/ScriptSystem.cpp index 309838a919e..52c5c1640af 100644 --- a/src/server/game/Scripting/ScriptSystem.cpp +++ b/src/server/game/Scripting/ScriptSystem.cpp @@ -21,7 +21,7 @@ #include "DatabaseEnv.h" #include "ScriptMgr.h" -ScriptPointVector const SystemMgr::_empty; +TC_GAME_API ScriptPointVector const SystemMgr::_empty; SystemMgr* SystemMgr::instance() { diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h index 99eb1610991..1b79c29d643 100644 --- a/src/server/game/Scripting/ScriptSystem.h +++ b/src/server/game/Scripting/ScriptSystem.h @@ -59,7 +59,7 @@ struct ScriptPointMove typedef std::vector<ScriptPointMove> ScriptPointVector; -class SystemMgr +class TC_GAME_API SystemMgr { private: SystemMgr() { } diff --git a/src/server/game/Server/Packet.h b/src/server/game/Server/Packet.h index ed9c1cc0afd..4bf9f2be688 100644 --- a/src/server/game/Server/Packet.h +++ b/src/server/game/Server/Packet.h @@ -22,7 +22,7 @@ namespace WorldPackets { - class Packet + class TC_GAME_API Packet { public: Packet(WorldPacket&& worldPacket) : _worldPacket(std::move(worldPacket)) { } diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h index faa060b3c0f..590fa930845 100644 --- a/src/server/game/Server/Packets/ChatPackets.h +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -147,7 +147,7 @@ namespace WorldPackets }; // SMSG_CHAT - class Chat final : public ServerPacket + class TC_GAME_API Chat final : public ServerPacket { public: Chat() : ServerPacket(SMSG_CHAT, 100) { } @@ -217,7 +217,7 @@ namespace WorldPackets int32 EmoteID = 0; }; - class PrintNotification final : public ServerPacket + class TC_GAME_API PrintNotification final : public ServerPacket { public: PrintNotification(std::string const& notifyText) : ServerPacket(SMSG_PRINT_NOTIFICATION, 2 + notifyText.size()), NotifyText(notifyText) { } diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index ebf920e2787..cef9a810213 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -397,7 +397,7 @@ namespace WorldPackets WorldPacket const* Write() override { return &_worldPacket; } }; - class Weather final : public ServerPacket + class TC_GAME_API Weather final : public ServerPacket { public: Weather(); @@ -598,7 +598,7 @@ namespace WorldPackets ObjectGuid ObjectGUID; }; - class PlaySound final : public ServerPacket + class TC_GAME_API PlaySound final : public ServerPacket { public: PlaySound() : ServerPacket(SMSG_PLAY_SOUND, 20) { } diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index e8fc4586ac4..018e0d5fe1a 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -42,7 +42,7 @@ namespace WorldPackets MovementInfo movementInfo; }; - class MoveUpdate final : public ServerPacket + class TC_GAME_API MoveUpdate final : public ServerPacket { public: MoveUpdate() : ServerPacket(SMSG_MOVE_UPDATE) { } @@ -427,7 +427,7 @@ namespace WorldPackets ObjectGuid SummonerGUID; }; - class ControlUpdate final : public ServerPacket + class TC_GAME_API ControlUpdate final : public ServerPacket { public: ControlUpdate() : ServerPacket(SMSG_CONTROL_UPDATE, 16 + 1) { } diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h index 28444e87e75..d5c1b9da118 100644 --- a/src/server/game/Server/Packets/NPCPackets.h +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -207,7 +207,7 @@ namespace WorldPackets ObjectGuid Healer; }; - class SpiritHealerConfirm final : public ServerPacket + class TC_GAME_API SpiritHealerConfirm final : public ServerPacket { public: SpiritHealerConfirm() : ServerPacket(SMSG_SPIRIT_HEALER_CONFIRM, 16) { } diff --git a/src/server/game/Server/Packets/ScenePackets.h b/src/server/game/Server/Packets/ScenePackets.h index 02fca2d5fe9..df6a1f0957e 100644 --- a/src/server/game/Server/Packets/ScenePackets.h +++ b/src/server/game/Server/Packets/ScenePackets.h @@ -25,7 +25,7 @@ namespace WorldPackets { namespace Scenes { - class PlayScene final : public ServerPacket + class TC_GAME_API PlayScene final : public ServerPacket { public: PlayScene() : ServerPacket(SMSG_PLAY_SCENE, 34) { } diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index e6c0fedd221..b1cb39251de 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -419,7 +419,7 @@ namespace WorldPackets uint8 CastID = 0; }; - class CastFailed final : public ServerPacket + class TC_GAME_API CastFailed final : public ServerPacket { public: CastFailed(OpcodeServer opcode) : ServerPacket(opcode, 4+4+4+4+1) { } @@ -445,7 +445,7 @@ namespace WorldPackets std::vector<SpellModifierData> ModifierData; }; - class SetSpellModifier final : public ServerPacket + class TC_GAME_API SetSpellModifier final : public ServerPacket { public: SetSpellModifier(OpcodeServer opcode) : ServerPacket(opcode, 20) { } diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 138cb7c1dd5..1aa6e4afd1c 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1765,7 +1765,7 @@ class OpcodeTable ServerOpcodeHandler* _internalTableServer[NUM_OPCODE_HANDLERS]; }; -extern OpcodeTable opcodeTable; +TC_GAME_API extern OpcodeTable opcodeTable; #pragma pack(pop) diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h index 5bfac184e61..329658f0789 100644 --- a/src/server/game/Server/Protocol/PacketLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -32,7 +32,7 @@ enum Direction class WorldPacket; -class PacketLog +class TC_GAME_API PacketLog { private: PacketLog(); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 9655968dcb3..1bcc9d0b373 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -863,7 +863,7 @@ struct PacketCounter }; /// Player session in the World -class WorldSession +class TC_GAME_API WorldSession { public: WorldSession(uint32 id, std::string&& name, uint32 battlenetAccountId, std::shared_ptr<WorldSocket> sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 0191d4d04d5..b3d4c9491f8 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -67,7 +67,7 @@ union ClientPktHeader #pragma pack(pop) -class WorldSocket : public Socket<WorldSocket> +class TC_GAME_API WorldSocket : public Socket<WorldSocket> { static std::string const ServerConnectionInitialize; static std::string const ClientConnectionInitialize; diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h index c6d5e4e6ef3..fd86d3b7931 100644 --- a/src/server/game/Server/WorldSocketMgr.h +++ b/src/server/game/Server/WorldSocketMgr.h @@ -30,7 +30,7 @@ class WorldSocket; /// Manages all sockets connected to peers and network threads -class WorldSocketMgr : public SocketMgr<WorldSocket> +class TC_GAME_API WorldSocketMgr : public SocketMgr<WorldSocket> { typedef SocketMgr<WorldSocket> BaseSocketMgr; diff --git a/src/server/game/Skills/SkillDiscovery.h b/src/server/game/Skills/SkillDiscovery.h index b7fe1cdc8b2..c2020e5b075 100644 --- a/src/server/game/Skills/SkillDiscovery.h +++ b/src/server/game/Skills/SkillDiscovery.h @@ -23,8 +23,9 @@ class Player; -void LoadSkillDiscoveryTable(); -uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player); -bool HasDiscoveredAllSpells(uint32 spellId, Player* player); -uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player); +TC_GAME_API void LoadSkillDiscoveryTable(); +TC_GAME_API uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player); +TC_GAME_API bool HasDiscoveredAllSpells(uint32 spellId, Player* player); +TC_GAME_API uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player); + #endif diff --git a/src/server/game/Skills/SkillExtraItems.h b/src/server/game/Skills/SkillExtraItems.h index 2889b221600..5a477b65f0b 100644 --- a/src/server/game/Skills/SkillExtraItems.h +++ b/src/server/game/Skills/SkillExtraItems.h @@ -23,12 +23,14 @@ // predef classes used in functions class Player; + // returns true and sets the appropriate info if the player can create a perfect item with the given spellId -bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType); +TC_GAME_API bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType); // load perfection proc info from DB -void LoadSkillPerfectItemTable(); +TC_GAME_API void LoadSkillPerfectItemTable(); // returns true and sets the appropriate info if the player can create extra items with the given spellId -bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax); +TC_GAME_API bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax); // function to load the extra item creation info from DB -void LoadSkillExtraItemTable(); +TC_GAME_API void LoadSkillExtraItemTable(); + #endif diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 95ace9c7a32..0d907e4148c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -27,7 +27,7 @@ class Aura; typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uint8 mode, bool apply) const; -class AuraEffect +class TC_GAME_API AuraEffect { friend void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount); friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel); diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 7ad36c58956..65cdbced339 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -47,7 +47,7 @@ class ChargeDropEvent; // update aura target map every 500 ms instead of every update - reduce amount of grid searcher calls #define UPDATE_TARGET_MAP_INTERVAL 500 -class AuraApplication +class TC_GAME_API AuraApplication { friend void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask); friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode); @@ -113,7 +113,7 @@ struct AuraLoadEffectInfo }; #pragma pack(pop) -class Aura +class TC_GAME_API Aura { friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel); public: @@ -326,7 +326,7 @@ class Aura SpellEffectInfoVector _spelEffectInfos; }; -class UnitAura : public Aura +class TC_GAME_API UnitAura : public Aura { friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel); public: @@ -347,7 +347,7 @@ class UnitAura : public Aura DiminishingGroup m_AuraDRGroup:8; // Diminishing }; -class DynObjAura : public Aura +class TC_GAME_API DynObjAura : public Aura { friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel); public: @@ -358,7 +358,7 @@ class DynObjAura : public Aura void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) override; }; -class ChargeDropEvent : public BasicEvent +class TC_GAME_API ChargeDropEvent : public BasicEvent { friend class Aura; protected: diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a7c9b91a31f..dd6d39f6030 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -115,7 +115,7 @@ enum SpellRangeFlag SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon }; -struct SpellDestination +struct TC_GAME_API SpellDestination { SpellDestination(); SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID); @@ -167,7 +167,7 @@ struct SpellLogEffectFeedPetParams int32 ItemID = 0; }; -class SpellCastTargets +class TC_GAME_API SpellCastTargets { public: SpellCastTargets(); @@ -291,7 +291,7 @@ enum SpellEffectHandleMode typedef std::list<std::pair<uint32, ObjectGuid>> DispelList; -class Spell +class TC_GAME_API Spell { friend void Unit::SetCurrentCastSpell(Spell* pSpell); friend class SpellScript; @@ -851,7 +851,7 @@ class Spell namespace Trinity { - struct WorldObjectSpellTargetCheck + struct TC_GAME_API WorldObjectSpellTargetCheck { Unit* _caster; Unit* _referer; @@ -866,7 +866,7 @@ namespace Trinity bool operator()(WorldObject* target); }; - struct WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck + struct TC_GAME_API WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck { float _range; Position const* _position; @@ -875,7 +875,7 @@ namespace Trinity bool operator()(WorldObject* target); }; - struct WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck + struct TC_GAME_API WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck { float _range; Position const* _position; @@ -884,7 +884,7 @@ namespace Trinity bool operator()(WorldObject* target); }; - struct WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck + struct TC_GAME_API WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck { float _coneAngle; WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster, @@ -892,7 +892,7 @@ namespace Trinity bool operator()(WorldObject* target); }; - struct WorldObjectSpellTrajTargetCheck : public WorldObjectSpellAreaTargetCheck + struct TC_GAME_API WorldObjectSpellTrajTargetCheck : public WorldObjectSpellAreaTargetCheck { WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster, SpellInfo const* spellInfo); bool operator()(WorldObject* target); @@ -901,7 +901,7 @@ namespace Trinity typedef void(Spell::*pEffect)(SpellEffIndex effIndex); -class SpellEvent : public BasicEvent +class TC_GAME_API SpellEvent : public BasicEvent { public: SpellEvent(Spell* spell); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index c63fdc63e47..f2a3d346fdf 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -39,7 +39,7 @@ enum SpellCooldownFlags SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set }; -class SpellHistory +class TC_GAME_API SpellHistory { public: typedef std::chrono::system_clock Clock; diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 8f321bccc6d..b8e9b10efc4 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -204,7 +204,7 @@ enum SpellCustomAttributes uint32 GetTargetFlagMask(SpellTargetObjectTypes objType); -class SpellImplicitTargetInfo +class TC_GAME_API SpellImplicitTargetInfo { private: Targets _target; @@ -235,7 +235,7 @@ private: static StaticData _data[TOTAL_SPELL_TARGETS]; }; -class SpellEffectInfo +class TC_GAME_API SpellEffectInfo { SpellInfo const* _spellInfo; public: @@ -323,7 +323,7 @@ typedef std::unordered_map<uint32, SpellVisualVector> SpellVisualMap; typedef std::vector<AuraEffect*> AuraEffectVector; -class SpellInfo +class TC_GAME_API SpellInfo { public: uint32 Id; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 38dc65c5421..79721235c17 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -430,7 +430,7 @@ enum EffectRadiusIndex }; // Spell pet auras -class PetAura +class TC_GAME_API PetAura { private: typedef std::unordered_map<uint32, uint32> PetAuraMap; @@ -477,7 +477,7 @@ class PetAura }; typedef std::map<uint32, PetAura> SpellPetAuraMap; -struct SpellArea +struct TC_GAME_API SpellArea { uint32 spellId; uint32 areaId; // zone/subzone/or 0 is not limited to zone @@ -590,14 +590,14 @@ inline bool IsProfessionOrRidingSkill(uint32 skill) bool IsPartOfSkillLine(uint32 skillId, uint32 spellId); // spell diminishing returns -DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto); -DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group); -DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group); -int32 GetDiminishingReturnsLimitDuration(SpellInfo const* spellproto); +TC_GAME_API DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto); +TC_GAME_API DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group); +TC_GAME_API DiminishingLevels GetDiminishingReturnsMaxLevel(DiminishingGroup group); +TC_GAME_API int32 GetDiminishingReturnsLimitDuration(SpellInfo const* spellproto); -extern PetFamilySpellsStore sPetFamilySpellsStore; +TC_GAME_API extern PetFamilySpellsStore sPetFamilySpellsStore; -class SpellMgr +class TC_GAME_API SpellMgr { // Constructors private: diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 02eaa2ef92f..aca3e074b9a 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -52,7 +52,7 @@ enum SpellScriptState #define SPELL_SCRIPT_STATE_END SPELL_SCRIPT_STATE_UNLOADING + 1 // helper class from which SpellScript and SpellAura derive, use these classes instead -class _SpellScript +class TC_GAME_API _SpellScript { // internal use classes & functions // DO NOT OVERRIDE THESE IN SCRIPTS @@ -68,7 +68,7 @@ class _SpellScript std::string const* _GetScriptName() const; protected: - class EffectHook + class TC_GAME_API EffectHook { public: EffectHook(uint8 _effIndex); @@ -82,7 +82,7 @@ class _SpellScript uint8 effIndex; }; - class EffectNameCheck + class TC_GAME_API EffectNameCheck { public: EffectNameCheck(uint16 _effName) { effName = _effName; } @@ -92,7 +92,7 @@ class _SpellScript uint16 effName; }; - class EffectAuraNameCheck + class TC_GAME_API EffectAuraNameCheck { public: EffectAuraNameCheck(uint16 _effAurName) { effAurName = _effAurName; } @@ -149,7 +149,7 @@ enum SpellScriptHookType #define HOOK_SPELL_END SPELL_SCRIPT_HOOK_CHECK_CAST + 1 #define HOOK_SPELL_COUNT HOOK_SPELL_END - HOOK_SPELL_START -class SpellScript : public _SpellScript +class TC_GAME_API SpellScript : public _SpellScript { // internal use classes & functions // DO NOT OVERRIDE THESE IN SCRIPTS @@ -165,7 +165,7 @@ class SpellScript : public _SpellScript SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript) - class CastHandler + class TC_GAME_API CastHandler { public: CastHandler(SpellCastFnType _pCastHandlerScript); @@ -174,7 +174,7 @@ class SpellScript : public _SpellScript SpellCastFnType pCastHandlerScript; }; - class CheckCastHandler + class TC_GAME_API CheckCastHandler { public: CheckCastHandler(SpellCheckCastFnType checkCastHandlerScript); @@ -183,7 +183,7 @@ class SpellScript : public _SpellScript SpellCheckCastFnType _checkCastHandlerScript; }; - class EffectHandler : public _SpellScript::EffectNameCheck, public _SpellScript::EffectHook + class TC_GAME_API EffectHandler : public _SpellScript::EffectNameCheck, public _SpellScript::EffectHook { public: EffectHandler(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -194,7 +194,7 @@ class SpellScript : public _SpellScript SpellEffectFnType pEffectHandlerScript; }; - class HitHandler + class TC_GAME_API HitHandler { public: HitHandler(SpellHitFnType _pHitHandlerScript); @@ -203,7 +203,7 @@ class SpellScript : public _SpellScript SpellHitFnType pHitHandlerScript; }; - class TargetHook : public _SpellScript::EffectHook + class TC_GAME_API TargetHook : public _SpellScript::EffectHook { public: TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest); @@ -216,7 +216,7 @@ class SpellScript : public _SpellScript bool dest; }; - class ObjectAreaTargetSelectHandler : public TargetHook + class TC_GAME_API ObjectAreaTargetSelectHandler : public TargetHook { public: ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); @@ -225,7 +225,7 @@ class SpellScript : public _SpellScript SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript; }; - class ObjectTargetSelectHandler : public TargetHook + class TC_GAME_API ObjectTargetSelectHandler : public TargetHook { public: ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); @@ -234,7 +234,7 @@ class SpellScript : public _SpellScript SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript; }; - class DestinationTargetSelectHandler : public TargetHook + class TC_GAME_API DestinationTargetSelectHandler : public TargetHook { public: DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); @@ -472,7 +472,7 @@ enum AuraScriptHookType #define HOOK_AURA_EFFECT_END HOOK_AURA_EFFECT_CALC_SPELLMOD + 1 #define HOOK_AURA_EFFECT_COUNT HOOK_AURA_EFFECT_END - HOOK_AURA_EFFECT_START */ -class AuraScript : public _SpellScript +class TC_GAME_API AuraScript : public _SpellScript { // internal use classes & functions // DO NOT OVERRIDE THESE IN SCRIPTS @@ -495,7 +495,7 @@ class AuraScript : public _SpellScript AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript) - class CheckAreaTargetHandler + class TC_GAME_API CheckAreaTargetHandler { public: CheckAreaTargetHandler(AuraCheckAreaTargetFnType pHandlerScript); @@ -503,7 +503,7 @@ class AuraScript : public _SpellScript private: AuraCheckAreaTargetFnType pHandlerScript; }; - class AuraDispelHandler + class TC_GAME_API AuraDispelHandler { public: AuraDispelHandler(AuraDispelFnType pHandlerScript); @@ -511,14 +511,14 @@ class AuraScript : public _SpellScript private: AuraDispelFnType pHandlerScript; }; - class EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook + class TC_GAME_API EffectBase : public _SpellScript::EffectAuraNameCheck, public _SpellScript::EffectHook { public: EffectBase(uint8 _effIndex, uint16 _effName); std::string ToString(); bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) override; }; - class EffectPeriodicHandler : public EffectBase + class TC_GAME_API EffectPeriodicHandler : public EffectBase { public: EffectPeriodicHandler(AuraEffectPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -526,7 +526,7 @@ class AuraScript : public _SpellScript private: AuraEffectPeriodicFnType pEffectHandlerScript; }; - class EffectUpdatePeriodicHandler : public EffectBase + class TC_GAME_API EffectUpdatePeriodicHandler : public EffectBase { public: EffectUpdatePeriodicHandler(AuraEffectUpdatePeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -534,7 +534,7 @@ class AuraScript : public _SpellScript private: AuraEffectUpdatePeriodicFnType pEffectHandlerScript; }; - class EffectCalcAmountHandler : public EffectBase + class TC_GAME_API EffectCalcAmountHandler : public EffectBase { public: EffectCalcAmountHandler(AuraEffectCalcAmountFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -542,7 +542,7 @@ class AuraScript : public _SpellScript private: AuraEffectCalcAmountFnType pEffectHandlerScript; }; - class EffectCalcPeriodicHandler : public EffectBase + class TC_GAME_API EffectCalcPeriodicHandler : public EffectBase { public: EffectCalcPeriodicHandler(AuraEffectCalcPeriodicFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -550,7 +550,7 @@ class AuraScript : public _SpellScript private: AuraEffectCalcPeriodicFnType pEffectHandlerScript; }; - class EffectCalcSpellModHandler : public EffectBase + class TC_GAME_API EffectCalcSpellModHandler : public EffectBase { public: EffectCalcSpellModHandler(AuraEffectCalcSpellModFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); @@ -558,7 +558,7 @@ class AuraScript : public _SpellScript private: AuraEffectCalcSpellModFnType pEffectHandlerScript; }; - class EffectApplyHandler : public EffectBase + class TC_GAME_API EffectApplyHandler : public EffectBase { public: EffectApplyHandler(AuraEffectApplicationModeFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode); @@ -567,7 +567,7 @@ class AuraScript : public _SpellScript AuraEffectApplicationModeFnType pEffectHandlerScript; AuraEffectHandleModes mode; }; - class EffectAbsorbHandler : public EffectBase + class TC_GAME_API EffectAbsorbHandler : public EffectBase { public: EffectAbsorbHandler(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex); @@ -575,7 +575,7 @@ class AuraScript : public _SpellScript private: AuraEffectAbsorbFnType pEffectHandlerScript; }; - class EffectManaShieldHandler : public EffectBase + class TC_GAME_API EffectManaShieldHandler : public EffectBase { public: EffectManaShieldHandler(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex); @@ -583,7 +583,7 @@ class AuraScript : public _SpellScript private: AuraEffectAbsorbFnType pEffectHandlerScript; }; - class EffectSplitHandler : public EffectBase + class TC_GAME_API EffectSplitHandler : public EffectBase { public: EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex); @@ -591,7 +591,7 @@ class AuraScript : public _SpellScript private: AuraEffectSplitFnType pEffectHandlerScript; }; - class CheckProcHandler + class TC_GAME_API CheckProcHandler { public: CheckProcHandler(AuraCheckProcFnType handlerScript); @@ -599,7 +599,7 @@ class AuraScript : public _SpellScript private: AuraCheckProcFnType _HandlerScript; }; - class AuraProcHandler + class TC_GAME_API AuraProcHandler { public: AuraProcHandler(AuraProcFnType handlerScript); @@ -607,7 +607,7 @@ class AuraScript : public _SpellScript private: AuraProcFnType _HandlerScript; }; - class EffectProcHandler : public EffectBase + class TC_GAME_API EffectProcHandler : public EffectBase { public: EffectProcHandler(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName); @@ -647,7 +647,7 @@ class AuraScript : public _SpellScript AuraApplication const* m_auraApplication; bool m_defaultActionPrevented; - class ScriptStateStore + class TC_GAME_API ScriptStateStore { public: AuraApplication const* _auraApplication; diff --git a/src/server/game/Support/SupportMgr.cpp b/src/server/game/Support/SupportMgr.cpp index 142904fcae3..97a828f44d6 100644 --- a/src/server/game/Support/SupportMgr.cpp +++ b/src/server/game/Support/SupportMgr.cpp @@ -409,6 +409,10 @@ SuggestionTicket* SupportMgr::GetTicket<SuggestionTicket>(uint32 suggestionId) } +template TC_GAME_API BugTicket* SupportMgr::GetTicket<BugTicket>(uint32); +template TC_GAME_API ComplaintTicket* SupportMgr::GetTicket<ComplaintTicket>(uint32); +template TC_GAME_API SuggestionTicket* SupportMgr::GetTicket<SuggestionTicket>(uint32); + template<> uint32 SupportMgr::GetOpenTicketCount<BugTicket>() const { return _openBugTicketCount; } @@ -418,6 +422,10 @@ uint32 SupportMgr::GetOpenTicketCount<ComplaintTicket>() const { return _openCom template<> uint32 SupportMgr::GetOpenTicketCount<SuggestionTicket>() const { return _openSuggestionTicketCount; } +template TC_GAME_API uint32 SupportMgr::GetOpenTicketCount<BugTicket>() const; +template TC_GAME_API uint32 SupportMgr::GetOpenTicketCount<ComplaintTicket>() const; +template TC_GAME_API uint32 SupportMgr::GetOpenTicketCount<SuggestionTicket>() const; + void SupportMgr::LoadBugTickets() { uint32 oldMSTime = getMSTime(); @@ -613,6 +621,10 @@ void SupportMgr::RemoveTicket<SuggestionTicket>(uint32 ticketId) } } +template TC_GAME_API void SupportMgr::RemoveTicket<BugTicket>(uint32); +template TC_GAME_API void SupportMgr::RemoveTicket<ComplaintTicket>(uint32); +template TC_GAME_API void SupportMgr::RemoveTicket<SuggestionTicket>(uint32); + template<> void SupportMgr::CloseTicket<BugTicket>(uint32 ticketId, ObjectGuid closedBy) { @@ -649,6 +661,10 @@ void SupportMgr::CloseTicket<SuggestionTicket>(uint32 ticketId, ObjectGuid close } } +template TC_GAME_API void SupportMgr::CloseTicket<BugTicket>(uint32, ObjectGuid); +template TC_GAME_API void SupportMgr::CloseTicket<ComplaintTicket>(uint32, ObjectGuid); +template TC_GAME_API void SupportMgr::CloseTicket<SuggestionTicket>(uint32, ObjectGuid); + template<> void SupportMgr::ResetTickets<BugTicket>() { @@ -690,6 +706,10 @@ void SupportMgr::ResetTickets<SuggestionTicket>() CharacterDatabase.Execute(stmt); } +template TC_GAME_API void SupportMgr::ResetTickets<BugTicket>(); +template TC_GAME_API void SupportMgr::ResetTickets<ComplaintTicket>(); +template TC_GAME_API void SupportMgr::ResetTickets<SuggestionTicket>(); + template<> void SupportMgr::ShowList<BugTicket>(ChatHandler& handler) const { @@ -717,6 +737,10 @@ void SupportMgr::ShowList<SuggestionTicket>(ChatHandler& handler) const handler.SendSysMessage(itr->second->FormatViewMessageString(handler).c_str()); } +template TC_GAME_API void SupportMgr::ShowList<BugTicket>(ChatHandler&) const; +template TC_GAME_API void SupportMgr::ShowList<ComplaintTicket>(ChatHandler&) const; +template TC_GAME_API void SupportMgr::ShowList<SuggestionTicket>(ChatHandler&) const; + template<> void SupportMgr::ShowClosedList<BugTicket>(ChatHandler& handler) const { @@ -743,3 +767,7 @@ void SupportMgr::ShowClosedList<SuggestionTicket>(ChatHandler& handler) const if (itr->second->IsClosed()) handler.SendSysMessage(itr->second->FormatViewMessageString(handler).c_str()); } + +template TC_GAME_API void SupportMgr::ShowClosedList<BugTicket>(ChatHandler&) const; +template TC_GAME_API void SupportMgr::ShowClosedList<ComplaintTicket>(ChatHandler&) const; +template TC_GAME_API void SupportMgr::ShowClosedList<SuggestionTicket>(ChatHandler&) const; diff --git a/src/server/game/Support/SupportMgr.h b/src/server/game/Support/SupportMgr.h index 86f5b223a86..aafbbc2dd20 100644 --- a/src/server/game/Support/SupportMgr.h +++ b/src/server/game/Support/SupportMgr.h @@ -50,7 +50,7 @@ enum SupportSpamType using ChatLog = WorldPackets::Ticket::SupportTicketSubmitComplaint::SupportTicketChatLog; -class Ticket +class TC_GAME_API Ticket { public: Ticket(); @@ -116,7 +116,7 @@ protected: std::string _comment; }; -class BugTicket : public Ticket +class TC_GAME_API BugTicket : public Ticket { public: BugTicket(); @@ -140,7 +140,7 @@ private: std::string _note; }; -class ComplaintTicket : public Ticket +class TC_GAME_API ComplaintTicket : public Ticket { public: ComplaintTicket(); @@ -176,7 +176,7 @@ private: std::string _note; }; -class SuggestionTicket : public Ticket +class TC_GAME_API SuggestionTicket : public Ticket { public: SuggestionTicket(); @@ -204,7 +204,7 @@ typedef std::map<uint32, BugTicket*> BugTicketList; typedef std::map<uint32, ComplaintTicket*> ComplaintTicketList; typedef std::map<uint32, SuggestionTicket*> SuggestionTicketList; -class SupportMgr +class TC_GAME_API SupportMgr { private: SupportMgr(); diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index 0feacd47539..5bff16ad812 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -76,7 +76,7 @@ typedef std::unordered_map<uint32, CreatureTextHolder> CreatureTextMap; // a typedef std::map<CreatureTextId, CreatureTextLocale> LocaleCreatureTextMap; -class CreatureTextMgr +class TC_GAME_API CreatureTextMgr { private: CreatureTextMgr() { } diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.h b/src/server/game/Tools/CharacterDatabaseCleaner.h index ecbd6d0a790..f1e6900a6bb 100644 --- a/src/server/game/Tools/CharacterDatabaseCleaner.h +++ b/src/server/game/Tools/CharacterDatabaseCleaner.h @@ -30,20 +30,20 @@ namespace CharacterDatabaseCleaner CLEANING_FLAG_QUESTSTATUS = 0x10 }; - void CleanDatabase(); + TC_GAME_API void CleanDatabase(); - void CheckUnique(const char* column, const char* table, bool (*check)(uint32)); + TC_GAME_API void CheckUnique(const char* column, const char* table, bool (*check)(uint32)); - bool AchievementProgressCheck(uint32 criteria); - bool SkillCheck(uint32 skill); - bool SpellCheck(uint32 spell_id); - bool TalentCheck(uint32 talent_id); + TC_GAME_API bool AchievementProgressCheck(uint32 criteria); + TC_GAME_API bool SkillCheck(uint32 skill); + TC_GAME_API bool SpellCheck(uint32 spell_id); + TC_GAME_API bool TalentCheck(uint32 talent_id); - void CleanCharacterAchievementProgress(); - void CleanCharacterSkills(); - void CleanCharacterSpell(); - void CleanCharacterTalent(); - void CleanCharacterQuestStatus(); + TC_GAME_API void CleanCharacterAchievementProgress(); + TC_GAME_API void CleanCharacterSkills(); + TC_GAME_API void CleanCharacterSpell(); + TC_GAME_API void CleanCharacterTalent(); + TC_GAME_API void CleanCharacterQuestStatus(); } #endif diff --git a/src/server/game/Tools/PlayerDump.h b/src/server/game/Tools/PlayerDump.h index 9f95572fd8c..66f4fd3fe13 100644 --- a/src/server/game/Tools/PlayerDump.h +++ b/src/server/game/Tools/PlayerDump.h @@ -65,7 +65,7 @@ enum DumpReturn DUMP_CHARACTER_DELETED }; -class PlayerDump +class TC_GAME_API PlayerDump { public: typedef std::set<ObjectGuid::LowType> DumpGuidSet; @@ -75,7 +75,7 @@ class PlayerDump PlayerDump() { } }; -class PlayerDumpWriter : public PlayerDump +class TC_GAME_API PlayerDumpWriter : public PlayerDump { public: PlayerDumpWriter() { } @@ -94,7 +94,7 @@ class PlayerDumpWriter : public PlayerDump DumpGuidSet items; }; -class PlayerDumpReader : public PlayerDump +class TC_GAME_API PlayerDumpReader : public PlayerDump { public: PlayerDumpReader() { } diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index 35ee18d4c02..b0aa496cbe8 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -92,7 +92,7 @@ struct ClientWardenModule class WorldSession; -class Warden +class TC_GAME_API Warden { friend class WardenWin; friend class WardenMac; diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h index a09dc3a6dbb..7349fd5b589 100644 --- a/src/server/game/Warden/WardenCheckMgr.h +++ b/src/server/game/Warden/WardenCheckMgr.h @@ -48,7 +48,7 @@ struct WardenCheckResult BigNumber Result; // MEM_CHECK }; -class WardenCheckMgr +class TC_GAME_API WardenCheckMgr { private: WardenCheckMgr(); diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h index 26a2d86524e..c7435502f63 100644 --- a/src/server/game/Warden/WardenMac.h +++ b/src/server/game/Warden/WardenMac.h @@ -28,7 +28,7 @@ class WorldSession; class Warden; -class WardenMac : public Warden +class TC_GAME_API WardenMac : public Warden { public: WardenMac(); diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h index 4bf1af77c47..b3e6d7c586c 100644 --- a/src/server/game/Warden/WardenWin.h +++ b/src/server/game/Warden/WardenWin.h @@ -62,7 +62,7 @@ struct WardenInitModuleRequest class WorldSession; class Warden; -class WardenWin : public Warden +class TC_GAME_API WardenWin : public Warden { public: WardenWin(); diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index 393080f044a..92140fbc2af 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -153,7 +153,7 @@ bool Weather::ReGenerate() uint32 chance2 = chance1 + m_weatherChances->data[season].snowChance; uint32 chance3 = chance2 + m_weatherChances->data[season].stormChance; - uint32 rnd = urand(0, 99); + uint32 rnd = urand(1, 100); if (rnd <= chance1) m_type = WEATHER_TYPE_RAIN; else if (rnd <= chance2) diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h index 0135b28522f..e0330b85a60 100644 --- a/src/server/game/Weather/Weather.h +++ b/src/server/game/Weather/Weather.h @@ -62,7 +62,7 @@ enum WeatherState : uint32 }; /// Weather for one zone -class Weather +class TC_GAME_API Weather { public: diff --git a/src/server/game/Weather/WeatherMgr.h b/src/server/game/Weather/WeatherMgr.h index 97c541fd3c0..e3dd4ac9ec4 100644 --- a/src/server/game/Weather/WeatherMgr.h +++ b/src/server/game/Weather/WeatherMgr.h @@ -30,15 +30,15 @@ class Player; namespace WeatherMgr { - void LoadWeatherData(); + TC_GAME_API void LoadWeatherData(); - Weather* FindWeather(uint32 id); - Weather* AddWeather(uint32 zone_id); - void RemoveWeather(uint32 zone_id); + TC_GAME_API Weather* FindWeather(uint32 id); + TC_GAME_API Weather* AddWeather(uint32 zone_id); + TC_GAME_API void RemoveWeather(uint32 zone_id); - void SendFineWeatherUpdateToPlayer(Player* player); + TC_GAME_API void SendFineWeatherUpdateToPlayer(Player* player); - void Update(uint32 diff); + TC_GAME_API void Update(uint32 diff); } #endif diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index bb675720d23..be9b48a81f3 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -74,17 +74,18 @@ #include <boost/algorithm/string.hpp> -std::atomic<bool> World::m_stopEvent(false); -uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; -std::atomic<uint32> World::m_worldLoopCounter(0); +TC_GAME_API std::atomic<bool> World::m_stopEvent(false); +TC_GAME_API uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; -float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE; -float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE; -float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS; +TC_GAME_API std::atomic<uint32> World::m_worldLoopCounter(0); -int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD; -int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD; -int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +TC_GAME_API float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE; +TC_GAME_API float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE; +TC_GAME_API float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS; + +TC_GAME_API int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +TC_GAME_API int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD; +TC_GAME_API int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD; /// World constructor World::World() diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 88baac9abf3..24a23f4f853 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -556,7 +556,7 @@ struct CharacterInfo }; /// The World -class World +class TC_GAME_API World { public: static World* instance(); @@ -895,8 +895,9 @@ class World std::deque<PreparedQueryResultFuture> m_realmCharCallbacks; }; -extern Realm realm; -uint32 GetVirtualRealmAddress(); +TC_GAME_API extern Realm realm; + +TC_GAME_API uint32 GetVirtualRealmAddress(); #define sWorld World::instance() diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index d0f639cb49a..c5b6aed89b9 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -51,7 +51,7 @@ endif () GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) -add_library(scripts +add_library(scripts STATIC ${PRIVATE_SOURCES} ${PRIVATE_PCH_SOURCE} ) diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index aedbe68d51c..ce6c13bd932 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -21,6 +21,8 @@ endif() GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) +add_definitions(-DTRINITY_API_EXPORT_SHARED) + add_library(shared ${PRIVATE_SOURCES} ${PRIVATE_PCH_SOURCE} @@ -40,13 +42,26 @@ target_include_directories(shared target_link_libraries(shared PUBLIC - database) + database + rapidjson) set_target_properties(shared PROPERTIES FOLDER "server") +if( BUILD_SHARED_LIBS ) + if( UNIX ) + install(TARGETS shared + LIBRARY + DESTINATION lib) + elseif( WIN32 ) + install(TARGETS shared + RUNTIME + DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() +endif() + # Generate precompiled header if (USE_COREPCH) add_cxx_pch(shared ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) diff --git a/src/server/shared/DataStores/DB2StorageLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h index 0b83bc43dc4..41705c67f19 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.h +++ b/src/server/shared/DataStores/DB2StorageLoader.h @@ -24,7 +24,7 @@ #include <cassert> #include <list> -class DB2FileLoader +class TC_SHARED_API DB2FileLoader { public: DB2FileLoader(); @@ -114,7 +114,7 @@ private: int unk5; // WDB2 }; -class DB2DatabaseLoader +class TC_SHARED_API DB2DatabaseLoader { public: explicit DB2DatabaseLoader(std::string const& storageName) : _storageName(storageName) { } diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h index cbbd786337c..e58031e6ccc 100644 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/server/shared/DataStores/DBCFileLoader.h @@ -23,7 +23,7 @@ #include "Utilities/ByteConverter.h" #include <cassert> -class DBCFileLoader +class TC_SHARED_API DBCFileLoader { public: DBCFileLoader(); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index b8c6ee1c36e..2373e632c44 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -37,7 +37,7 @@ class MessageBuffer; // Root of ByteBuffer exception hierarchy -class ByteBufferException : public std::exception +class TC_SHARED_API ByteBufferException : public std::exception { public: ~ByteBufferException() throw() { } @@ -51,7 +51,7 @@ private: std::string msg_; }; -class ByteBufferPositionException : public ByteBufferException +class TC_SHARED_API ByteBufferPositionException : public ByteBufferException { public: ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize); @@ -59,7 +59,7 @@ public: ~ByteBufferPositionException() throw() { } }; -class ByteBufferSourceException : public ByteBufferException +class TC_SHARED_API ByteBufferSourceException : public ByteBufferException { public: ByteBufferSourceException(size_t pos, size_t size, size_t valueSize); @@ -67,7 +67,7 @@ public: ~ByteBufferSourceException() throw() { } }; -class ByteBuffer +class TC_SHARED_API ByteBuffer { public: static size_t const DEFAULT_SIZE = 0x1000; diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h index 585a98e4569..87d333a4bf6 100644 --- a/src/server/shared/Realm/Realm.h +++ b/src/server/shared/Realm/Realm.h @@ -41,7 +41,7 @@ enum RealmFlags namespace Battlenet { - struct RealmHandle + struct TC_SHARED_API RealmHandle { RealmHandle() : Region(0), Site(0), Realm(0) { } RealmHandle(uint8 region, uint8 battlegroup, uint32 index) @@ -78,7 +78,7 @@ enum RealmType }; // Storage object for a realm -struct Realm +struct TC_SHARED_API Realm { Battlenet::RealmHandle Id; uint32 Build; |