diff --git a/.gitignore b/.gitignore index 2dbbadb..d53ea43 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ /build/*.exe /build/gmake /build/vs*/ +/doc/html /thirdparty/lib /intermediate diff --git a/build/Doxyfile b/build/Doxyfile index 6e60e58..a54bd8e 100644 --- a/build/Doxyfile +++ b/build/Doxyfile @@ -52,7 +52,7 @@ PROJECT_LOGO = # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = ../doc +OUTPUT_DIRECTORY = ./doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output @@ -514,7 +514,7 @@ GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = $(RAPIDJSON_SECTIONS) # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in @@ -548,7 +548,7 @@ SHOW_FILES = YES # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. -SHOW_NAMESPACES = YES +SHOW_NAMESPACES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from @@ -638,7 +638,9 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../include/ +INPUT = ./include/ \ + ./readme.md \ + ./doc/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -660,34 +662,12 @@ FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.for \ - *.vhd \ - *.vhdl + *.md # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. @@ -748,7 +728,7 @@ EXAMPLE_RECURSIVE = NO # directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = ./doc # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1479,13 +1459,13 @@ ENABLE_PREPROCESSING = YES # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. diff --git a/doc/features.md b/doc/features.md index f5d9355..3cc6309 100644 --- a/doc/features.md +++ b/doc/features.md @@ -39,10 +39,10 @@ ## API styles * SAX (Simple API for XML) style API - * Similar to [SAX](http://en.wikipedia.org/wiki/Simple_API_for_XML), RapidJSON provides a event sequential access parser API (`GenericReader`). It also provides a generator API (`GenericWriter`) which consumes the same set of events. + * Similar to [SAX](http://en.wikipedia.org/wiki/Simple_API_for_XML), RapidJSON provides a event sequential access parser API (`rapidjson::GenericReader`). It also provides a generator API (`rapidjson::Writer`) which consumes the same set of events. * DOM (Document Object Model) style API - * Similar to [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) for HTML/XML, RapidJSON can parse JSON into a DOM representation (`GenericDocument`), for easy manipulation, and finally stringify back to JSON if needed. - * The DOM style API (`GenericDocument`) is actually implemented with SAX style API (`GenericReader`). SAX is faster but sometimes DOM is easier. Users can pick their choices according to scenarios. + * Similar to [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) for HTML/XML, RapidJSON can parse JSON into a DOM representation (`rapidjson::GenericDocument`), for easy manipulation, and finally stringify back to JSON if needed. + * The DOM style API (`rapidjson::GenericDocument`) is actually implemented with SAX style API (`rapidjson::GenericReader`). SAX is faster but sometimes DOM is easier. Users can pick their choices according to scenarios. ## DOM (Document) @@ -59,13 +59,13 @@ ## SAX (Writer) -* Support PrettyWriter for adding newlines and indentations. +* Support `rapidjson::PrettyWriter` for adding newlines and indentations. * Support custom precision for floating point values. ## Stream -* Support `GenericStringBuffer` for storing the output JSON as string. -* Support `FileReadStream`/`FileWriteStream` for input/output `FILE` object. +* Support `rapidjson::GenericStringBuffer` for storing the output JSON as string. +* Support `rapidjson::FileReadStream`/`rapidjson::FileWriteStream` for input/output `FILE` object. * Support custom streams. ## Memory diff --git a/doc/stream.md b/doc/stream.md index 441dbaa..84d58bc 100644 --- a/doc/stream.md +++ b/doc/stream.md @@ -1,6 +1,6 @@ # RapidJSON Stream -In RapidJSON, `Stream` is a concept for reading/writing JSON. Here we first show how to use streams provided. And then see how to create a custom streams. +In RapidJSON, `rapidjson::Stream` is a concept for reading/writing JSON. Here we first show how to use streams provided. And then see how to create a custom streams. ## Memory Streams @@ -73,6 +73,8 @@ However, if the JSON is big, or memory is limited, you can use `FileReadStream`. #include "rapidjson/filereadstream.h" #include +using namespace rapidjson; + FILE* fp = fopen("big.json", "rb"); // non-Windows use "r" char readBuffer[65536]; @@ -96,6 +98,8 @@ Apart from reading file, user can also use `FileReadStream` to read `stdin`. #include "rapidjson/filewritestream.h" #include +using namespace rapidjson; + Document d; d.Parse(json); // ... @@ -212,6 +216,8 @@ You can obtain the type of UTF via `UTFType GetType()`. And check whether a BOM Similarly, to choose encoding for output during runtime, we can use `AutoUTFOutputStream`. This class is not automatic *per se*. You need to specify the UTF type and whether to write BOM in runtime. ~~~~~~~~~~cpp +using namespace rapidjson; + void WriteJSONFile(FILE* fp, UTFType type, bool putBOM, const Document& d) { char writeBuffer[256]; FileWriteStream bos(fp, writeBuffer, sizeof(writeBuffer)); diff --git a/doc/tutorial.md b/doc/tutorial.md index 0b3da16..721e747 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -383,7 +383,7 @@ Object is a collection of key-value pairs. Each key must be a string value. The Here is an example. ~~~~~~~~~~cpp -Value contact(kObejct); +Value contact(kObject); contact.AddMember("name", "Milo", document.GetAllocator()); contact.AddMember("married", true, document.GetAllocator()); ~~~~~~~~~~ @@ -433,4 +433,4 @@ This tutorial shows the basics of DOM tree query and manipulation. There are sev 5. [Performance](performance.md) shows some in-house and third-party benchmarks. 6. [Internals](internals.md) describes some internal designs and techniques of RapidJSON. -You may also refer to the FAQ, API documentation, examples and unit tests. +You may also refer to the [FAQ](faq.md), API documentation, examples and unit tests. diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index bc2d836..3fd98b8 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -73,7 +73,7 @@ class GenericMemberIterator public: //! Iterator type itself - typedef GenericMemberIterator Type; + typedef GenericMemberIterator Iterator; //! Constant iterator type typedef GenericMemberIterator ConstType; //! Non-constant iterator type @@ -112,29 +112,29 @@ public: //! @name stepping //@{ - Type& operator++(){ ++ptr_; return *this; } - Type& operator--(){ --ptr_; return *this; } - Type operator++(int){ Type old(*this); ++ptr_; return old; } - Type operator--(int){ Type old(*this); --ptr_; return old; } + 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 //@{ - Type operator+(DifferenceType n) const { return Type(ptr_+n); } - Type operator-(DifferenceType n) const { return Type(ptr_-n); } + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } - Type& operator+=(DifferenceType n) { ptr_+=n; return *this; } - Type& operator-=(DifferenceType n) { ptr_-=n; return *this; } + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } //@} //! @name relations //@{ - bool operator==(Type that) const { return ptr_ == that.ptr_; } - bool operator!=(Type that) const { return ptr_ != that.ptr_; } - bool operator<=(Type that) const { return ptr_ <= that.ptr_; } - bool operator>=(Type that) const { return ptr_ >= that.ptr_; } - bool operator< (Type that) const { return ptr_ < that.ptr_; } - bool operator> (Type that) const { return ptr_ > that.ptr_; } + bool operator==(Iterator that) const { return ptr_ == that.ptr_; } + bool operator!=(Iterator that) const { return ptr_ != that.ptr_; } + bool operator<=(Iterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(Iterator that) const { return ptr_ >= that.ptr_; } + bool operator< (Iterator that) const { return ptr_ < that.ptr_; } + bool operator> (Iterator that) const { return ptr_ > that.ptr_; } //@} //! @name dereference @@ -145,7 +145,7 @@ public: //@} //! Distance - DifferenceType operator-(Type that) const { return ptr_-that.ptr_; } + DifferenceType operator-(Iterator that) const { return ptr_-that.ptr_; } private: //! Internal constructor from plain pointer @@ -165,13 +165,13 @@ struct GenericMemberIterator; template struct GenericMemberIterator { //! use plain pointer as iterator type - typedef GenericMember* Type; + typedef GenericMember* Iterator; }; //! const GenericMemberIterator template struct GenericMemberIterator { //! use plain const pointer as iterator type - typedef const GenericMember* Type; + typedef const GenericMember* Iterator; }; #endif // RAPIDJSON_NOMEMBERITERATORCLASS @@ -198,8 +198,8 @@ public: 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 typename GenericMemberIterator::Type MemberIterator; //!< Member iterator for iterating in object. - typedef typename GenericMemberIterator::Type ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::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. @@ -937,7 +937,7 @@ private: }; #pragma pack (pop) -//! Value with UTF8 encoding. +//! GenericValue with UTF8 encoding typedef GenericValue > Value; /////////////////////////////////////////////////////////////////////////////// @@ -948,6 +948,7 @@ typedef GenericValue > Value; \note implements Handler concept \tparam Encoding encoding for both parsing and string storage. \tparam Allocator allocator for allocating memory for the DOM, and the stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructors. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. */ template > class GenericDocument : public GenericValue { @@ -962,8 +963,13 @@ public: */ GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {} - //! Parse JSON text from an input stream. - /*! \tparam parseFlags Combination of ParseFlag. + //!@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. */ @@ -985,18 +991,34 @@ public: 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 GenericDocument& ParseStream(InputStream& is) { return ParseStream(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 GenericDocument& ParseStream(InputStream& is) { return ParseStream(is); } + //!@} - //! Parse JSON text from a mutable string. - /*! \tparam parseFlags Combination of ParseFlag. + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Transcoding from input Encoding \param str Mutable zero-terminated string to be parsed. \return The document itself for fluent API. */ @@ -1006,17 +1028,31 @@ public: return ParseStream(s); } + //! 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 GenericDocument& ParseInsitu(Ch* str) { return ParseInsitu(str); } + //! 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(str); } + //!@} - //! Parse JSON text from a read-only string. - /*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag). + //!@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 @@ -1026,14 +1062,25 @@ public: return ParseStream(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 GenericDocument& Parse(const Ch* str) { return Parse(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(str); } + //!@} + + //!@name Handling parse errors + //!@{ //! Whether a parse error was occured in the last parsing. bool HasParseError() const { return parseErrorCode_ != kParseErrorNone; } @@ -1044,6 +1091,8 @@ public: //! Get the offset in character of the parsing error. size_t GetErrorOffset() const { return errorOffset_; } + //!@} + //! Get the allocator of this document. Allocator& GetAllocator() { return stack_.GetAllocator(); } @@ -1086,7 +1135,7 @@ private: } private: - // Prohibit assignment + //! Prohibit assignment GenericDocument& operator=(const GenericDocument&); void ClearStack() { @@ -1103,6 +1152,7 @@ private: size_t errorOffset_; }; +//! GenericDocument with UTF8 encoding typedef GenericDocument > Document; // defined here due to the dependency on GenericDocument diff --git a/include/rapidjson/prettywriter.h b/include/rapidjson/prettywriter.h index cbbcdab..5d04433 100644 --- a/include/rapidjson/prettywriter.h +++ b/include/rapidjson/prettywriter.h @@ -24,9 +24,9 @@ public: typedef typename Base::Ch Ch; //! Constructor - /*! \param os Output os. + /*! \param os Output stream. \param allocator User supplied allocator. If it is null, it will create a private one. - \param levelDepth Initial capacity of + \param levelDepth Initial capacity of stack. */ PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} @@ -46,7 +46,9 @@ public: return *this; } - //@name Implementation of Handler. + /*! @name Implementation of Handler + \see Handler + */ //@{ PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } @@ -56,11 +58,6 @@ public: PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } - //! Overridden for fluent API, see \ref Writer::Double() - PrettyWriter& Double(double d, int precision) { - int oldPrecision = Base::GetDoublePrecision(); - return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); - } PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { (void)copy; @@ -117,9 +114,19 @@ public: //@} + /*! @name Convenience extensions */ + //@{ + //! Simpler but slower overload. PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } + //! Overridden for fluent API, see \ref Writer::Double() + PrettyWriter& Double(double d, int precision) { + int oldPrecision = Base::GetDoublePrecision(); + return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); + } + + //@} protected: void PrettyPrefix(Type type) { (void)type; diff --git a/include/rapidjson/rapidjson.h b/include/rapidjson/rapidjson.h index a6d5c06..b6cb2f4 100644 --- a/include/rapidjson/rapidjson.h +++ b/include/rapidjson/rapidjson.h @@ -4,6 +4,16 @@ // Copyright (c) 2011 Milo Yip (miloyip@gmail.com) // Version 0.1 +/*!\file rapidjson.h + \brief common definitions and configuration + + \todo Complete Doxygen documentation for configure macros. + */ + +/*! \mainpage + Documentation can be found in \ref readme.md README. +*/ + #include // malloc(), realloc(), free() #include // memcpy() @@ -14,6 +24,7 @@ // (U)INT64_C constant macros. // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this. #ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS 1 // required by C++ standard #endif @@ -25,6 +36,7 @@ #include #include #endif +//!@endcond #endif // RAPIDJSON_NO_INT64TYPEDEF /////////////////////////////////////////////////////////////////////////////// @@ -46,7 +58,7 @@ //! Endianness of the machine. /*! GCC provided macro for detecting endianness of the target machine. But other compilers may not have this. User can define RAPIDJSON_ENDIAN to either - RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN. + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. */ #ifndef RAPIDJSON_ENDIAN #ifdef __BYTE_ORDER__ @@ -115,7 +127,9 @@ typedef unsigned SizeType; // Adopt from boost #ifndef RAPIDJSON_STATIC_ASSERT +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN namespace rapidjson { + template struct STATIC_ASSERTION_FAILURE; template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; template struct StaticAssertTest {}; @@ -130,7 +144,13 @@ template struct StaticAssertTest {}; #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::StaticAssertTest<\ sizeof(::rapidjson::STATIC_ASSERTION_FAILURE)>\ RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE @@ -139,9 +159,11 @@ template struct StaticAssertTest {}; /////////////////////////////////////////////////////////////////////////////// // Helpers +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN #define RAPIDJSON_MULTILINEMACRO_BEGIN do { #define RAPIDJSON_MULTILINEMACRO_END \ } while((void)0, 0) +//!@endcond /////////////////////////////////////////////////////////////////////////////// // Allocators and Encodings @@ -149,6 +171,7 @@ template struct StaticAssertTest {}; #include "allocators.h" #include "encodings.h" +//! main RapidJSON namespace namespace rapidjson { /////////////////////////////////////////////////////////////////////////////// @@ -246,6 +269,7 @@ struct StreamTraits > { enum { copyOptimization = 1 }; }; +//! String stream with UTF8 encoding. typedef GenericStringStream > StringStream; /////////////////////////////////////////////////////////////////////////////// @@ -282,6 +306,7 @@ struct StreamTraits > { enum { copyOptimization = 1 }; }; +//! Insitu string stream with UTF8 encoding. typedef GenericInsituStringStream > InsituStringStream; /////////////////////////////////////////////////////////////////////////////// diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index dac1537..59d03b6 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -43,6 +43,8 @@ namespace rapidjson { // ParseFlag //! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ enum ParseFlag { kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer. kParseInsituFlag = 1, //!< In-situ(destructive) parsing. @@ -257,7 +259,7 @@ template<> inline void SkipWhitespace(StringStream& is) { /////////////////////////////////////////////////////////////////////////////// // GenericReader -//! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator. +//! 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. @@ -276,7 +278,7 @@ template<> inline void SkipWhitespace(StringStream& is) { template > class GenericReader { public: - typedef typename SourceEncoding::Ch Ch; + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type //! Constructor. /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) @@ -285,12 +287,12 @@ public: GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {} //! Parse JSON text. - /*! \tparam parseFlags Combination of ParseFlag. - \tparam InputStream Type of input stream. - \tparam Handler Type of handler which must implement Handler concept. - \param is Input stream to be parsed. - \param handler The handler to receive events. - \return Whether the parsing is successful. + /*! \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 bool Parse(InputStream& is, Handler& handler) { @@ -321,6 +323,13 @@ public: return !HasParseError(); } + //! 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 bool Parse(InputStream& is, Handler& handler) { return Parse(is, handler); diff --git a/include/rapidjson/stringbuffer.h b/include/rapidjson/stringbuffer.h index fd7aab8..162e5f1 100644 --- a/include/rapidjson/stringbuffer.h +++ b/include/rapidjson/stringbuffer.h @@ -37,6 +37,7 @@ struct GenericStringBuffer { mutable internal::Stack stack_; }; +//! String buffer with UTF8 encoding typedef GenericStringBuffer > StringBuffer; //! Implement specialized version of PutN() with memset() for better performance. diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index 95c550c..979b781 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -25,8 +25,9 @@ namespace rapidjson { for example Reader::Parse() and Document::Accept(). \tparam OutputStream Type of output stream. - \tparam SourceEncoding Encoding of both source strings. - \tparam TargetEncoding Encoding of and output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam Allocator Type of allocator for allocating memory of stack. \note implements Handler concept */ template, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > @@ -34,6 +35,11 @@ class Writer { public: typedef typename SourceEncoding::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. + */ Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : os_(os), level_stack_(allocator, levelDepth * sizeof(Level)), doublePrecision_(kDefaultDoublePrecision) {} @@ -53,8 +59,11 @@ public: //! \see SetDoublePrecision() int GetDoublePrecision() const { return doublePrecision_; } - //@name Implementation of Handler + /*!@name Implementation of Handler + \see Handler + */ //@{ + Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } @@ -75,20 +84,6 @@ public: */ Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } - //! Writes the given \c double value to the stream (explicit precision) - /*! - The currently set double precision is ignored in favor of the explicitly - given precision for this value. - \see Double(), SetDoublePrecision(), GetDoublePrecision() - \param d The value to be written - \param precision The number of significant digits for this value - \return The Writer itself for fluent API. - */ - Writer& Double(double d, int precision) { - int oldPrecision = GetDoublePrecision(); - return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); - } - Writer& String(const Ch* str, SizeType length, bool copy = false) { (void)copy; Prefix(kStringType); @@ -133,9 +128,28 @@ public: } //@} + /*! @name Convenience extensions */ + //@{ + + //! Writes the given \c double value to the stream (explicit precision) + /*! + The currently set double precision is ignored in favor of the explicitly + given precision for this value. + \see Double(), SetDoublePrecision(), GetDoublePrecision() + \param d The value to be written + \param precision The number of significant digits for this value + \return The Writer itself for fluent API. + */ + Writer& Double(double d, int precision) { + int oldPrecision = GetDoublePrecision(); + return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); + } + //! Simpler but slower overload. Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } + //@} + protected: //! Information for each nested level struct Level { diff --git a/readme.md b/readme.md index 6c1fa80..1741d91 100644 --- a/readme.md +++ b/readme.md @@ -37,7 +37,7 @@ Users can build and run the unit tests on their platform/compiler. ## Installation -RapidJSON is a header-only C++ library. Just copy the `rapidjson/include/rapidjson` folder to system or project's include path. +RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path. To build the tests and examples: @@ -45,15 +45,21 @@ To build the tests and examples: 2. Copy premake4 executable to RapidJSON/build (or system path) 3. Run `rapidjson/build/premake.bat` on Windows, `RapidJSON/build/premake.sh` on Linux or other platforms 4. On Windows, build the solution at `rapidjson/build/vs2008/` or `/vs2010/` -5. On other platforms, run GNU make at `rapidjson/build/gmake/` (e.g., `make -f test.make config=release32`, `make -f example.make config=debug32`) +5. On other platforms, run GNU make at `rapidjson/build/gmake/` (e.g., `make -f test.make config=release32`; `make -f example.make config=debug32`) 6. On success, the executable are generated at `rapidjson/bin` +To build the [Doxygen](http://doxygen.org) documentation: + +1. Obtain and install [Doxygen](http://doxygen.org/download.html). +2. In the top-level directory, run `doxygen build/Doxyfile`. +3. Browse the generated documentation in `doc/html`. + ## Usage at a glance This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string. [simpledom.cpp](example/simpledom/simpledom.cpp) -```cpp +~~~~~~~~~~cpp #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" @@ -80,12 +86,12 @@ int main() { std::cout << buffer.GetString() << std::endl; return 0; } -``` +~~~~~~~~~~ Note that this example did not handle potential errors. The following diagram shows the process. -![simpledom](doc/diagram/simpledom.png?raw=true) +![simpledom](doc/diagram/simpledom.png) More [examples](example/) are available.