Changeset 487 for branches


Ignore:
Timestamp:
03/27/14 15:56:37 (5 years ago)
Author:
jls17
Message:
  • upgraded rapidjson to v0.11
Location:
branches/work_304/thirdparty/rapidjson
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • branches/work_304/thirdparty/rapidjson/document.h

    r313 r487  
    44#include "reader.h" 
    55#include "internal/strfunc.h" 
     6#include <new>          // placement new 
     7 
     8#ifdef _MSC_VER 
     9#pragma warning(push) 
     10#pragma warning(disable : 4127) // conditional expression is constant 
     11#endif 
    612 
    713namespace rapidjson { 
     
    148154 
    149155                        case kCopyStringFlag: 
    150                                 Allocator::Free((void*)data_.s.str); 
     156                                Allocator::Free(const_cast<Ch*>(data_.s.str)); 
    151157                                break; 
    152158                        } 
     
    265271                        } 
    266272                } 
    267                 o.members[o.size].name = name; 
    268                 o.members[o.size].value = value; 
     273                o.members[o.size].name.RawAssign(name); 
     274                o.members[o.size].value.RawAssign(value); 
    269275                o.size++; 
    270276                return *this; 
     
    392398                if (data_.a.size >= data_.a.capacity) 
    393399                        Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : data_.a.capacity * 2, allocator); 
    394                 data_.a.elements[data_.a.size++] = value; 
     400                data_.a.elements[data_.a.size++].RawAssign(value); 
    395401                return *this; 
    396402        } 
     
    414420        //@{ 
    415421 
    416         int GetInt() const                      { RAPIDJSON_ASSERT(flags_ & kIntFlag);   return data_.n.i;   } 
    417         unsigned GetUint() const        { RAPIDJSON_ASSERT(flags_ & kUintFlag);  return data_.n.u;   } 
     422        int GetInt() const                      { RAPIDJSON_ASSERT(flags_ & kIntFlag);   return data_.n.i.i;   } 
     423        unsigned GetUint() const        { RAPIDJSON_ASSERT(flags_ & kUintFlag);  return data_.n.u.u;   } 
    418424        int64_t GetInt64() const        { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; } 
    419         int64_t GetUint64() const       { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.u64; } 
     425        uint64_t GetUint64() const      { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; } 
    420426 
    421427        double GetDouble() const { 
    422428                RAPIDJSON_ASSERT(IsNumber()); 
    423429                if ((flags_ & kDoubleFlag) != 0)                                return data_.n.d;       // exact type, no conversion. 
    424                 if ((flags_ & kIntFlag) != 0)                                   return data_.n.i;       // int -> double 
    425                 if ((flags_ & kUintFlag) != 0)                                  return data_.n.u;       // unsigned -> double 
     430                if ((flags_ & kIntFlag) != 0)                                   return data_.n.i.i;     // int -> double 
     431                if ((flags_ & kUintFlag) != 0)                                  return data_.n.u.u;     // unsigned -> double 
    426432                if ((flags_ & kInt64Flag) != 0)                                 return (double)data_.n.i64; // int64_t -> double (may lose precision) 
    427433                RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0);  return (double)data_.n.u64;     // uint64_t -> double (may lose precision) 
     
    486492        */ 
    487493        template <typename Handler> 
    488         GenericValue& Accept(Handler& handler) { 
     494        const GenericValue& Accept(Handler& handler) const { 
    489495                switch(GetType()) { 
    490496                case kNullType:         handler.Null(); break; 
     
    513519 
    514520                case kNumberType: 
    515                         if (IsInt())                    handler.Int(data_.n.i); 
    516                         else if (IsUint())              handler.Uint(data_.n.u); 
     521                        if (IsInt())                    handler.Int(data_.n.i.i); 
     522                        else if (IsUint())              handler.Uint(data_.n.u.u); 
    517523                        else if (IsInt64())             handler.Int64(data_.n.i64); 
    518                         else if (IsUint64())    handler.Uint64(data_.n.i64); 
     524                        else if (IsUint64())    handler.Uint64(data_.n.u64); 
    519525                        else                                    handler.Double(data_.n.d); 
    520526                        break; 
     
    543549                kFalseFlag = kFalseType | kBoolFlag, 
    544550                kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, 
    545                 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag, 
     551                kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, 
    546552                kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, 
    547553                kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, 
     
    567573        union Number { 
    568574#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN 
    569                 struct { 
     575                struct I { 
    570576                        int i; 
    571577                        char padding[4]; 
    572                 }; 
    573                 struct { 
     578                }i; 
     579                struct U { 
    574580                        unsigned u; 
    575581                        char padding2[4]; 
    576                 }; 
     582                }u; 
    577583#else 
    578                 struct { 
     584                struct I { 
    579585                        char padding[4]; 
    580586                        int i; 
    581                 }; 
    582                 struct { 
     587                }i; 
     588                struct U { 
    583589                        char padding2[4]; 
    584590                        unsigned u; 
    585                 }; 
     591                }u; 
    586592#endif 
    587593                int64_t i64; 
     
    614620                RAPIDJSON_ASSERT(IsObject()); 
    615621 
     622                SizeType length = internal::StrLen(name); 
     623 
    616624                Object& o = data_.o; 
    617625                for (Member* member = o.members; member != data_.o.members + data_.o.size; ++member) 
    618                         if (name[member->name.data_.s.length] == '\0' && memcmp(member->name.data_.s.str, name, member->name.data_.s.length * sizeof(Ch)) == 0) 
     626                        if (length == member->name.data_.s.length && memcmp(member->name.data_.s.str, name, length * sizeof(Ch)) == 0) 
    619627                                return member; 
    620628 
     
    651659                RAPIDJSON_ASSERT(s != NULL); 
    652660                flags_ = kCopyStringFlag; 
    653                 data_.s.str = (Ch *)allocator.Malloc(length + 1); 
     661                data_.s.str = (Ch *)allocator.Malloc((length + 1) * sizeof(Ch)); 
    654662                data_.s.length = length; 
    655                 memcpy((void*)data_.s.str, s, length); 
    656                 ((Ch*)data_.s.str)[length] = '\0'; 
     663                memcpy(const_cast<Ch*>(data_.s.str), s, length * sizeof(Ch)); 
     664                const_cast<Ch*>(data_.s.str)[length] = '\0'; 
    657665        } 
    658666 
     
    698706                \return The document itself for fluent API. 
    699707        */ 
    700         template <unsigned parseFlags, typename SourceEncoding, typename InputStream> 
    701         GenericDocument& ParseStream(InputStream& is) { 
     708        template <unsigned parseFlags, typename Stream> 
     709        GenericDocument& ParseStream(Stream& stream) { 
    702710                ValueType::SetNull(); // Remove existing root if exist 
    703                 GenericReader<SourceEncoding, Encoding> reader; 
    704                 if (reader.Parse<parseFlags>(is, *this)) { 
     711                GenericReader<Encoding, Allocator> reader; 
     712                if (reader.template Parse<parseFlags>(stream, *this)) { 
    705713                        RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object 
    706714                        this->RawAssign(*stack_.template Pop<ValueType>(1));    // Add this-> to prevent issue 13. 
     
    721729                \return The document itself for fluent API. 
    722730        */ 
    723         template <unsigned parseFlags, typename SourceEncoding> 
     731        template <unsigned parseFlags> 
    724732        GenericDocument& ParseInsitu(Ch* str) { 
    725733                GenericInsituStringStream<Encoding> s(str); 
    726                 return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s); 
    727         } 
    728  
    729         template <unsigned parseFlags> 
    730         GenericDocument& ParseInsitu(Ch* str) { 
    731                 return ParseInsitu<parseFlags, Encoding>(str); 
     734                return ParseStream<parseFlags | kParseInsituFlag>(s); 
    732735        } 
    733736 
     
    736739                \param str Read-only zero-terminated string to be parsed. 
    737740        */ 
    738         template <unsigned parseFlags, typename SourceEncoding> 
     741        template <unsigned parseFlags> 
    739742        GenericDocument& Parse(const Ch* str) { 
    740743                RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 
    741                 GenericStringStream<SourceEncoding> s(str); 
    742                 return ParseStream<parseFlags, SourceEncoding>(s); 
    743         } 
    744  
    745         template <unsigned parseFlags> 
    746         GenericDocument& Parse(const Ch* str) { 
    747                 return Parse<parseFlags, Encoding>(str); 
     744                GenericStringStream<Encoding> s(str); 
     745                return ParseStream<parseFlags>(s); 
    748746        } 
    749747 
     
    763761        size_t GetStackCapacity() const { return stack_.GetCapacity(); } 
    764762 
    765 //private: 
    766         //friend class GenericReader<Encoding>; // for Reader to call the following private handler functions 
     763private: 
     764        // Prohibit assignment 
     765        GenericDocument& operator=(const GenericDocument&); 
     766 
     767        friend class GenericReader<Encoding, Allocator>;        // for Reader to call the following private handler functions 
    767768 
    768769        // Implementation of Handler 
     
    796797        } 
    797798 
    798 private: 
    799799        void ClearStack() { 
    800800                if (Allocator::kNeedFree) 
     
    815815} // namespace rapidjson 
    816816 
     817#ifdef _MSC_VER 
     818#pragma warning(pop) 
     819#endif 
     820 
    817821#endif // RAPIDJSON_DOCUMENT_H_ 
  • branches/work_304/thirdparty/rapidjson/filestream.h

    r313 r487  
    22#define RAPIDJSON_FILESTREAM_H_ 
    33 
    4 #include "rapidjson.h" 
    54#include <cstdio> 
    65 
    76namespace rapidjson { 
    87 
    9 //! (Depreciated) Wrapper of C file stream for input or output. 
     8//! Wrapper of C file stream for input or output. 
    109/*! 
    1110        This simple wrapper does not check the validity of the stream. 
    1211        \implements Stream 
    13         \deprecated { This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. } 
    1412*/ 
    1513class FileStream { 
     
    2220        size_t Tell() const { return count_; } 
    2321        void Put(char c) { fputc(c, fp_); } 
    24         void Flush() { fflush(fp_); } 
    2522 
    2623        // Not implemented 
     
    3633                        count_++; 
    3734                } 
    38                 else if (current_ != '\0') 
     35                else 
    3936                        current_ = '\0'; 
    4037        } 
  • branches/work_304/thirdparty/rapidjson/internal/stack.h

    r313 r487  
    6565 
    6666        Allocator& GetAllocator() { return *allocator_; } 
    67         bool Empty() const { return stack_top_ == stack_; } 
    6867        size_t GetSize() const { return stack_top_ - stack_; } 
    6968        size_t GetCapacity() const { return stack_capacity_; } 
  • branches/work_304/thirdparty/rapidjson/prettywriter.h

    r313 r487  
    88//! Writer with indentation and spacing. 
    99/*! 
    10         \tparam OutputStream Type of ouptut os. 
     10        \tparam Stream Type of ouptut stream. 
    1111        \tparam Encoding Encoding of both source strings and output. 
    1212        \tparam Allocator Type of allocator for allocating memory of stack. 
    1313*/ 
    14 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > 
    15 class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> { 
     14template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > 
     15class PrettyWriter : public Writer<Stream, Encoding, Allocator> { 
    1616public: 
    17         typedef Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> Base; 
     17        typedef Writer<Stream, Encoding, Allocator> Base; 
    1818        typedef typename Base::Ch Ch; 
    1919 
    2020        //! Constructor 
    21         /*! \param os Output os. 
     21        /*! \param stream Output stream. 
    2222                \param allocator User supplied allocator. If it is null, it will create a private one. 
    2323                \param levelDepth Initial capacity of  
    2424        */ 
    25         PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :  
    26                 Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} 
     25        PrettyWriter(Stream& stream, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :  
     26                Base(stream, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} 
    2727 
    2828        //! Set custom indentation. 
     
    5050 
    5151        PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { 
     52                (void)copy; 
    5253                PrettyPrefix(kStringType); 
    5354                Base::WriteString(str, length); 
     
    6364 
    6465        PrettyWriter& EndObject(SizeType memberCount = 0) { 
     66                (void)memberCount; 
    6567                RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 
    6668                RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); 
     
    6870 
    6971                if (!empty) { 
    70                         Base::os_.Put('\n'); 
     72                        Base::stream_.Put('\n'); 
    7173                        WriteIndent(); 
    7274                } 
    7375                Base::WriteEndObject(); 
    74                 if (Base::level_stack_.Empty()) // end of json text 
    75                         Base::os_.Flush(); 
    7676                return *this; 
    7777        } 
     
    8585 
    8686        PrettyWriter& EndArray(SizeType memberCount = 0) { 
     87                (void)memberCount; 
    8788                RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); 
    8889                RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray); 
     
    9091 
    9192                if (!empty) { 
    92                         Base::os_.Put('\n'); 
     93                        Base::stream_.Put('\n'); 
    9394                        WriteIndent(); 
    9495                } 
    9596                Base::WriteEndArray(); 
    96                 if (Base::level_stack_.Empty()) // end of json text 
    97                         Base::os_.Flush(); 
    9897                return *this; 
    9998        } 
     
    106105protected: 
    107106        void PrettyPrefix(Type type) { 
     107                (void)type; 
    108108                if (Base::level_stack_.GetSize() != 0) { // this value is not at root 
    109109                        typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>(); 
     
    111111                        if (level->inArray) { 
    112112                                if (level->valueCount > 0) { 
    113                                         Base::os_.Put(','); // add comma if it is not the first element in array 
    114                                         Base::os_.Put('\n'); 
     113                                        Base::stream_.Put(','); // add comma if it is not the first element in array 
     114                                        Base::stream_.Put('\n'); 
    115115                                } 
    116116                                else 
    117                                         Base::os_.Put('\n'); 
     117                                        Base::stream_.Put('\n'); 
    118118                                WriteIndent(); 
    119119                        } 
     
    121121                                if (level->valueCount > 0) { 
    122122                                        if (level->valueCount % 2 == 0) { 
    123                                                 Base::os_.Put(','); 
    124                                                 Base::os_.Put('\n'); 
     123                                                Base::stream_.Put(','); 
     124                                                Base::stream_.Put('\n'); 
    125125                                        } 
    126126                                        else { 
    127                                                 Base::os_.Put(':'); 
    128                                                 Base::os_.Put(' '); 
     127                                                Base::stream_.Put(':'); 
     128                                                Base::stream_.Put(' '); 
    129129                                        } 
    130130                                } 
    131131                                else 
    132                                         Base::os_.Put('\n'); 
     132                                        Base::stream_.Put('\n'); 
    133133 
    134134                                if (level->valueCount % 2 == 0) 
     
    145145        void WriteIndent()  { 
    146146                size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; 
    147                 PutN(Base::os_, indentChar_, count); 
     147                PutN(Base::stream_, indentChar_, count); 
    148148        } 
    149149 
  • branches/work_304/thirdparty/rapidjson/rapidjson.h

    r313 r487  
    22#define RAPIDJSON_RAPIDJSON_H_ 
    33 
    4 // Copyright (c) 2011 Milo Yip (miloyip@gmail.com) 
    5 // Version 0.1 
     4// Copyright (c) 2011-2012 Milo Yip (miloyip@gmail.com) 
     5// Version 0.11 
    66 
    77#include <cstdlib>      // malloc(), realloc(), free() 
     
    1717typedef __int64 int64_t; 
    1818typedef unsigned __int64 uint64_t; 
    19 #define RAPIDJSON_FORCEINLINE __forceinline 
    2019#else 
    2120#include <inttypes.h> 
    22 #define RAPIDJSON_FORCEINLINE 
    2321#endif 
    2422#endif // RAPIDJSON_NO_INT64TYPEDEF 
     
    4644#endif // RAPIDJSON_ENDIAN 
    4745 
    48  
    49 /////////////////////////////////////////////////////////////////////////////// 
    50 // RAPIDJSON_ALIGNSIZE 
    51  
    52 //! Data alignment of the machine. 
    53 /*! 
    54         Some machine requires strict data alignment. 
    55         Currently the default uses 4 bytes alignment. User can customize this. 
    56 */ 
    57 #ifndef RAPIDJSON_ALIGN 
    58 #define RAPIDJSON_ALIGN(x) ((x + 3) & ~3) 
    59 #endif 
    60  
    6146/////////////////////////////////////////////////////////////////////////////// 
    6247// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD 
     
    9782 
    9883/////////////////////////////////////////////////////////////////////////////// 
    99 // RAPIDJSON_STATIC_ASSERT 
    100  
    101 // Adopt from boost 
    102 #ifndef RAPIDJSON_STATIC_ASSERT 
     84// Helpers 
     85 
     86#define RAPIDJSON_MULTILINEMACRO_BEGIN do {   
     87#define RAPIDJSON_MULTILINEMACRO_END \ 
     88} while((void)0, 0) 
     89 
    10390namespace rapidjson { 
    104 template <bool x> struct STATIC_ASSERTION_FAILURE; 
    105 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; 
    106 template<int x> struct StaticAssertTest {}; 
    107 } // namespace rapidjson 
    108  
    109 #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) 
    110 #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) 
    111 #define RAPIDJSON_DO_JOIN2(X, Y) X##Y 
    112  
    113 #define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\ 
    114         sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\ 
    115         RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) 
    116 #endif 
    117  
    118 /////////////////////////////////////////////////////////////////////////////// 
    119 // Allocators and Encodings 
    120  
    121 #include "allocators.h" 
    122 #include "encodings.h" 
    123  
    124 namespace rapidjson { 
     91 
     92/////////////////////////////////////////////////////////////////////////////// 
     93// Allocator 
     94 
     95/*! \class rapidjson::Allocator 
     96        \brief Concept for allocating, resizing and freeing memory block. 
     97         
     98        Note that Malloc() and Realloc() are non-static but Free() is static. 
     99         
     100        So if an allocator need to support Free(), it needs to put its pointer in  
     101        the header of memory block. 
     102 
     103\code 
     104concept Allocator { 
     105        static const bool kNeedFree;    //!< Whether this allocator needs to call Free(). 
     106 
     107        // Allocate a memory block. 
     108        // \param size of the memory block in bytes. 
     109        // \returns pointer to the memory block. 
     110        void* Malloc(size_t size); 
     111 
     112        // Resize a memory block. 
     113        // \param originalPtr The pointer to current memory block. Null pointer is permitted. 
     114        // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) 
     115        // \param newSize the new size in bytes. 
     116        void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); 
     117 
     118        // Free a memory block. 
     119        // \param pointer to the memory block. Null pointer is permitted. 
     120        static void Free(void *ptr); 
     121}; 
     122\endcode 
     123*/ 
     124 
     125/////////////////////////////////////////////////////////////////////////////// 
     126// CrtAllocator 
     127 
     128//! C-runtime library allocator. 
     129/*! This class is just wrapper for standard C library memory routines. 
     130        \implements Allocator 
     131*/ 
     132class CrtAllocator { 
     133public: 
     134        static const bool kNeedFree = true; 
     135        void* Malloc(size_t size) { return malloc(size); } 
     136        void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); } 
     137        static void Free(void *ptr) { free(ptr); } 
     138}; 
     139 
     140/////////////////////////////////////////////////////////////////////////////// 
     141// MemoryPoolAllocator 
     142 
     143//! Default memory allocator used by the parser and DOM. 
     144/*! This allocator allocate memory blocks from pre-allocated memory chunks.  
     145 
     146    It does not free memory blocks. And Realloc() only allocate new memory. 
     147 
     148    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. 
     149 
     150    User may also supply a buffer as the first chunk. 
     151 
     152    If the user-buffer is full then additional chunks are allocated by BaseAllocator. 
     153 
     154    The user-buffer is not deallocated by this allocator. 
     155 
     156    \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. 
     157        \implements Allocator 
     158*/ 
     159template <typename BaseAllocator = CrtAllocator> 
     160class MemoryPoolAllocator { 
     161public: 
     162        static const bool kNeedFree = false;    //!< Tell users that no need to call Free() with this allocator. (concept Allocator) 
     163 
     164        //! Constructor with chunkSize. 
     165        /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. 
     166                \param baseAllocator The allocator for allocating memory chunks. 
     167        */ 
     168        MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :  
     169                chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) 
     170        { 
     171                if (!baseAllocator_) 
     172                        ownBaseAllocator_ = baseAllocator_ = new BaseAllocator(); 
     173                AddChunk(chunk_capacity_); 
     174        } 
     175 
     176        //! Constructor with user-supplied buffer. 
     177        /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. 
     178 
     179                The user buffer will not be deallocated when this allocator is destructed. 
     180 
     181                \param buffer User supplied buffer. 
     182                \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). 
     183                \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. 
     184                \param baseAllocator The allocator for allocating memory chunks. 
     185        */ 
     186        MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : 
     187                chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) 
     188        { 
     189                RAPIDJSON_ASSERT(buffer != 0); 
     190                RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); 
     191                chunkHead_ = (ChunkHeader*)buffer; 
     192                chunkHead_->capacity = size - sizeof(ChunkHeader); 
     193                chunkHead_->size = 0; 
     194                chunkHead_->next = 0; 
     195        } 
     196 
     197        //! Destructor. 
     198        /*! This deallocates all memory chunks, excluding the user-supplied buffer. 
     199        */ 
     200        ~MemoryPoolAllocator() { 
     201                Clear(); 
     202                delete ownBaseAllocator_; 
     203        } 
     204 
     205        //! Deallocates all memory chunks, excluding the user-supplied buffer. 
     206        void Clear() { 
     207                while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) { 
     208                        ChunkHeader* next = chunkHead_->next; 
     209                        baseAllocator_->Free(chunkHead_); 
     210                        chunkHead_ = next; 
     211                } 
     212        } 
     213 
     214        //! Computes the total capacity of allocated memory chunks. 
     215        /*! \return total capacity in bytes. 
     216        */ 
     217        size_t Capacity() { 
     218                size_t capacity = 0; 
     219                for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) 
     220                        capacity += c->capacity; 
     221                return capacity; 
     222        } 
     223 
     224        //! Computes the memory blocks allocated. 
     225        /*! \return total used bytes. 
     226        */ 
     227        size_t Size() { 
     228                size_t size = 0; 
     229                for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) 
     230                        size += c->size; 
     231                return size; 
     232        } 
     233 
     234        //! Allocates a memory block. (concept Allocator) 
     235        void* Malloc(size_t size) { 
     236                size = (size + 3) & ~3; // Force aligning size to 4 
     237 
     238                if (chunkHead_->size + size > chunkHead_->capacity) 
     239                        AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size); 
     240 
     241                char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size; 
     242                RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4 
     243                chunkHead_->size += size; 
     244 
     245                return buffer; 
     246        } 
     247 
     248        //! Resizes a memory block (concept Allocator) 
     249        void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { 
     250                if (originalPtr == 0) 
     251                        return Malloc(newSize); 
     252 
     253                // Do not shrink if new size is smaller than original 
     254                if (originalSize >= newSize) 
     255                        return originalPtr; 
     256 
     257                // Simply expand it if it is the last allocation and there is sufficient space 
     258                if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) { 
     259                        size_t increment = newSize - originalSize; 
     260                        increment = (increment + 3) & ~3;       // Force aligning size to 4 
     261                        if (chunkHead_->size + increment <= chunkHead_->capacity) { 
     262                                chunkHead_->size += increment; 
     263                                RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0);    // returned buffer is aligned to 4 
     264                                return originalPtr; 
     265                        } 
     266                } 
     267 
     268                // Realloc process: allocate and copy memory, do not free original buffer. 
     269                void* newBuffer = Malloc(newSize); 
     270                RAPIDJSON_ASSERT(newBuffer != 0);       // Do not handle out-of-memory explicitly. 
     271                return memcpy(newBuffer, originalPtr, originalSize); 
     272        } 
     273 
     274        //! Frees a memory block (concept Allocator) 
     275        static void Free(void *) {} // Do nothing 
     276 
     277private: 
     278        //! Creates a new chunk. 
     279        /*! \param capacity Capacity of the chunk in bytes. 
     280        */ 
     281        void AddChunk(size_t capacity) { 
     282                ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity); 
     283                chunk->capacity = capacity; 
     284                chunk->size = 0; 
     285                chunk->next = chunkHead_; 
     286                chunkHead_ =  chunk; 
     287        } 
     288 
     289        static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. 
     290 
     291        //! Chunk header for perpending to each chunk. 
     292        /*! Chunks are stored as a singly linked list. 
     293        */ 
     294        struct ChunkHeader { 
     295                size_t capacity;        //!< Capacity of the chunk in bytes (excluding the header itself). 
     296                size_t size;            //!< Current size of allocated memory in bytes. 
     297                ChunkHeader *next;      //!< Next chunk in the linked list. 
     298        }; 
     299 
     300        ChunkHeader *chunkHead_;        //!< Head of the chunk linked-list. Only the head chunk serves allocation. 
     301        size_t chunk_capacity_;         //!< The minimum capacity of chunk when they are allocated. 
     302        char *userBuffer_;                      //!< User supplied buffer. 
     303        BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory chunks. 
     304        BaseAllocator* ownBaseAllocator_;       //!< base allocator created by this object. 
     305}; 
     306 
     307/////////////////////////////////////////////////////////////////////////////// 
     308// Encoding 
     309 
     310/*! \class rapidjson::Encoding 
     311        \brief Concept for encoding of Unicode characters. 
     312 
     313\code 
     314concept Encoding { 
     315        typename Ch;    //! Type of character. 
     316 
     317        //! \brief Encode a Unicode codepoint to a buffer. 
     318        //! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character. 
     319        //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. 
     320        //! \returns the pointer to the next character after the encoded data. 
     321        static Ch* Encode(Ch *buffer, unsigned codepoint); 
     322}; 
     323\endcode 
     324*/ 
     325 
     326/////////////////////////////////////////////////////////////////////////////// 
     327// UTF8 
     328 
     329//! UTF-8 encoding. 
     330/*! http://en.wikipedia.org/wiki/UTF-8 
     331        \tparam CharType Type for storing 8-bit UTF-8 data. Default is char. 
     332        \implements Encoding 
     333*/ 
     334template<typename CharType = char> 
     335struct UTF8 { 
     336        typedef CharType Ch; 
     337 
     338        static Ch* Encode(Ch *buffer, unsigned codepoint) { 
     339                if (codepoint <= 0x7F)  
     340                        *buffer++ = codepoint & 0xFF; 
     341                else if (codepoint <= 0x7FF) { 
     342                        *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF); 
     343                        *buffer++ = 0x80 | ((codepoint & 0x3F)); 
     344                } 
     345                else if (codepoint <= 0xFFFF) { 
     346                        *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF); 
     347                        *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); 
     348                        *buffer++ = 0x80 | (codepoint & 0x3F); 
     349                } 
     350                else { 
     351                        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); 
     352                        *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF); 
     353                        *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F); 
     354                        *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F); 
     355                        *buffer++ = 0x80 | (codepoint & 0x3F); 
     356                } 
     357                return buffer; 
     358        } 
     359}; 
     360 
     361/////////////////////////////////////////////////////////////////////////////// 
     362// UTF16 
     363 
     364//! UTF-16 encoding. 
     365/*! http://en.wikipedia.org/wiki/UTF-16 
     366        \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. 
     367        \implements Encoding 
     368*/ 
     369template<typename CharType = wchar_t> 
     370struct UTF16 { 
     371        typedef CharType Ch; 
     372 
     373        static Ch* Encode(Ch* buffer, unsigned codepoint) { 
     374                if (codepoint <= 0xFFFF) { 
     375                        RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair  
     376                        *buffer++ = static_cast<Ch>(codepoint); 
     377                } 
     378                else { 
     379                        RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); 
     380                        unsigned v = codepoint - 0x10000; 
     381                        *buffer++ = static_cast<Ch>((v >> 10) + 0xD800); 
     382                        *buffer++ = (v & 0x3FF) + 0xDC00; 
     383                } 
     384                return buffer; 
     385        } 
     386}; 
     387 
     388/////////////////////////////////////////////////////////////////////////////// 
     389// UTF32 
     390 
     391//! UTF-32 encoding.  
     392/*! http://en.wikipedia.org/wiki/UTF-32 
     393        \tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. 
     394        \implements Encoding 
     395*/ 
     396template<typename CharType = unsigned> 
     397struct UTF32 { 
     398        typedef CharType Ch; 
     399 
     400        static Ch *Encode(Ch* buffer, unsigned codepoint) { 
     401                RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); 
     402                *buffer++ = codepoint; 
     403                return buffer; 
     404        } 
     405}; 
    125406 
    126407/////////////////////////////////////////////////////////////////////////////// 
     
    130411        \brief Concept for reading and writing characters. 
    131412 
    132         For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). 
    133  
    134         For write-only stream, only need to implement Put() and Flush(). 
     413        For read-only stream, no need to implement PutBegin(), Put() and PutEnd(). 
     414 
     415        For write-only stream, only need to implement Put(). 
    135416 
    136417\code 
     
    154435        //! Write a character. 
    155436        void Put(Ch c); 
    156  
    157         //! Flush the buffer. 
    158         void Flush(); 
    159437 
    160438        //! End the writing operation. 
     
    190468 
    191469        Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 
    192         void Put(Ch c) { RAPIDJSON_ASSERT(false); } 
    193         void Flush() { RAPIDJSON_ASSERT(false); } 
    194         size_t PutEnd(Ch* begin) { RAPIDJSON_ASSERT(false); return 0; } 
     470        void Put(Ch) { RAPIDJSON_ASSERT(false); } 
     471        size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 
    195472 
    196473        const Ch* src_;         //!< Current read position. 
     
    221498        Ch* PutBegin() { return dst_ = src_; } 
    222499        void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } 
    223         void Flush() {} 
    224500        size_t PutEnd(Ch* begin) { return dst_ - begin; } 
    225501 
  • branches/work_304/thirdparty/rapidjson/reader.h

    r313 r487  
    66 
    77#include "rapidjson.h" 
    8 #include "encodings.h" 
    98#include "internal/pow10.h" 
    109#include "internal/stack.h" 
     
    1716#endif 
    1817 
     18#ifdef _MSC_VER 
     19#pragma warning(push) 
     20#pragma warning(disable : 4127) // conditional expression is constant 
     21#endif 
     22 
    1923#ifndef RAPIDJSON_PARSE_ERROR 
    20 #define RAPIDJSON_PARSE_ERROR(msg, offset) do { parseError_ = msg; errorOffset_ = offset; longjmp(jmpbuf_, 1); } while(false) 
     24#define RAPIDJSON_PARSE_ERROR(msg, offset) \ 
     25        RAPIDJSON_MULTILINEMACRO_BEGIN \ 
     26        parseError_ = msg; \ 
     27        errorOffset_ = offset; \ 
     28        longjmp(jmpbuf_, 1); \ 
     29        RAPIDJSON_MULTILINEMACRO_END 
    2130#endif 
    2231 
     
    2938enum ParseFlag { 
    3039        kParseDefaultFlags = 0,                 //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. 
    31         kParseInsituFlag = 1,                   //!< In-situ(destructive) parsing. 
    32         kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. 
     40        kParseInsituFlag = 1                    //!< In-situ(destructive) parsing. 
    3341}; 
    3442 
     
    7078        void Default() {} 
    7179        void Null() { Default(); } 
    72         void Bool(bool b) { Default(); } 
    73         void Int(int i) { Default(); } 
    74         void Uint(unsigned i) { Default(); } 
    75         void Int64(int64_t i) { Default(); } 
    76         void Uint64(uint64_t i) { Default(); } 
    77         void Double(double d) { Default(); } 
    78         void String(const Ch* str, SizeType length, bool copy) { Default(); } 
     80        void Bool(bool) { Default(); } 
     81        void Int(int) { Default(); } 
     82        void Uint(unsigned) { Default(); } 
     83        void Int64(int64_t) { Default(); } 
     84        void Uint64(uint64_t) { Default(); } 
     85        void Double(double) { Default(); } 
     86        void String(const Ch*, SizeType, bool) { Default(); } 
    7987        void StartObject() { Default(); } 
    80         void EndObject(SizeType memberCount) { Default(); } 
     88        void EndObject(SizeType) { Default(); } 
    8189        void StartArray() { Default(); } 
    82         void EndArray(SizeType elementCount) { Default(); } 
     90        void EndArray(SizeType) { Default(); } 
    8391}; 
    8492 
     
    9098        \note This function has SSE2/SSE4.2 specialization. 
    9199*/ 
    92 template<typename InputStream> 
    93 void SkipWhitespace(InputStream& is) { 
    94         InputStream s = is;     // Use a local copy for optimization 
     100template<typename Stream> 
     101void SkipWhitespace(Stream& stream) { 
     102        Stream s = stream;      // Use a local copy for optimization 
    95103        while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t') 
    96104                s.Take(); 
    97         is = s; 
     105        stream = s; 
    98106} 
    99107 
     
    163171#ifdef RAPIDJSON_SIMD 
    164172//! Template function specialization for InsituStringStream 
    165 template<> inline void SkipWhitespace(InsituStringStream& is) {  
    166         is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_)); 
     173template<> inline void SkipWhitespace(InsituStringStream& stream) {  
     174        stream.src_ = const_cast<char*>(SkipWhitespace_SIMD(stream.src_)); 
    167175} 
    168176 
    169177//! Template function specialization for StringStream 
    170 template<> inline void SkipWhitespace(StringStream& is) { 
    171         is.src_ = SkipWhitespace_SIMD(is.src_); 
     178template<> inline void SkipWhitespace(StringStream& stream) { 
     179        stream.src_ = SkipWhitespace_SIMD(stream.src_); 
    172180} 
    173181#endif // RAPIDJSON_SIMD 
     
    188196    A GenericReader object can be reused for parsing multiple JSON text. 
    189197     
    190     \tparam SourceEncoding Encoding of the input stream. 
    191         \tparam TargetEncoding Encoding of the parse output. 
     198    \tparam Encoding Encoding of both the stream and the parse output. 
    192199    \tparam Allocator Allocator type for stack. 
    193200*/ 
    194 template <typename SourceEncoding, typename TargetEncoding, typename Allocator = MemoryPoolAllocator<> > 
     201template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 
    195202class GenericReader { 
    196203public: 
    197         typedef typename SourceEncoding::Ch Ch; 
     204        typedef typename Encoding::Ch Ch; 
    198205 
    199206        //! Constructor. 
     
    205212        //! Parse JSON text. 
    206213        /*! \tparam parseFlags Combination of ParseFlag.  
    207                  \tparam InputStream Type of input stream. 
     214                 \tparam Stream Type of input stream. 
    208215                 \tparam Handler Type of handler which must implement Handler concept. 
    209216                 \param stream Input stream to be parsed. 
     
    211218                 \return Whether the parsing is successful. 
    212219        */ 
    213         template <unsigned parseFlags, typename InputStream, typename Handler> 
    214         bool Parse(InputStream& is, Handler& handler) { 
     220        template <unsigned parseFlags, typename Stream, typename Handler> 
     221        bool Parse(Stream& stream, Handler& handler) { 
    215222                parseError_ = 0; 
    216223                errorOffset_ = 0; 
    217224 
     225#ifdef _MSC_VER 
     226#pragma warning(push) 
     227#pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable 
     228#endif 
    218229                if (setjmp(jmpbuf_)) { 
     230#ifdef _MSC_VER 
     231#pragma warning(pop) 
     232#endif 
    219233                        stack_.Clear(); 
    220234                        return false; 
    221235                } 
    222236 
    223                 SkipWhitespace(is); 
    224  
    225                 if (is.Peek() == '\0') 
    226                         RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", is.Tell()); 
     237                SkipWhitespace(stream); 
     238 
     239                if (stream.Peek() == '\0') 
     240                        RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell()); 
    227241                else { 
    228                         switch (is.Peek()) { 
    229                                 case '{': ParseObject<parseFlags>(is, handler); break; 
    230                                 case '[': ParseArray<parseFlags>(is, handler); break; 
    231                                 default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", is.Tell()); 
    232                         } 
    233                         SkipWhitespace(is); 
    234  
    235                         if (is.Peek() != '\0') 
    236                                 RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", is.Tell()); 
     242                        switch (stream.Peek()) { 
     243                                case '{': ParseObject<parseFlags>(stream, handler); break; 
     244                                case '[': ParseArray<parseFlags>(stream, handler); break; 
     245                                default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell()); 
     246                        } 
     247                        SkipWhitespace(stream); 
     248 
     249                        if (stream.Peek() != '\0') 
     250                                RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell()); 
    237251                } 
    238252 
     
    246260private: 
    247261        // Parse object: { string : value, ... } 
    248         template<unsigned parseFlags, typename InputStream, typename Handler> 
    249         void ParseObject(InputStream& is, Handler& handler) { 
    250                 RAPIDJSON_ASSERT(is.Peek() == '{'); 
    251                 is.Take();      // Skip '{' 
     262        template<unsigned parseFlags, typename Stream, typename Handler> 
     263        void ParseObject(Stream& stream, Handler& handler) { 
     264                RAPIDJSON_ASSERT(stream.Peek() == '{'); 
     265                stream.Take();  // Skip '{' 
    252266                handler.StartObject(); 
    253                 SkipWhitespace(is); 
    254  
    255                 if (is.Peek() == '}') { 
    256                         is.Take(); 
     267                SkipWhitespace(stream); 
     268 
     269                if (stream.Peek() == '}') { 
     270                        stream.Take(); 
    257271                        handler.EndObject(0);   // empty object 
    258272                        return; 
     
    260274 
    261275                for (SizeType memberCount = 0;;) { 
    262                         if (is.Peek() != '"') 
    263                                 RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", is.Tell()); 
    264  
    265                         ParseString<parseFlags>(is, handler); 
    266                         SkipWhitespace(is); 
    267  
    268                         if (is.Take() != ':') 
    269                                 RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", is.Tell()); 
    270  
    271                         SkipWhitespace(is); 
    272  
    273                         ParseValue<parseFlags>(is, handler); 
    274                         SkipWhitespace(is); 
     276                        if (stream.Peek() != '"') { 
     277                                RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell()); 
     278                                break; 
     279                        } 
     280 
     281                        ParseString<parseFlags>(stream, handler); 
     282                        SkipWhitespace(stream); 
     283 
     284                        if (stream.Take() != ':') { 
     285                                RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell()); 
     286                                break; 
     287                        } 
     288                        SkipWhitespace(stream); 
     289 
     290                        ParseValue<parseFlags>(stream, handler); 
     291                        SkipWhitespace(stream); 
    275292 
    276293                        ++memberCount; 
    277294 
    278                         switch(is.Take()) { 
    279                                 case ',': SkipWhitespace(is); break; 
     295                        switch(stream.Take()) { 
     296                                case ',': SkipWhitespace(stream); break; 
    280297                                case '}': handler.EndObject(memberCount); return; 
    281                                 default:  RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", is.Tell()); 
     298                                default:  RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell()); 
    282299                        } 
    283300                } 
     
    285302 
    286303        // Parse array: [ value, ... ] 
    287         template<unsigned parseFlags, typename InputStream, typename Handler> 
    288         void ParseArray(InputStream& is, Handler& handler) { 
    289                 RAPIDJSON_ASSERT(is.Peek() == '['); 
    290                 is.Take();      // Skip '[' 
     304        template<unsigned parseFlags, typename Stream, typename Handler> 
     305        void ParseArray(Stream& stream, Handler& handler) { 
     306                RAPIDJSON_ASSERT(stream.Peek() == '['); 
     307                stream.Take();  // Skip '[' 
    291308                handler.StartArray(); 
    292                 SkipWhitespace(is); 
    293  
    294                 if (is.Peek() == ']') { 
    295                         is.Take(); 
     309                SkipWhitespace(stream); 
     310 
     311                if (stream.Peek() == ']') { 
     312                        stream.Take(); 
    296313                        handler.EndArray(0); // empty array 
    297314                        return; 
     
    299316 
    300317                for (SizeType elementCount = 0;;) { 
    301                         ParseValue<parseFlags>(is, handler); 
     318                        ParseValue<parseFlags>(stream, handler); 
    302319                        ++elementCount; 
    303                         SkipWhitespace(is); 
    304  
    305                         switch (is.Take()) { 
    306                                 case ',': SkipWhitespace(is); break; 
     320                        SkipWhitespace(stream); 
     321 
     322                        switch (stream.Take()) { 
     323                                case ',': SkipWhitespace(stream); break; 
    307324                                case ']': handler.EndArray(elementCount); return; 
    308                                 default:  RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", is.Tell()); 
    309                         } 
    310                 } 
    311         } 
    312  
    313         template<unsigned parseFlags, typename InputStream, typename Handler> 
    314         void ParseNull(InputStream& is, Handler& handler) { 
    315                 RAPIDJSON_ASSERT(is.Peek() == 'n'); 
    316                 is.Take(); 
    317  
    318                 if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') 
     325                                default:  RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell()); 
     326                        } 
     327                } 
     328        } 
     329 
     330        template<unsigned parseFlags, typename Stream, typename Handler> 
     331        void ParseNull(Stream& stream, Handler& handler) { 
     332                RAPIDJSON_ASSERT(stream.Peek() == 'n'); 
     333                stream.Take(); 
     334 
     335                if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l') 
    319336                        handler.Null(); 
    320337                else 
    321                         RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); 
    322         } 
    323  
    324         template<unsigned parseFlags, typename InputStream, typename Handler> 
    325         void ParseTrue(InputStream& is, Handler& handler) { 
    326                 RAPIDJSON_ASSERT(is.Peek() == 't'); 
    327                 is.Take(); 
    328  
    329                 if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') 
     338                        RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); 
     339        } 
     340 
     341        template<unsigned parseFlags, typename Stream, typename Handler> 
     342        void ParseTrue(Stream& stream, Handler& handler) { 
     343                RAPIDJSON_ASSERT(stream.Peek() == 't'); 
     344                stream.Take(); 
     345 
     346                if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e') 
    330347                        handler.Bool(true); 
    331348                else 
    332                         RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell()); 
    333         } 
    334  
    335         template<unsigned parseFlags, typename InputStream, typename Handler> 
    336         void ParseFalse(InputStream& is, Handler& handler) { 
    337                 RAPIDJSON_ASSERT(is.Peek() == 'f'); 
    338                 is.Take(); 
    339  
    340                 if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') 
     349                        RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell()); 
     350        } 
     351 
     352        template<unsigned parseFlags, typename Stream, typename Handler> 
     353        void ParseFalse(Stream& stream, Handler& handler) { 
     354                RAPIDJSON_ASSERT(stream.Peek() == 'f'); 
     355                stream.Take(); 
     356 
     357                if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e') 
    341358                        handler.Bool(false); 
    342359                else 
    343                         RAPIDJSON_PARSE_ERROR("Invalid value", is.Tell() - 1); 
     360                        RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1); 
    344361        } 
    345362 
    346363        // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). 
    347         template<typename InputStream> 
    348         unsigned ParseHex4(InputStream& is) { 
    349                 InputStream s = is;     // Use a local copy for optimization 
     364        template<typename Stream> 
     365        unsigned ParseHex4(Stream& stream) { 
     366                Stream s = stream;      // Use a local copy for optimization 
    350367                unsigned codepoint = 0; 
    351368                for (int i = 0; i < 4; i++) { 
     
    359376                        else if (c >= 'a' && c <= 'f') 
    360377                                codepoint -= 'a' - 10; 
    361                         else 
     378                        else  
    362379                                RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1); 
    363380                } 
    364                 is = s; // Restore is 
     381                stream = s; // Restore stream 
    365382                return codepoint; 
    366383        } 
    367384 
    368         struct StackStream { 
    369                 typedef typename TargetEncoding::Ch Ch; 
    370  
    371                 StackStream(internal::Stack<Allocator>& stack) : stack_(stack), length_(0) {} 
    372                 void Put(Ch c) { 
    373                         *stack_.template Push<Ch>() = c; 
    374                         ++length_; 
    375                 } 
    376                 internal::Stack<Allocator>& stack_; 
    377                 SizeType length_; 
    378         }; 
    379  
    380         // Parse string and generate String event. Different code paths for kParseInsituFlag. 
    381         template<unsigned parseFlags, typename InputStream, typename Handler> 
    382         void ParseString(InputStream& is, Handler& handler) { 
    383                 InputStream s = is;     // Local copy for optimization 
    384                 if (parseFlags & kParseInsituFlag) { 
    385                         Ch *head = s.PutBegin(); 
    386                         ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); 
    387                         size_t length = s.PutEnd(head) - 1; 
    388                         RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); 
    389                         handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false); 
    390                 } 
    391                 else { 
    392                         StackStream stackStream(stack_); 
    393                         ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); 
    394                         handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true); 
    395                 } 
    396                 is = s;         // Restore is 
    397         } 
    398  
    399         // Parse string to an output is 
    400         // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. 
    401         template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream> 
    402         RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { 
     385        // Parse string, handling the prefix and suffix double quotes and escaping. 
     386        template<unsigned parseFlags, typename Stream, typename Handler> 
     387        void ParseString(Stream& stream, Handler& handler) { 
    403388#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
    404                 static const char escape[256] = { 
     389                static const Ch escape[256] = { 
    405390                        Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',  
    406391                        Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,  
     
    411396#undef Z16 
    412397 
    413                 RAPIDJSON_ASSERT(is.Peek() == '\"'); 
    414                 is.Take();      // Skip '\"' 
     398                Stream s = stream;      // Use a local copy for optimization 
     399                RAPIDJSON_ASSERT(s.Peek() == '\"'); 
     400                s.Take();       // Skip '\"' 
     401                Ch *head; 
     402                SizeType len; 
     403                if (parseFlags & kParseInsituFlag) 
     404                        head = s.PutBegin(); 
     405                else 
     406                        len = 0; 
     407 
     408#define RAPIDJSON_PUT(x) \ 
     409        do { \ 
     410                if (parseFlags & kParseInsituFlag) \ 
     411                        s.Put(x); \ 
     412                else { \ 
     413                        *stack_.template Push<Ch>() = x; \ 
     414                        ++len; \ 
     415                } \ 
     416        } while(false) 
    415417 
    416418                for (;;) { 
    417                         Ch c = is.Peek(); 
     419                        Ch c = s.Take(); 
    418420                        if (c == '\\') {        // Escape 
    419                                 is.Take(); 
    420                                 Ch e = is.Take(); 
    421                                 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) 
    422                                         os.Put(escape[(unsigned char)e]); 
     421                                Ch e = s.Take(); 
     422                                if ((sizeof(Ch) == 1 || e < 256) && escape[(unsigned char)e]) 
     423                                        RAPIDJSON_PUT(escape[(unsigned char)e]); 
    423424                                else if (e == 'u') {    // Unicode 
    424                                         unsigned codepoint = ParseHex4(is); 
    425                                         if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { 
    426                                                 // Handle UTF-16 surrogate pair 
    427                                                 if (is.Take() != '\\' || is.Take() != 'u') 
    428                                                         RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", is.Tell() - 2); 
    429                                                 unsigned codepoint2 = ParseHex4(is); 
    430                                                 if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) 
    431                                                         RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", is.Tell() - 2); 
     425                                        unsigned codepoint = ParseHex4(s); 
     426                                        if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair 
     427                                                if (s.Take() != '\\' || s.Take() != 'u') { 
     428                                                        RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2); 
     429                                                        return; 
     430                                                } 
     431                                                unsigned codepoint2 = ParseHex4(s); 
     432                                                if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) { 
     433                                                        RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2); 
     434                                                        return; 
     435                                                } 
    432436                                                codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; 
    433437                                        } 
    434                                         TEncoding::Encode(os, codepoint); 
    435                                 } 
    436                                 else 
    437                                         RAPIDJSON_PARSE_ERROR("Unknown escape character", is.Tell() - 1); 
     438 
     439                                        Ch buffer[4]; 
     440                                        SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]); 
     441 
     442                                        if (parseFlags & kParseInsituFlag)  
     443                                                for (SizeType i = 0; i < count; i++) 
     444                                                        s.Put(buffer[i]); 
     445                                        else { 
     446                                                memcpy(stack_.template Push<Ch>(count), buffer, count * sizeof(Ch)); 
     447                                                len += count; 
     448                                        } 
     449                                } 
     450                                else { 
     451                                        RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1); 
     452                                        return; 
     453                                } 
    438454                        } 
    439455                        else if (c == '"') {    // Closing double quote 
    440                                 is.Take(); 
    441                                 os.Put('\0');   // null-terminate the string 
     456                                if (parseFlags & kParseInsituFlag) { 
     457                                        size_t length = s.PutEnd(head); 
     458                                        RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); 
     459                                        RAPIDJSON_PUT('\0');    // null-terminate the string 
     460                                        handler.String(head, SizeType(length), false); 
     461                                } 
     462                                else { 
     463                                        RAPIDJSON_PUT('\0'); 
     464                                        handler.String(stack_.template Pop<Ch>(len), len - 1, true); 
     465                                } 
     466                                stream = s;     // restore stream 
    442467                                return; 
    443468                        } 
    444                         else if (c == '\0') 
    445                                 RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", is.Tell() - 1); 
    446                         else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF 
    447                                 RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", is.Tell() - 1); 
    448                         else { 
    449                                 if (parseFlags & kParseValidateEncodingFlag ?  
    450                                         !Transcoder<SEncoding, TEncoding>::Validate(is, os) :  
    451                                         !Transcoder<SEncoding, TEncoding>::Transcode(is, os)) 
    452                                         RAPIDJSON_PARSE_ERROR("Invalid encoding", is.Tell()); 
    453                         } 
    454                 } 
    455         } 
    456  
    457         template<unsigned parseFlags, typename InputStream, typename Handler> 
    458         void ParseNumber(InputStream& is, Handler& handler) { 
    459                 InputStream s = is; // Local copy for optimization 
     469                        else if (c == '\0') { 
     470                                RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1); 
     471                                return; 
     472                        } 
     473                        else if ((unsigned)c < 0x20) {  // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF 
     474                                RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1); 
     475                                return; 
     476                        } 
     477                        else 
     478                                RAPIDJSON_PUT(c);       // Normal character, just copy 
     479                } 
     480#undef RAPIDJSON_PUT 
     481        } 
     482 
     483        template<unsigned parseFlags, typename Stream, typename Handler> 
     484        void ParseNumber(Stream& stream, Handler& handler) { 
     485                Stream s = stream; // Local copy for optimization 
    460486                // Parse minus 
    461487                bool minus = false; 
     
    496522                                } 
    497523                } 
    498                 else 
    499                         RAPIDJSON_PARSE_ERROR("Expect a value here.", is.Tell()); 
     524                else { 
     525                        RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell()); 
     526                        return; 
     527                } 
    500528 
    501529                // Parse 64bit int 
     
    529557                        d = (double)i64; 
    530558                        while (s.Peek() >= '0' && s.Peek() <= '9') { 
    531                                 if (d >= 1E307) 
    532                                         RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); 
     559                                if (d >= 1E307) { 
     560                                        RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); 
     561                                        return; 
     562                                } 
    533563                                d = d * 10 + (s.Take() - '0'); 
    534564                        } 
     
    548578                                --expFrac; 
    549579                        } 
    550                         else 
    551                                 RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", is.Tell()); 
     580                        else { 
     581                                RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell()); 
     582                                return; 
     583                        } 
    552584 
    553585                        while (s.Peek() >= '0' && s.Peek() <= '9') { 
     
    581613                                while (s.Peek() >= '0' && s.Peek() <= '9') { 
    582614                                        exp = exp * 10 + (s.Take() - '0'); 
    583                                         if (exp > 308) 
    584                                                 RAPIDJSON_PARSE_ERROR("Number too big to store in double", is.Tell()); 
    585                                 } 
    586                         } 
    587                         else 
     615                                        if (exp > 308) { 
     616                                                RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell()); 
     617                                                return; 
     618                                        } 
     619                                } 
     620                        } 
     621                        else { 
    588622                                RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell()); 
     623                                return; 
     624                        } 
    589625 
    590626                        if (expMinus) 
     
    612648                } 
    613649 
    614                 is = s; // restore is 
     650                stream = s; // restore stream 
    615651        } 
    616652 
    617653        // Parse any JSON value 
    618         template<unsigned parseFlags, typename InputStream, typename Handler> 
    619         void ParseValue(InputStream& is, Handler& handler) { 
    620                 switch (is.Peek()) { 
    621                         case 'n': ParseNull  <parseFlags>(is, handler); break; 
    622                         case 't': ParseTrue  <parseFlags>(is, handler); break; 
    623                         case 'f': ParseFalse <parseFlags>(is, handler); break; 
    624                         case '"': ParseString<parseFlags>(is, handler); break; 
    625                         case '{': ParseObject<parseFlags>(is, handler); break; 
    626                         case '[': ParseArray <parseFlags>(is, handler); break; 
    627                         default : ParseNumber<parseFlags>(is, handler); 
     654        template<unsigned parseFlags, typename Stream, typename Handler> 
     655        void ParseValue(Stream& stream, Handler& handler) { 
     656                switch (stream.Peek()) { 
     657                        case 'n': ParseNull  <parseFlags>(stream, handler); break; 
     658                        case 't': ParseTrue  <parseFlags>(stream, handler); break; 
     659                        case 'f': ParseFalse <parseFlags>(stream, handler); break; 
     660                        case '"': ParseString<parseFlags>(stream, handler); break; 
     661                        case '{': ParseObject<parseFlags>(stream, handler); break; 
     662                        case '[': ParseArray <parseFlags>(stream, handler); break; 
     663                        default : ParseNumber<parseFlags>(stream, handler); 
    628664                } 
    629665        } 
     
    637673 
    638674//! Reader with UTF8 encoding and default allocator. 
    639 typedef GenericReader<UTF8<>, UTF8<> > Reader; 
     675typedef GenericReader<UTF8<> > Reader; 
    640676 
    641677} // namespace rapidjson 
    642678 
     679#ifdef _MSC_VER 
     680#pragma warning(pop) 
     681#endif 
     682 
    643683#endif // RAPIDJSON_READER_H_ 
  • branches/work_304/thirdparty/rapidjson/stringbuffer.h

    r313 r487  
    2020 
    2121        void Put(Ch c) { *stack_.template Push<Ch>() = c; } 
    22         void Flush() {} 
    2322 
    2423        void Clear() { stack_.Clear(); } 
    2524 
    26         const Ch* GetString() const { 
     25        const char* GetString() const { 
    2726                // Push and pop a null terminator. This is safe. 
    2827                *stack_.template Push<Ch>() = '\0'; 
     
    3231        } 
    3332 
    34         size_t GetSize() const { return stack_.GetSize(); } 
     33        size_t Size() const { return stack_.GetSize(); } 
    3534 
    3635        static const size_t kDefaultCapacity = 256; 
  • branches/work_304/thirdparty/rapidjson/writer.h

    r313 r487  
    88#include <new>          // placement new 
    99 
     10#ifdef _MSC_VER 
     11#pragma warning(push) 
     12#pragma warning(disable : 4127) // conditional expression is constant 
     13#endif 
     14 
    1015namespace rapidjson { 
    1116 
    1217//! JSON writer 
    1318/*! Writer implements the concept Handler. 
    14         It generates JSON text by events to an output os. 
     19        It generates JSON text by events to an output stream. 
    1520 
    1621        User may programmatically calls the functions of a writer to generate JSON text. 
     
    2025        for example Reader::Parse() and Document::Accept(). 
    2126 
    22         \tparam OutputStream Type of output stream. 
    23         \tparam SourceEncoding Encoding of both source strings. 
    24         \tparam TargetEncoding Encoding of and output stream. 
     27        \tparam Stream Type of ouptut stream. 
     28        \tparam Encoding Encoding of both source strings and output. 
    2529        \implements Handler 
    2630*/ 
    27 template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > 
     31template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > 
    2832class Writer { 
    2933public: 
    30         typedef typename SourceEncoding::Ch Ch; 
    31  
    32         Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :  
    33                 os_(os), level_stack_(allocator, levelDepth * sizeof(Level)) {} 
     34        typedef typename Encoding::Ch Ch; 
     35 
     36        Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :  
     37                stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {} 
    3438 
    3539        //@name Implementation of Handler 
     
    4448 
    4549        Writer& String(const Ch* str, SizeType length, bool copy = false) { 
     50                (void)copy; 
    4651                Prefix(kStringType); 
    4752                WriteString(str, length); 
     
    5762 
    5863        Writer& EndObject(SizeType memberCount = 0) { 
     64                (void)memberCount; 
    5965                RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); 
    6066                RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); 
    6167                level_stack_.template Pop<Level>(1); 
    6268                WriteEndObject(); 
    63                 if (level_stack_.Empty())       // end of json text 
    64                         os_.Flush(); 
    6569                return *this; 
    6670        } 
     
    7478 
    7579        Writer& EndArray(SizeType elementCount = 0) { 
     80                (void)elementCount; 
    7681                RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); 
    7782                RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray); 
    7883                level_stack_.template Pop<Level>(1); 
    7984                WriteEndArray(); 
    80                 if (level_stack_.Empty())       // end of json text 
    81                         os_.Flush(); 
    8285                return *this; 
    8386        } 
     
    9093        //! Information for each nested level 
    9194        struct Level { 
    92                 Level(bool inArray) : inArray(inArray), valueCount(0) {} 
     95                Level(bool inArray_) : inArray(inArray_), valueCount(0) {} 
    9396                bool inArray;           //!< true if in array, otherwise in object 
    9497                size_t valueCount;      //!< number of values in this level 
     
    98101 
    99102        void WriteNull()  { 
    100                 os_.Put('n'); os_.Put('u'); os_.Put('l'); os_.Put('l'); 
     103                stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l'); 
    101104        } 
    102105 
    103106        void WriteBool(bool b)  { 
    104107                if (b) { 
    105                         os_.Put('t'); os_.Put('r'); os_.Put('u'); os_.Put('e'); 
     108                        stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e'); 
    106109                } 
    107110                else { 
    108                         os_.Put('f'); os_.Put('a'); os_.Put('l'); os_.Put('s'); os_.Put('e'); 
     111                        stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e'); 
    109112                } 
    110113        } 
     
    112115        void WriteInt(int i) { 
    113116                if (i < 0) { 
    114                         os_.Put('-'); 
     117                        stream_.Put('-'); 
    115118                        i = -i; 
    116119                } 
     
    128131                do { 
    129132                        --p; 
    130                         os_.Put(*p); 
     133                        stream_.Put(*p); 
    131134                } while (p != buffer); 
    132135        } 
     
    134137        void WriteInt64(int64_t i64) { 
    135138                if (i64 < 0) { 
    136                         os_.Put('-'); 
     139                        stream_.Put('-'); 
    137140                        i64 = -i64; 
    138141                } 
     
    150153                do { 
    151154                        --p; 
    152                         os_.Put(*p); 
     155                        stream_.Put(*p); 
    153156                } while (p != buffer); 
    154157        } 
     
    164167                RAPIDJSON_ASSERT(ret >= 1); 
    165168                for (int i = 0; i < ret; i++) 
    166                         os_.Put(buffer[i]); 
     169                        stream_.Put(buffer[i]); 
    167170        } 
    168171 
    169172        void WriteString(const Ch* str, SizeType length)  { 
    170                 static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 
     173                static const char hexDigits[] = "0123456789ABCDEF"; 
    171174                static const char escape[256] = { 
    172175#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
     
    181184                }; 
    182185 
    183                 os_.Put('\"'); 
    184                 GenericStringStream<SourceEncoding> is(str); 
    185                 while (is.Tell() < length) { 
    186                         const Ch c = is.Peek(); 
    187                         if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c])  { 
    188                                 is.Take(); 
    189                                 os_.Put('\\'); 
    190                                 os_.Put(escape[(unsigned char)c]); 
    191                                 if (escape[(unsigned char)c] == 'u') { 
    192                                         os_.Put('0'); 
    193                                         os_.Put('0'); 
    194                                         os_.Put(hexDigits[(unsigned char)c >> 4]); 
    195                                         os_.Put(hexDigits[(unsigned char)c & 0xF]); 
     186                stream_.Put('\"'); 
     187                for (const Ch* p = str; p != str + length; ++p) { 
     188                        if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p])  { 
     189                                stream_.Put('\\'); 
     190                                stream_.Put(escape[(unsigned char)*p]); 
     191                                if (escape[(unsigned char)*p] == 'u') { 
     192                                        stream_.Put('0'); 
     193                                        stream_.Put('0'); 
     194                                        stream_.Put(hexDigits[(*p) >> 4]); 
     195                                        stream_.Put(hexDigits[(*p) & 0xF]); 
    196196                                } 
    197197                        } 
    198198                        else 
    199                                 Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, os_); 
    200                 } 
    201                 os_.Put('\"'); 
    202         } 
    203  
    204         void WriteStartObject() { os_.Put('{'); } 
    205         void WriteEndObject()   { os_.Put('}'); } 
    206         void WriteStartArray()  { os_.Put('['); } 
    207         void WriteEndArray()    { os_.Put(']'); } 
     199                                stream_.Put(*p); 
     200                } 
     201                stream_.Put('\"'); 
     202        } 
     203 
     204        void WriteStartObject() { stream_.Put('{'); } 
     205        void WriteEndObject()   { stream_.Put('}'); } 
     206        void WriteStartArray()  { stream_.Put('['); } 
     207        void WriteEndArray()    { stream_.Put(']'); } 
    208208 
    209209        void Prefix(Type type) { 
     210                (void)type; 
    210211                if (level_stack_.GetSize() != 0) { // this value is not at root 
    211212                        Level* level = level_stack_.template Top<Level>(); 
    212213                        if (level->valueCount > 0) { 
    213214                                if (level->inArray)  
    214                                         os_.Put(','); // add comma if it is not the first element in array 
     215                                        stream_.Put(','); // add comma if it is not the first element in array 
    215216                                else  // in object 
    216                                         os_.Put((level->valueCount % 2 == 0) ? ',' : ':'); 
     217                                        stream_.Put((level->valueCount % 2 == 0) ? ',' : ':'); 
    217218                        } 
    218219                        if (!level->inArray && level->valueCount % 2 == 0) 
     
    224225        } 
    225226 
    226         OutputStream& os_; 
     227        Stream& stream_; 
    227228        internal::Stack<Allocator> level_stack_; 
     229 
     230private: 
     231        // Prohibit assignment for VC C4512 warning 
     232        Writer& operator=(const Writer& w); 
    228233}; 
    229234 
    230235} // namespace rapidjson 
    231236 
     237#ifdef _MSC_VER 
     238#pragma warning(pop) 
     239#endif 
     240 
    232241#endif // RAPIDJSON_RAPIDJSON_H_ 
Note: See TracChangeset for help on using the changeset viewer.