include/cinder/Json.h
Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2012, The Cinder Project
00003  All rights reserved.
00004  
00005  This code is designed for use with the Cinder C++ library, http://libcinder.org
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00008  the following conditions are met:
00009 
00010     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00011     the following disclaimer.
00012     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00013     the following disclaimer in the documentation and/or other materials provided with the distribution.
00014 
00015  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00016  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00017  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00018  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00019  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00020  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00021  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00022  POSSIBILITY OF SUCH DAMAGE.
00023 */
00024 
00025 #pragma once
00026 
00027 #include "cinder/DataSource.h"
00028 #include "cinder/DataTarget.h"
00029 #include "cinder/Exception.h"
00030 #include "cinder/Utilities.h"
00031 
00032 #include <string>
00033 #include <boost/container/list.hpp>
00034 
00035 namespace Json {
00036     class Value;
00037 }
00038 
00039 namespace cinder {
00040 
00041 class JsonTree {
00042   public:
00043     
00045     typedef boost::container::list<JsonTree> Container;
00046 
00047     typedef Container::const_iterator ConstIter;
00048     typedef Container::iterator Iter;
00050 
00052 
00053   private:
00054     
00056     typedef enum 
00057     { 
00058         NODE_UNKNOWN, NODE_NULL, NODE_ARRAY, NODE_OBJECT, NODE_VALUE
00059     } NodeType;
00060 
00061     typedef enum 
00062     { 
00063         VALUE_BOOL, VALUE_DOUBLE, VALUE_INT, VALUE_STRING, VALUE_UINT
00064     } ValueType;
00066 
00068 
00069   public:
00070 
00072     class ParseOptions {
00073       public:
00075         ParseOptions();
00077         ParseOptions& ignoreErrors( bool ignore = true );
00079         bool    getIgnoreErrors() const;
00080         
00081       private:
00083         bool    mIgnoreErrors;
00085         
00086     };
00087     
00089     class WriteOptions {
00090     public:
00092         WriteOptions();
00094         WriteOptions& createDocument( bool createDocument = true );
00096         WriteOptions& indented( bool indent = true );
00098         bool    getCreateDocument() const;
00100         bool    getIndented() const;
00101         
00102     private:
00104         bool    mCreateDocument;
00105         bool    mIndented;
00107         
00108     };
00109     
00111     
00113     explicit JsonTree();
00115     JsonTree( const JsonTree &jsonTree );
00118     explicit JsonTree( DataSourceRef dataSource, ParseOptions parseOptions = ParseOptions() );
00120     explicit JsonTree( const std::string &jsonString, ParseOptions parseOptions = ParseOptions() );
00122     explicit JsonTree( const std::string &key, bool value );
00124     explicit JsonTree( const std::string &key, double value );
00126     explicit JsonTree( const std::string &key, float value );
00128     explicit JsonTree( const std::string &key, int value );
00130     explicit JsonTree( const std::string &key, const std::string &value );
00132     explicit JsonTree( const std::string &key, const char *value );
00134     explicit JsonTree( const std::string &key, uint32_t value );
00136     explicit JsonTree( const std::string &key, int64_t value );
00138     explicit JsonTree( const std::string &key, uint64_t value );
00139     
00141     static JsonTree                 makeArray( const std::string &key = "" );
00143     static JsonTree                 makeObject( const std::string &key = "" );
00144     
00146 
00148     std::string                     serialize() const;
00149 
00151     Iter                            begin();
00153     ConstIter                       begin() const;
00155     Iter                            end();
00157     ConstIter                       end() const;
00158 
00160     JsonTree&                       operator=( const JsonTree &jsonTree );
00161     
00164     JsonTree&                       operator[]( const std::string &relativePath );
00167     const JsonTree&                 operator[]( const std::string &relativePath ) const;
00169     JsonTree&                       operator[]( size_t index );
00171     const JsonTree&                 operator[]( size_t index ) const;
00173     friend std::ostream&            operator<<( std::ostream &out, const JsonTree &json );
00174     
00177     JsonTree&                       getChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' );
00180     const JsonTree&                 getChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' ) const;
00182     JsonTree&                       getChild( size_t index );
00184     const JsonTree&                 getChild( size_t index ) const;
00186     const Container&        getChildren() const;
00187 
00190     bool                            hasChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' ) const;
00192     bool                            hasChildren() const;
00193 
00195     JsonTree&                       getParent();
00197     const JsonTree&                 getParent() const;
00199     bool                            hasParent() const;
00200 
00202     void                            clear();
00207     void                            pushBack( const JsonTree &newChild );
00209     void                            removeChild( size_t index );
00211     Iter                            removeChild( Iter pos );
00213     void                            replaceChild( size_t index, const JsonTree &newChild );
00215     void                            replaceChild( Iter pos, const JsonTree &newChild );
00216 
00220     void                            write( const fs::path &path, WriteOptions writeOptions = WriteOptions() );
00224     void                            write( DataTargetRef target, WriteOptions writeOptions = WriteOptions() );
00225 
00227     const std::string&              getKey() const;
00228     
00230     std::string                     getPath( char separator = '.' ) const;
00231     
00234     template <typename T> 
00235     inline T                        getValue() const
00236     {
00237         try {
00238             return fromString<T>( mValue );
00239         } catch ( boost::bad_lexical_cast &) {
00240             throw ExcNonConvertible( * this );
00241         }
00242         return (T)0; // Unreachable. Prevents warning.
00243     }
00244 
00246     const std::string&              getValue() const { return mValue; }
00247 
00248 private:
00249 
00251     explicit JsonTree( const std::string &key, const Json::Value &value );
00252 
00253     Json::Value                     createNativeDoc( WriteOptions writeOptions = WriteOptions() ) const;
00254     static Json::Value              deserializeNative( const std::string &jsonString, ParseOptions parseOptions );
00255     static std::string              serializeNative( const Json::Value &value );
00256    
00257     void                            init( const std::string &key, const Json::Value &value, bool setType = false, 
00258         NodeType nodeType = NODE_VALUE, ValueType valueType = VALUE_STRING );
00259     
00260     JsonTree*                       getNodePtr( const std::string &relativePath, bool caseSensitive, char separator ) const;
00261     static bool                     isIndex( const std::string &key );
00262     
00263     Container                       mChildren;
00264     std::string                     mKey;
00265     JsonTree                        *mParent;
00266     NodeType                        mNodeType;
00267     std::string                     mValue;
00268     ValueType                       mValueType;
00270 
00271   public:
00272 
00274 
00276     class Exception : public cinder::Exception 
00277     {
00278     };
00279 
00281     class ExcChildNotFound : public JsonTree::Exception {
00282       public:
00283         ExcChildNotFound( const JsonTree &node, const std::string &key ) throw();
00284         virtual const char* what() const throw() 
00285         { 
00286             return mMessage; 
00287         }
00288 
00289       private:
00290         char mMessage[ 2048 ];
00291     };
00292 
00294     class ExcNonConvertible : public JsonTree::Exception {
00295       public:
00296         ExcNonConvertible( const JsonTree &node ) throw();
00297         virtual const char* what() const throw() 
00298         { 
00299             return mMessage; 
00300         }
00301 
00302       private:
00303         char mMessage[ 2048 ];
00304     };
00305 
00307     class ExcJsonParserError : public JsonTree::Exception {
00308     public:
00309         ExcJsonParserError( const std::string &errorMessage ) throw();
00310         virtual const char* what() const throw() 
00311         { 
00312             return mMessage; 
00313         }
00314         
00315     private:
00316         char mMessage[ 2048 ];
00317     };
00318 
00319 };
00320 
00321 std::ostream&                       operator<<( std::ostream &out, const JsonTree &json );
00322 
00323 }