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 <iterator>
00033 #include <string>
00034 #include <list>
00035 
00036 namespace Json {
00037 class Value;
00038 }
00039 
00040 namespace cinder {
00041 
00042 class JsonTree {
00043   public:
00044     
00046     typedef std::list<JsonTree>::const_iterator ConstIter;
00047     typedef std::list<JsonTree>::iterator Iter;
00049 
00051 
00052   private:
00053     
00055     typedef enum 
00056     { 
00057         NODE_UNKNOWN, NODE_NULL, NODE_ARRAY, NODE_OBJECT, NODE_VALUE
00058     } NodeType;
00059 
00060     typedef enum 
00061     { 
00062         VALUE_BOOL, VALUE_DOUBLE, VALUE_INT, VALUE_STRING, VALUE_UINT
00063     } ValueType;
00065 
00067 
00068   public:
00069 
00071     class ParseOptions {
00072       public:
00074         ParseOptions();
00076         ParseOptions& ignoreErrors( bool ignore = true );
00078         bool    getIgnoreErrors() const;
00079         
00080       private:
00082         bool    mIgnoreErrors;
00084         
00085     };
00086     
00088     class WriteOptions {
00089     public:
00091         WriteOptions();
00093         WriteOptions& createDocument( bool createDocument = true );
00095         WriteOptions& indented( bool indent = true );
00097         bool    getCreateDocument() const;
00099         bool    getIndented() const;
00100         
00101     private:
00103         bool    mCreateDocument;
00104         bool    mIndented;
00106         
00107     };
00108     
00110     
00112     explicit JsonTree();
00114     JsonTree( const JsonTree &jsonTree );
00117     explicit JsonTree( DataSourceRef dataSource, ParseOptions parseOptions = ParseOptions() );
00119     explicit JsonTree( const std::string &jsonString, ParseOptions parseOptions = ParseOptions() );
00121     explicit JsonTree( const std::string &key, bool value );
00123     explicit JsonTree( const std::string &key, double value );
00125     explicit JsonTree( const std::string &key, float value );
00127     explicit JsonTree( const std::string &key, int value );
00129     explicit JsonTree( const std::string &key, const std::string &value );
00131     explicit JsonTree( const std::string &key, const char *value );
00133     explicit JsonTree( const std::string &key, uint32_t value );
00135     explicit JsonTree( const std::string &key, int64_t value );
00137     explicit JsonTree( const std::string &key, uint64_t value );
00138     
00140     static JsonTree                 makeArray( const std::string &key = "" );
00142     static JsonTree                 makeObject( const std::string &key = "" );
00143     
00145 
00147     std::string                     serialize() const;
00148 
00150     Iter                            begin();
00152     ConstIter                       begin() const;
00154     Iter                            end();
00156     ConstIter                       end() const;
00157 
00159     JsonTree&                       operator=( const JsonTree &jsonTree );
00160     
00163     JsonTree&                       operator[]( const std::string &relativePath );
00166     const JsonTree&                 operator[]( const std::string &relativePath ) const;
00168     JsonTree&                       operator[]( size_t index );
00170     const JsonTree&                 operator[]( size_t index ) const;
00172     friend std::ostream&            operator<<( std::ostream &out, const JsonTree &json );
00173     
00176     JsonTree&                       getChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' );
00179     const JsonTree&                 getChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' ) const;
00181     JsonTree&                       getChild( size_t index );
00183     const JsonTree&                 getChild( size_t index ) const;
00185     const std::list<JsonTree>&      getChildren() const;
00186 
00189     bool                            hasChild( const std::string &relativePath, bool caseSensitive = false, char separator = '.' ) const;
00191     bool                            hasChildren() const;
00192 
00194     JsonTree&                       getParent();
00196     const JsonTree&                 getParent() const;
00198     bool                            hasParent() const;
00199 
00201     void                            clear();
00206     void                            pushBack( const JsonTree &newChild );
00208     void                            removeChild( size_t index );
00210     Iter                            removeChild( Iter pos );
00212     void                            replaceChild( size_t index, const JsonTree &newChild );
00214     void                            replaceChild( Iter pos, const JsonTree &newChild );
00215 
00219     void                            write( const fs::path &path, WriteOptions writeOptions = WriteOptions() );
00223     void                            write( DataTargetRef target, WriteOptions writeOptions = WriteOptions() );
00224 
00226     const std::string&              getKey() const;
00227     
00229     std::string                     getPath( char separator = '.' ) const;
00230     
00233     template <typename T> 
00234     inline T                        getValue() const
00235     {
00236         try {
00237             return fromString<T>( mValue );
00238         } catch ( boost::bad_lexical_cast &) {
00239             throw ExcNonConvertible( * this );
00240         }
00241         return (T)0; // Unreachable. Prevents warning.
00242     }
00243 
00245     const std::string&              getValue() const { return mValue; }
00246 
00247 private:
00248 
00250     explicit JsonTree( const std::string &key, const Json::Value &value );
00251 
00252     Json::Value                     createNativeDoc( WriteOptions writeOptions = WriteOptions() ) const;
00253     static Json::Value              deserializeNative( const std::string &jsonString, ParseOptions parseOptions );
00254     static std::string              serializeNative( const Json::Value &value );
00255    
00256     void                            init( const std::string &key, const Json::Value &value, bool setType = false, 
00257         NodeType nodeType = NODE_VALUE, ValueType valueType = VALUE_STRING );
00258     
00259     JsonTree*                       getNodePtr( const std::string &relativePath, bool caseSensitive, char separator ) const;
00260     static bool                     isIndex( const std::string &key );
00261     
00262     std::list<JsonTree>             mChildren;
00263     std::string                     mKey;
00264     JsonTree                        *mParent;
00265     NodeType                        mNodeType;
00266     std::string                     mValue;
00267     ValueType                       mValueType;
00269 
00270   public:
00271 
00273 
00275     class Exception : public cinder::Exception 
00276     {
00277     };
00278 
00280     class ExcChildNotFound : public JsonTree::Exception {
00281       public:
00282         ExcChildNotFound( const JsonTree &node, const std::string &key ) throw();
00283         virtual const char* what() const throw() 
00284         { 
00285             return mMessage; 
00286         }
00287 
00288       private:
00289         char mMessage[ 2048 ];
00290     };
00291 
00293     class ExcNonConvertible : public JsonTree::Exception {
00294       public:
00295         ExcNonConvertible( const JsonTree &node ) throw();
00296         virtual const char* what() const throw() 
00297         { 
00298             return mMessage; 
00299         }
00300 
00301       private:
00302         char mMessage[ 2048 ];
00303     };
00304 
00306     class ExcJsonParserError : public JsonTree::Exception {
00307     public:
00308         ExcJsonParserError( const std::string &errorMessage ) throw();
00309         virtual const char* what() const throw() 
00310         { 
00311             return mMessage; 
00312         }
00313         
00314     private:
00315         char mMessage[ 2048 ];
00316     };
00317 
00318 };
00319 
00320 std::ostream&                       operator<<( std::ostream &out, const JsonTree &json );
00321 
00322 }