diff --git a/README b/README index a713a75..7db8650 100644 --- a/README +++ b/README @@ -19,7 +19,7 @@ Of course these will be added in the future, possibly the next release. You need the following libraries: -- json-c +- yajl - libcurl - libstdc++ - libgcrypt diff --git a/grive/src/main.cc b/grive/src/main.cc index b7b2585..b172f40 100644 --- a/grive/src/main.cc +++ b/grive/src/main.cc @@ -24,7 +24,7 @@ #include "http/CurlAgent.hh" #include "protocol/AuthAgent.hh" #include "protocol/OAuth2.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" #include "bfd/Backtrace.hh" #include "util/Exception.hh" @@ -164,7 +164,7 @@ int Main( int argc, char **argv ) token.Auth( code ) ; // save to config - config.Set( "refresh_token", Json( token.RefreshToken() ) ) ; + config.Set( "refresh_token", Val( token.RefreshToken() ) ) ; config.Save() ; } diff --git a/libgrive/CMakeLists.txt b/libgrive/CMakeLists.txt index a5a3dd7..fd61053 100644 --- a/libgrive/CMakeLists.txt +++ b/libgrive/CMakeLists.txt @@ -12,7 +12,6 @@ find_package(Iberty) find_package(ZLIB) find_package(PkgConfig) -pkg_check_modules(JSONC REQUIRED json-c) pkg_check_modules(YAJL REQUIRED yajl) # additional headers if build unit tests @@ -45,7 +44,6 @@ include_directories( ${libgrive_SOURCE_DIR}/test ${GDBM_INCLUDE_DIR} ${OPT_INCS} - ${JSONC_INCLUDE_DIRS} ${YAJL_INCLUDE_DIRS} ) @@ -87,7 +85,6 @@ add_library( grive STATIC ${LIBGRIVE_SRC} ${OPT_SRC} ) target_link_libraries( grive ${YAJL_LIBRARIES} ${CURL_LIBRARIES} - ${JSONC_LIBRARIES} ${LIBGCRYPT_LIBRARIES} ${GDBM_LIBRARIES} ${Boost_LIBRARIES} diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 3935448..c5e4eef 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -51,7 +51,7 @@ namespace const std::string state_file = ".grive_state" ; } -Drive::Drive( http::Agent *agent, const Json& options ) : +Drive::Drive( http::Agent *agent, const Val& options ) : m_http ( agent ), m_root ( options["path"].Str() ), m_state ( m_root / state_file, options ), diff --git a/libgrive/src/drive/Drive.hh b/libgrive/src/drive/Drive.hh index 0490d5c..1f1e475 100644 --- a/libgrive/src/drive/Drive.hh +++ b/libgrive/src/drive/Drive.hh @@ -22,7 +22,7 @@ #include "State.hh" #include "http/Header.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" #include "util/Exception.hh" #include @@ -42,7 +42,7 @@ class Entry ; class Drive { public : - Drive( http::Agent *agent, const Json& options ) ; + Drive( http::Agent *agent, const Val& options ) ; void DetectChanges() ; void Update() ; @@ -63,7 +63,7 @@ private : std::string m_resume_link ; fs::path m_root ; State m_state ; - Json m_options ; + Val m_options ; } ; } } // end of namespace diff --git a/libgrive/src/drive/Resource.cc b/libgrive/src/drive/Resource.cc index 498a426..a9d28b9 100644 --- a/libgrive/src/drive/Resource.cc +++ b/libgrive/src/drive/Resource.cc @@ -27,7 +27,7 @@ // #include "http/ResponseLog.hh" #include "http/StringResponse.hh" #include "http/XmlResponse.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" #include "util/CArray.hh" #include "util/Crypt.hh" #include "util/log/Log.hh" @@ -346,7 +346,7 @@ Resource* Resource::FindChild( const std::string& name ) } // try to change the state to "sync" -void Resource::Sync( http::Agent *http, DateTime& sync_time, const Json& options ) +void Resource::Sync( http::Agent *http, DateTime& sync_time, const Val& options ) { assert( m_state != unknown ) ; assert( !IsRoot() || m_state == sync ) ; // root folder is already synced @@ -363,7 +363,7 @@ void Resource::Sync( http::Agent *http, DateTime& sync_time, const Json& options boost::bind( &Resource::Sync, _1, http, boost::ref(sync_time), options ) ) ; } -void Resource::SyncSelf( http::Agent* http, const Json& options ) +void Resource::SyncSelf( http::Agent* http, const Val& options ) { assert( !IsRoot() || m_state == sync ) ; // root is always sync assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ; diff --git a/libgrive/src/drive/Resource.hh b/libgrive/src/drive/Resource.hh index 190518e..57f9262 100644 --- a/libgrive/src/drive/Resource.hh +++ b/libgrive/src/drive/Resource.hh @@ -34,7 +34,7 @@ namespace http class Agent ; } -class Json ; +class Val ; namespace v1 { @@ -77,7 +77,7 @@ public : void FromRemote( const Entry& remote, const DateTime& last_sync ) ; void FromLocal( const DateTime& last_sync ) ; - void Sync( http::Agent* http, DateTime& sync_time, const Json& options ) ; + void Sync( http::Agent* http, DateTime& sync_time, const Val& options ) ; // children access iterator begin() const ; @@ -136,7 +136,7 @@ private : void DeleteRemote( http::Agent* http ) ; void AssignIDs( const Entry& remote ) ; - void SyncSelf( http::Agent* http, const Json& options ) ; + void SyncSelf( http::Agent* http, const Val& options ) ; private : std::string m_name ; diff --git a/libgrive/src/drive/ResourceTree.cc b/libgrive/src/drive/ResourceTree.cc index d806232..fa8af7e 100644 --- a/libgrive/src/drive/ResourceTree.cc +++ b/libgrive/src/drive/ResourceTree.cc @@ -20,7 +20,6 @@ #include "ResourceTree.hh" #include "CommonUri.hh" -#include "protocol/Json.hh" #include "util/Destroy.hh" #include "util/log/Log.hh" diff --git a/libgrive/src/drive/ResourceTree.hh b/libgrive/src/drive/ResourceTree.hh index 6bd1501..d0a391c 100644 --- a/libgrive/src/drive/ResourceTree.hh +++ b/libgrive/src/drive/ResourceTree.hh @@ -30,8 +30,6 @@ namespace gr { -class Json ; - namespace v1 { namespace details diff --git a/libgrive/src/drive/State.cc b/libgrive/src/drive/State.cc index 3b227c9..c1a17e5 100644 --- a/libgrive/src/drive/State.cc +++ b/libgrive/src/drive/State.cc @@ -27,13 +27,14 @@ #include "util/Crypt.hh" #include "util/File.hh" #include "util/log/Log.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" +#include "json/JsonParser.hh" #include namespace gr { namespace v1 { -State::State( const fs::path& filename, const Json& options ) : +State::State( const fs::path& filename, const Val& options ) : m_res ( options["path"].Str() ), m_dir ( options["dir"].Str() ), m_cstamp ( -1 ) @@ -41,7 +42,7 @@ State::State( const fs::path& filename, const Json& options ) : Read( filename ) ; // the "-f" option will make grive always thinks remote is newer - Json force ; + Val force ; if ( options.Get("force", force) && force.Bool() ) m_last_sync = DateTime() ; @@ -240,9 +241,10 @@ void State::Read( const fs::path& filename ) try { File file( filename ) ; - Json json = Json::Parse( &file ) ; - - Json last_sync = json["last_sync"] ; + + Val json = ParseJson( file ); + + Val last_sync = json["last_sync"] ; m_last_sync.Assign( last_sync["sec"].Int(), last_sync["nsec"].Int() ) ; @@ -257,19 +259,19 @@ void State::Read( const fs::path& filename ) void State::Write( const fs::path& filename ) const { - Json last_sync ; - last_sync.Add( "sec", Json( (int)m_last_sync.Sec() ) ); - last_sync.Add( "nsec", Json( (unsigned)m_last_sync.NanoSec() ) ); + Val last_sync ; + last_sync.Add( "sec", Val( (int)m_last_sync.Sec() ) ); + last_sync.Add( "nsec", Val( (unsigned)m_last_sync.NanoSec() ) ); - Json result ; + Val result ; result.Add( "last_sync", last_sync ) ; - result.Add( "change_stamp", Json(m_cstamp) ) ; + result.Add( "change_stamp", Val(m_cstamp) ) ; std::ofstream fs( filename.string().c_str() ) ; fs << result ; } -void State::Sync( http::Agent *http, const Json& options ) +void State::Sync( http::Agent *http, const Val& options ) { // set the last sync time from the time returned by the server for the last file synced // if the sync time hasn't changed (i.e. now files have been uploaded) diff --git a/libgrive/src/drive/State.hh b/libgrive/src/drive/State.hh index af79f8d..5049251 100644 --- a/libgrive/src/drive/State.hh +++ b/libgrive/src/drive/State.hh @@ -33,7 +33,7 @@ namespace http class Agent ; } -class Json ; +class Val ; namespace v1 { @@ -46,7 +46,7 @@ public : typedef ResourceTree::iterator iterator ; public : - explicit State( const fs::path& filename, const Json& options ) ; + explicit State( const fs::path& filename, const Val& options ) ; ~State() ; void FromLocal( const fs::path& p ) ; @@ -59,7 +59,7 @@ public : Resource* FindByHref( const std::string& href ) ; Resource* FindByID( const std::string& id ) ; - void Sync( http::Agent *http, const Json& options ) ; + void Sync( http::Agent *http, const Val& options ) ; iterator begin() ; iterator end() ; diff --git a/libgrive/src/json/JsonParser.cc b/libgrive/src/json/JsonParser.cc index 9ae63f4..50092cf 100644 --- a/libgrive/src/json/JsonParser.cc +++ b/libgrive/src/json/JsonParser.cc @@ -114,11 +114,22 @@ namespace }; } -void JsonParser::Parse( const std::string& json, ValVisitor *callback ) +Val ParseJson( const std::string& json ) { - JsonParser parser( callback ) ; + ValBuilder b; + JsonParser parser( &b ) ; parser.Parse( json.c_str(), json.size() ) ; parser.Finish() ; + return b.Result(); +} + +Val ParseJson( DataStream &in ) +{ + ValBuilder b; + JsonParser parser( &b ) ; + parser.Parse( in ) ; + parser.Finish() ; + return b.Result(); } struct JsonParser::Impl @@ -159,6 +170,17 @@ void JsonParser::Parse( const char *str, std::size_t size ) } } +void JsonParser::Parse( DataStream &in ) +{ + char buf[1024] ; + std::size_t count = 0 ; + + while ( (count = in.Read( buf, sizeof(buf) ) ) > 0 ) + { + Parse( buf, count ); + } +} + void JsonParser::Finish() { if ( yajl_complete_parse(m_impl->hand) != yajl_status_ok ) diff --git a/libgrive/src/json/JsonParser.hh b/libgrive/src/json/JsonParser.hh index 27d6a4c..ea9e09e 100644 --- a/libgrive/src/json/JsonParser.hh +++ b/libgrive/src/json/JsonParser.hh @@ -20,7 +20,9 @@ #pragma once +#include "Val.hh" #include "util/Exception.hh" +#include "util/DataStream.hh" #include #include @@ -29,6 +31,9 @@ namespace gr { class ValVisitor ; +Val ParseJson( const std::string& json ) ; +Val ParseJson( DataStream &in ) ; + class JsonParser { public : @@ -36,12 +41,11 @@ public : typedef boost::error_info ParseErr_ ; typedef boost::error_info JsonText_ ; - static void Parse( const std::string& json, ValVisitor *callback ) ; - explicit JsonParser( ValVisitor *callback ) ; ~JsonParser() ; void Parse( const char *str, std::size_t size ) ; + void Parse( DataStream &in ) ; void Finish() ; private : diff --git a/libgrive/src/protocol/Json.cc b/libgrive/src/protocol/Json.cc deleted file mode 100644 index 5abeaf2..0000000 --- a/libgrive/src/protocol/Json.cc +++ /dev/null @@ -1,527 +0,0 @@ -/* - grive: an GPL program to sync a local directory with Google Drive - Copyright (C) 2012 Wan Wai Ho - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation version 2 - of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "Json.hh" - -#include "util/DataStream.hh" - -// needs to include stdint.h before json-c to avoid macro re-def warning -#include - -// disable macro re-def warning for json-c headers -#ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable: 4005) -#endif -#include -#include -#ifdef _MSC_VER - #pragma warning(pop) -#endif - -#include -#include -#include -#include - -namespace gr { - -Json::Json( ) : - m_json( ::json_object_new_object() ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_object" ) - ) ; -} - -Json::Json( const char *str ) : - m_json( ::json_object_new_string( str ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_string" ) - << ValueErr( str ) - ) ; -} - -/** Note that json_object_new_string_len() is not used. -*/ -struct json_object* Json::InitStr( const char *str, std::size_t n ) -{ - struct json_object *j = ::json_object_new_string( str ) ; - if ( j == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_string_len" ) - << ValueErr( std::string(str, n) ) - ) ; - return j ; -} - -template <> -Json::Json( const std::string& str ) : - m_json( InitStr( str.c_str(), str.size() ) ) -{ -} - -template <> -Json::Json( const double& val ) : - m_json( ::json_object_new_double( val ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_double" ) - << ValueErr( val ) - ) ; -} - -template <> -Json::Json( const boost::int32_t& l ) : - m_json( ::json_object_new_int( l ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_int" ) - << ValueErr( l ) - ) ; -} - -template <> -Json::Json( const boost::int64_t& l ) : - m_json( ::json_object_new_int64( l ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_int64" ) - << ValueErr( l ) - ) ; -} - -template <> -Json::Json( const boost::uint32_t& l ) : - m_json( ::json_object_new_int( static_cast(l) ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_int" ) - << ValueErr( l ) - ) ; -} - -template <> -Json::Json( const boost::uint64_t& l ) : - m_json( ::json_object_new_int64( l ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_int64" ) - << ValueErr( l ) - ) ; -} - -template <> -Json::Json( const std::vector& arr ) : - m_json( ::json_object_new_array( ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( Error() << JsonCApi_( "json_object_new_array" ) ) ; - - for ( std::vector::const_iterator i = arr.begin() ; i != arr.end() ; ++i ) - Add( *i ) ; -} - -template <> -Json::Json( const bool& b ) : - m_json( ::json_object_new_boolean( b ) ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_new_boolean" ) - << ValueErr( b ) - ) ; -} - -template <> -Json::Json( const Object& obj ) : - m_json( ::json_object_new_object() ) -{ - if ( m_json == 0 ) - BOOST_THROW_EXCEPTION( Error() << JsonCApi_( "json_object_new_object" ) ) ; - - for ( Object::const_iterator i = obj.begin() ; i != obj.end() ; ++i ) - Add( i->first, i->second ) ; -} - -Json::Json( struct json_object *json, NotOwned ) : - m_json( json ) -{ - assert( m_json != 0 ) ; -} - -Json::Json( struct json_object *json ) : - m_json( json ) -{ - assert( json != 0 ) ; - ::json_object_get( m_json ) ; -} - -Json::Json( const Json& rhs ) : - m_json( rhs.m_json ) -{ - assert( m_json != 0 ) ; - ::json_object_get( m_json ) ; -} - -Json::~Json( ) -{ - assert( m_json != 0 ) ; - if ( m_json != 0 ) - ::json_object_put( m_json ) ; -} - -Json& Json::operator=( const Json& rhs ) -{ - Json tmp( rhs ) ; - Swap( tmp ) ; - return *this ; -} - -void Json::Swap( Json& other ) -{ - assert( m_json != 0 ) ; - assert( other.m_json != 0 ) ; - std::swap( m_json, other.m_json ) ; -} - -Json Json::operator[]( const std::string& key ) const -{ - assert( m_json != 0 ) ; - - struct json_object *j = 0 ; - if ( !::json_object_object_get_ex( m_json, key.c_str(), &j ) ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_object_get" ) - << KeyNotFound_( key ) - << Json_( ::json_object_to_json_string(m_json) ) ) ; - - assert( j != 0 ) ; - return Json( j ) ; -} - -Json Json::operator[]( const std::size_t& idx ) const -{ - assert( m_json != 0 ) ; - - struct json_object *j = ::json_object_array_get_idx( m_json, idx ) ; - if ( j == 0 ) - { - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_object_array_get_idx" ) - << OutOfRange_( idx ) - << Json_( ::json_object_to_json_string(m_json) ) ) ; - } - - return Json( j ) ; -} - -bool Json::Has( const std::string& key ) const -{ - assert( m_json != 0 ) ; - return ::json_object_object_get_ex( m_json, key.c_str(), 0 ) == TRUE ; -} - -bool Json::Get( const std::string& key, Json& json ) const -{ - assert( m_json != 0 ) ; - struct json_object *j = 0 ; - if ( ::json_object_object_get_ex( m_json, key.c_str(), &j ) ) - { - assert( j != 0 ) ; - - Json tmp( j ) ; - json.Swap( tmp ) ; - return true ; - } - else - return false ; -} - -void Json::Add( const std::string& key, const Json& json ) -{ - assert( m_json != 0 ) ; - assert( json.m_json != 0 ) ; - - ::json_object_get( json.m_json ) ; - ::json_object_object_add( m_json, key.c_str(), json.m_json ) ; -} - -void Json::Add( const Json& json ) -{ - assert( m_json != 0 ) ; - assert( json.m_json != 0 ) ; - - ::json_object_get( json.m_json ) ; - ::json_object_array_add( m_json, json.m_json ) ; -} - -bool Json::Bool() const -{ - assert( m_json != 0 ) ; - return ::json_object_get_boolean( m_json ) == TRUE ; -} - -template <> -bool Json::Is() const -{ - assert( m_json != 0 ) ; - return ::json_object_is_type( m_json, json_type_boolean ) == TRUE ; -} - -template <> -bool Json::As() const -{ - return Bool() ; -} - -std::string Json::Str() const -{ - assert( m_json != 0 ) ; - return ::json_object_get_string( m_json ) ; -} - -template <> -bool Json::Is() const -{ - assert( m_json != 0 ) ; - return ::json_object_is_type( m_json, json_type_string ) == TRUE ; -} - -template <> -std::string Json::As() const -{ - return Str() ; -} - -int Json::Int() const -{ - assert( m_json != 0 ) ; - return ::json_object_get_int( m_json ) ; -} - -template <> -bool Json::Is() const -{ - assert( m_json != 0 ) ; - return ::json_object_is_type( m_json, json_type_int ) == TRUE ; -} - -template <> -boost::int32_t Json::As() const -{ - return Int() ; -} - -template <> -boost::uint32_t Json::As() const -{ - return static_cast(Int()) ; -} - -template <> -boost::int64_t Json::As() const -{ - return ::json_object_get_int64( m_json ) ; -} - -template <> -boost::uint64_t Json::As() const -{ - return ::json_object_get_int64( m_json ) ; -} - -std::ostream& operator<<( std::ostream& os, const Json& json ) -{ - assert( json.m_json != 0 ) ; - return os << ::json_object_to_json_string( json.m_json ) ; -} - -void Json::Write( DataStream *out ) const -{ - assert( out != 0 ) ; - - const char *str = ::json_object_to_json_string( m_json ) ; - out->Write( str, std::strlen(str) ) ; -} - -Json::Type Json::DataType() const -{ - assert( m_json != 0 ) ; - return static_cast( ::json_object_get_type( m_json ) ) ; -} - -Json::Object Json::AsObject() const -{ - Object result ; - - json_object_object_foreach( m_json, key, val ) - { - result.insert( Object::value_type( key, Json( val ) ) ) ; - } - - return result ; -} - -template <> -bool Json::Is() const -{ - assert( m_json != 0 ) ; - return ::json_object_is_type( m_json, json_type_object ) == TRUE ; -} - -template <> -Json::Object Json::As() const -{ - return AsObject() ; -} - -Json::Array Json::AsArray() const -{ - std::size_t count = ::json_object_array_length( m_json ) ; - Array result ; - - for ( std::size_t i = 0 ; i < count ; ++i ) - result.push_back( Json( ::json_object_array_get_idx( m_json, i ) ) ) ; - - return result ; -} - -template <> -bool Json::Is() const -{ - assert( m_json != 0 ) ; - return ::json_object_is_type( m_json, json_type_array ) == TRUE ; -} - -template <> -Json::Array Json::As() const -{ - return AsArray() ; -} - -/// Finds an element in the array. -/// \pre "this" is an array -/// \return *this[i] if *this[i][key] == value -Json Json::FindInArray( const std::string& key, const std::string& value ) const -{ - std::size_t count = ::json_object_array_length( m_json ) ; - - for ( std::size_t i = 0 ; i < count ; ++i ) - { - Json item( ::json_object_array_get_idx( m_json, i ) ) ; - if ( item.Has(key) && item[key].Str() == value ) - return item ; - } - - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "Json::FindInArray" ) - << KeyNotFound_( key ) - << Value_(value) - ) ; - - // shut off compiler warnings - return Json() ; -} - -bool Json::FindInArray( const std::string& key, const std::string& value, Json& result ) const -{ - try - { - result = FindInArray( key, value ) ; - return true ; - } - catch ( Error& ) - { - } - return false ; -} - -Json Json::Parse( const std::string& str ) -{ - struct json_object *json = ::json_tokener_parse( str.c_str() ) ; - if ( json == 0 ) - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_tokener_parse" ) - << ValueErr( str ) - ) ; - - return Json( json, NotOwned() ) ; -} - -/// Parse a file. The file is loaded from file system. -/// \throw Error expt::ErrMsg contains a human-readable message describing the -/// error. -Json Json::Parse( DataStream *in ) -{ - assert( in != 0 ) ; - - struct json_tokener *tok = ::json_tokener_new() ; - struct json_object *json = 0 ; - - char buf[1024] ; - std::size_t count = 0 ; - - while ( (count = in->Read( buf, sizeof(buf) ) ) > 0 ) - { - json = ::json_tokener_parse_ex( tok, buf, count ) ; - - // check for parse error - if ( ::json_tokener_get_error(tok) == ::json_tokener_continue ) - break ; - } - - // save the error code and free the tokener before throwing exceptions - ::json_tokener_error err = ::json_tokener_get_error(tok) ; - ::json_tokener_free( tok ) ; tok = 0 ; - - if ( err != json_tokener_success || json == 0 ) - { - BOOST_THROW_EXCEPTION( - Error() - << JsonCApi_( "json_tokener_parse" ) - << ErrMsg_( ::json_tokener_error_desc(err) ) - ) ; - } - - return Json( json, NotOwned() ) ; -} - -} diff --git a/libgrive/src/protocol/Json.hh b/libgrive/src/protocol/Json.hh deleted file mode 100644 index 320f9d7..0000000 --- a/libgrive/src/protocol/Json.hh +++ /dev/null @@ -1,144 +0,0 @@ -/* - grive: an GPL program to sync a local directory with Google Drive - Copyright (C) 2012 Wan Wai Ho - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation version 2 - of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#pragma once - -#include "util/Exception.hh" - -#include -#include -#include - -struct json_object ; - -namespace gr { - -class DataStream ; - -/*! \brief Simple wrapper around JSON-C objects. - - This class represents JSON-C objects, which can be integers, booleans, strings - double, arrays and object. -*/ -class Json -{ -public : - typedef std::map Object ; - typedef std::vector Array ; - - struct Error : virtual Exception {} ; - typedef boost::error_info Json_ ; - typedef boost::error_info OutOfRange_ ; - typedef boost::error_info KeyNotFound_ ; - typedef boost::error_info JsonCApi_ ; - typedef boost::error_info Value_ ; - typedef boost::error_info ErrMsg_ ; - - template - struct Val_ - { - typedef boost::error_info Err ; - } ; - -public : - template - explicit Json( const T& val ) ; - - template - explicit Json( const char (&str)[n] ) : - m_json( InitStr( str, n ) ) - { - } - - Json() ; - Json( const Json& rhs ) ; - Json( const char *str ) ; - ~Json() ; - - static Json Parse( const std::string& str ) ; - static Json Parse( DataStream *in ) ; - - Json operator[]( const std::string& key ) const ; - Json operator[]( const std::size_t& idx ) const ; - Json& operator=( const Json& rhs ) ; - - void Swap( Json& other ) ; - - std::string Str() const ; - int Int() const ; - double Double() const ; - bool Bool() const ; - Array AsArray() const ; - Object AsObject() const ; - - template - bool Is() const ; - - template - T As() const ; - - bool Has( const std::string& key ) const ; - bool Get( const std::string& key, Json& json ) const ; - void Add( const std::string& key, const Json& json ) ; - void Add( const Json& json ) ; - Json FindInArray( const std::string& key, const std::string& value ) const ; - bool FindInArray( const std::string& key, const std::string& value, Json& result ) const ; - - /** Expect *this is a JSON array of objects. Select all "key" values inside each - objects in the array and copies them in the output iterator \a out. - */ - template - Out Select( const std::string& key, Out out ) - { - Array a = AsArray() ; - for ( Array::iterator i = a.begin() ; i != a.end() ; ++i ) - { - Json value; - if ( i->Get( key, value ) ) - *out++ = value.As() ; - } - return out ; - } - - friend std::ostream& operator<<( std::ostream& os, const Json& json ) ; - void Write( DataStream *out ) const ; - - enum Type { null_type, bool_type, double_type, int_type, object_type, array_type, string_type } ; - - Type DataType() const ; - -private : - Json( struct json_object *json ) ; - - struct NotOwned {} ; - Json( struct json_object *json, NotOwned ) ; - - static struct json_object* InitStr( const char *str, std::size_t n ) ; - - // helper for throwing exception - template static typename Val_::Err ValueErr( const T& t ) - { - return typename Val_::Err(t); - } - -private : - struct json_object *m_json ; -} ; - -} diff --git a/libgrive/src/protocol/JsonResponse.cc b/libgrive/src/protocol/JsonResponse.cc deleted file mode 100644 index a30d0e3..0000000 --- a/libgrive/src/protocol/JsonResponse.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - grive: an GPL program to sync a local directory with Google Drive - Copyright (C) 2012 Wan Wai Ho - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation version 2 - of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "JsonResponse.hh" - -#include "protocol/Json.hh" - -namespace gr { namespace http { - -JsonResponse::JsonResponse() -{ -} - -std::size_t JsonResponse::Write( const char *data, std::size_t count ) -{ - return m_resp.Write( data, count ) ; -} - -std::size_t JsonResponse::Read( char *data, std::size_t count ) -{ - return count ; -} - -Json JsonResponse::Response() const -{ - return Json::Parse( m_resp.Response() ) ; -} - -} } // end of namespace diff --git a/libgrive/src/protocol/JsonResponse.hh b/libgrive/src/protocol/JsonResponse.hh deleted file mode 100644 index 2b6322f..0000000 --- a/libgrive/src/protocol/JsonResponse.hh +++ /dev/null @@ -1,46 +0,0 @@ -/* - grive: an GPL program to sync a local directory with Google Drive - Copyright (C) 2012 Wan Wai Ho - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation version 2 - of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#pragma once - -#include "util/DataStream.hh" -#include "http/StringResponse.hh" - -namespace gr -{ - class Json ; -} - -namespace gr { namespace http { - -class JsonResponse : public DataStream -{ -public : - JsonResponse() ; - - std::size_t Write( const char *data, std::size_t count ) ; - std::size_t Read( char *data, std::size_t count ) ; - - Json Response() const ; - -private : - StringResponse m_resp ; -} ; - -} } // end of namespace diff --git a/libgrive/src/protocol/OAuth2.cc b/libgrive/src/protocol/OAuth2.cc index 5d2c172..a13c8e3 100644 --- a/libgrive/src/protocol/OAuth2.cc +++ b/libgrive/src/protocol/OAuth2.cc @@ -19,8 +19,7 @@ #include "OAuth2.hh" -#include "JsonResponse.hh" -#include "Json.hh" +#include "json/ValResponse.hh" #include "http/CurlAgent.hh" #include "http/Header.hh" @@ -61,13 +60,13 @@ void OAuth2::Auth( const std::string& auth_code ) "&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob" + "&grant_type=authorization_code" ; - http::JsonResponse resp ; + http::ValResponse resp ; http::CurlAgent http ; DisableLog dlog( log::debug ) ; http.Post( token_url, post, &resp, http::Header() ) ; - Json jresp = resp.Response() ; + Val jresp = resp.Response() ; m_access = jresp["access_token"].Str() ; m_refresh = jresp["refresh_token"].Str() ; } @@ -98,7 +97,7 @@ void OAuth2::Refresh( ) "&client_secret=" + m_client_secret + "&grant_type=refresh_token" ; - http::JsonResponse resp ; + http::ValResponse resp ; http::CurlAgent http ; DisableLog dlog( log::debug ) ; diff --git a/libgrive/src/util/Config.cc b/libgrive/src/util/Config.cc index 12c22c7..ca7c86a 100644 --- a/libgrive/src/util/Config.cc +++ b/libgrive/src/util/Config.cc @@ -20,6 +20,8 @@ #include "Config.hh" #include "util/File.hh" +#include "json/JsonWriter.hh" +#include "json/JsonParser.hh" #include @@ -36,13 +38,13 @@ const std::string default_root_folder = "."; Config::Config( const po::variables_map& vm ) { - m_cmd.Add( "log-xml", Json(vm.count("log-xml") > 0) ) ; - m_cmd.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ; - m_cmd.Add( "force", Json(vm.count("force") > 0 ) ) ; - m_cmd.Add( "path", Json(vm.count("path") > 0 + m_cmd.Add( "log-xml", Val(vm.count("log-xml") > 0) ) ; + m_cmd.Add( "new-rev", Val(vm.count("new-rev") > 0) ) ; + m_cmd.Add( "force", Val(vm.count("force") > 0 ) ) ; + m_cmd.Add( "path", Val(vm.count("path") > 0 ? vm["path"].as() : default_root_folder ) ) ; - m_cmd.Add( "dir", Json(vm.count("dir") > 0 + m_cmd.Add( "dir", Val(vm.count("dir") > 0 ? vm["dir"].as() : "" ) ) ; @@ -68,40 +70,41 @@ const fs::path Config::Filename() const void Config::Save( ) { gr::File file( m_path.string(), 0600 ) ; - m_file.Write( &file ) ; + JsonWriter wr( &file ) ; + m_file.Visit( &wr ) ; } -void Config::Set( const std::string& key, const Json& value ) +void Config::Set( const std::string& key, const Val& value ) { m_file.Add( key, value ) ; } -Json Config::Get( const std::string& key ) const +Val Config::Get( const std::string& key ) const { return m_cmd.Has(key) ? m_cmd[key] : m_file[key] ; } -Json Config::GetAll() const +Val Config::GetAll() const { - Json::Object obj = m_file.AsObject() ; - Json::Object cmd_obj = m_cmd.AsObject() ; + Val::Object obj = m_file.AsObject() ; + Val::Object cmd_obj = m_cmd.AsObject() ; - for ( Json::Object::iterator i = cmd_obj.begin() ; i != cmd_obj.end() ; ++i ) + for ( Val::Object::iterator i = cmd_obj.begin() ; i != cmd_obj.end() ; ++i ) obj[i->first] = i->second ; - return Json( obj ) ; + return Val( obj ) ; } -Json Config::Read() +Val Config::Read() { try { gr::File file(m_path) ; - return Json::Parse( &file ) ; + return ParseJson( file ) ; } catch ( Exception& e ) { - return Json() ; + return Val() ; } } diff --git a/libgrive/src/util/Config.hh b/libgrive/src/util/Config.hh index e2c0423..9a654c5 100644 --- a/libgrive/src/util/Config.hh +++ b/libgrive/src/util/Config.hh @@ -21,7 +21,7 @@ #include "Exception.hh" #include "FileSystem.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" namespace boost { @@ -43,14 +43,14 @@ public : const fs::path Filename() const ; - void Set( const std::string& key, const Json& value ) ; - Json Get( const std::string& key ) const ; + void Set( const std::string& key, const Val& value ) ; + Val Get( const std::string& key ) const ; - Json GetAll() const ; + Val GetAll() const ; void Save() ; private : - Json Read( ) ; + Val Read( ) ; static fs::path GetPath( const fs::path& root_path ) ; private : @@ -58,10 +58,10 @@ private : fs::path m_path; //! config values loaded from config file - Json m_file ; + Val m_file ; //! config values from command line - Json m_cmd ; + Val m_cmd ; } ; } // end of namespace diff --git a/libgrive/test/btest/JsonValTest.cc b/libgrive/test/btest/JsonValTest.cc index d5087cd..bbf2d9e 100644 --- a/libgrive/test/btest/JsonValTest.cc +++ b/libgrive/test/btest/JsonValTest.cc @@ -38,9 +38,7 @@ BOOST_FIXTURE_TEST_SUITE( JsonValTest, F ) BOOST_AUTO_TEST_CASE( Test ) { - ValBuilder b ; - JsonParser::Parse( "{\"key\": 100 }", &b ) ; - Val json = b.Result() ; + Val json = ParseJson( "{\"key\": 100 }" ) ; BOOST_CHECK( json.Is() ) ; BOOST_CHECK_EQUAL( json["key"].As(), 100 ) ; diff --git a/libgrive/test/drive/StateTest.cc b/libgrive/test/drive/StateTest.cc index e2ed768..167dab2 100644 --- a/libgrive/test/drive/StateTest.cc +++ b/libgrive/test/drive/StateTest.cc @@ -22,7 +22,7 @@ #include "Assert.hh" #include "drive/State.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" #include "util/log/Log.hh" #include diff --git a/libgrive/test/util/ConfigTest.cc b/libgrive/test/util/ConfigTest.cc index 48d7602..9974dd5 100644 --- a/libgrive/test/util/ConfigTest.cc +++ b/libgrive/test/util/ConfigTest.cc @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "Assert.hh" #include "util/Config.hh" -#include "protocol/Json.hh" +#include "json/Val.hh" #include "util/log/Log.hh" #include diff --git a/package/fedora16/grive.spec b/package/fedora16/grive.spec index 03770b9..3a7e767 100644 --- a/package/fedora16/grive.spec +++ b/package/fedora16/grive.spec @@ -31,7 +31,7 @@ Source0: https://github.com/grive/%{name}/tarball/v%{version} BuildRequires: cmake BuildRequires: libstdc++-devel BuildRequires: libcurl-devel -BuildRequires: json-c-devel +BuildRequires: yajl-devel BuildRequires: expat-devel BuildRequires: openssl-devel BuildRequires: boost-devel