mirror of https://github.com/vitalif/grive2
Remove JSON-C json wrappers, use YAJL for everything
parent
ac1763f2c7
commit
5bc503279a
2
README
2
README
|
@ -19,7 +19,7 @@ Of course these will be added in the future, possibly the next release.
|
||||||
|
|
||||||
You need the following libraries:
|
You need the following libraries:
|
||||||
|
|
||||||
- json-c
|
- yajl
|
||||||
- libcurl
|
- libcurl
|
||||||
- libstdc++
|
- libstdc++
|
||||||
- libgcrypt
|
- libgcrypt
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "http/CurlAgent.hh"
|
#include "http/CurlAgent.hh"
|
||||||
#include "protocol/AuthAgent.hh"
|
#include "protocol/AuthAgent.hh"
|
||||||
#include "protocol/OAuth2.hh"
|
#include "protocol/OAuth2.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
|
|
||||||
#include "bfd/Backtrace.hh"
|
#include "bfd/Backtrace.hh"
|
||||||
#include "util/Exception.hh"
|
#include "util/Exception.hh"
|
||||||
|
@ -164,7 +164,7 @@ int Main( int argc, char **argv )
|
||||||
token.Auth( code ) ;
|
token.Auth( code ) ;
|
||||||
|
|
||||||
// save to config
|
// save to config
|
||||||
config.Set( "refresh_token", Json( token.RefreshToken() ) ) ;
|
config.Set( "refresh_token", Val( token.RefreshToken() ) ) ;
|
||||||
config.Save() ;
|
config.Save() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ find_package(Iberty)
|
||||||
find_package(ZLIB)
|
find_package(ZLIB)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
pkg_check_modules(JSONC REQUIRED json-c)
|
|
||||||
pkg_check_modules(YAJL REQUIRED yajl)
|
pkg_check_modules(YAJL REQUIRED yajl)
|
||||||
|
|
||||||
# additional headers if build unit tests
|
# additional headers if build unit tests
|
||||||
|
@ -45,7 +44,6 @@ include_directories(
|
||||||
${libgrive_SOURCE_DIR}/test
|
${libgrive_SOURCE_DIR}/test
|
||||||
${GDBM_INCLUDE_DIR}
|
${GDBM_INCLUDE_DIR}
|
||||||
${OPT_INCS}
|
${OPT_INCS}
|
||||||
${JSONC_INCLUDE_DIRS}
|
|
||||||
${YAJL_INCLUDE_DIRS}
|
${YAJL_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -87,7 +85,6 @@ add_library( grive STATIC ${LIBGRIVE_SRC} ${OPT_SRC} )
|
||||||
target_link_libraries( grive
|
target_link_libraries( grive
|
||||||
${YAJL_LIBRARIES}
|
${YAJL_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${JSONC_LIBRARIES}
|
|
||||||
${LIBGCRYPT_LIBRARIES}
|
${LIBGCRYPT_LIBRARIES}
|
||||||
${GDBM_LIBRARIES}
|
${GDBM_LIBRARIES}
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace
|
||||||
const std::string state_file = ".grive_state" ;
|
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_http ( agent ),
|
||||||
m_root ( options["path"].Str() ),
|
m_root ( options["path"].Str() ),
|
||||||
m_state ( m_root / state_file, options ),
|
m_state ( m_root / state_file, options ),
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "State.hh"
|
#include "State.hh"
|
||||||
|
|
||||||
#include "http/Header.hh"
|
#include "http/Header.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
#include "util/Exception.hh"
|
#include "util/Exception.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -42,7 +42,7 @@ class Entry ;
|
||||||
class Drive
|
class Drive
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
Drive( http::Agent *agent, const Json& options ) ;
|
Drive( http::Agent *agent, const Val& options ) ;
|
||||||
|
|
||||||
void DetectChanges() ;
|
void DetectChanges() ;
|
||||||
void Update() ;
|
void Update() ;
|
||||||
|
@ -63,7 +63,7 @@ private :
|
||||||
std::string m_resume_link ;
|
std::string m_resume_link ;
|
||||||
fs::path m_root ;
|
fs::path m_root ;
|
||||||
State m_state ;
|
State m_state ;
|
||||||
Json m_options ;
|
Val m_options ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
} } // end of namespace
|
} } // end of namespace
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
// #include "http/ResponseLog.hh"
|
// #include "http/ResponseLog.hh"
|
||||||
#include "http/StringResponse.hh"
|
#include "http/StringResponse.hh"
|
||||||
#include "http/XmlResponse.hh"
|
#include "http/XmlResponse.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
#include "util/CArray.hh"
|
#include "util/CArray.hh"
|
||||||
#include "util/Crypt.hh"
|
#include "util/Crypt.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
|
@ -346,7 +346,7 @@ Resource* Resource::FindChild( const std::string& name )
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to change the state to "sync"
|
// 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( m_state != unknown ) ;
|
||||||
assert( !IsRoot() || m_state == sync ) ; // root folder is already synced
|
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 ) ) ;
|
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() || m_state == sync ) ; // root is always sync
|
||||||
assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ;
|
assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace http
|
||||||
class Agent ;
|
class Agent ;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Json ;
|
class Val ;
|
||||||
|
|
||||||
namespace v1 {
|
namespace v1 {
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public :
|
||||||
void FromRemote( const Entry& remote, const DateTime& last_sync ) ;
|
void FromRemote( const Entry& remote, const DateTime& last_sync ) ;
|
||||||
void FromLocal( 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
|
// children access
|
||||||
iterator begin() const ;
|
iterator begin() const ;
|
||||||
|
@ -136,7 +136,7 @@ private :
|
||||||
void DeleteRemote( http::Agent* http ) ;
|
void DeleteRemote( http::Agent* http ) ;
|
||||||
|
|
||||||
void AssignIDs( const Entry& remote ) ;
|
void AssignIDs( const Entry& remote ) ;
|
||||||
void SyncSelf( http::Agent* http, const Json& options ) ;
|
void SyncSelf( http::Agent* http, const Val& options ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::string m_name ;
|
std::string m_name ;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "ResourceTree.hh"
|
#include "ResourceTree.hh"
|
||||||
#include "CommonUri.hh"
|
#include "CommonUri.hh"
|
||||||
|
|
||||||
#include "protocol/Json.hh"
|
|
||||||
#include "util/Destroy.hh"
|
#include "util/Destroy.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
class Json ;
|
|
||||||
|
|
||||||
namespace v1 {
|
namespace v1 {
|
||||||
|
|
||||||
namespace details
|
namespace details
|
||||||
|
|
|
@ -27,13 +27,14 @@
|
||||||
#include "util/Crypt.hh"
|
#include "util/Crypt.hh"
|
||||||
#include "util/File.hh"
|
#include "util/File.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
|
#include "json/JsonParser.hh"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
namespace gr { namespace v1 {
|
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_res ( options["path"].Str() ),
|
||||||
m_dir ( options["dir"].Str() ),
|
m_dir ( options["dir"].Str() ),
|
||||||
m_cstamp ( -1 )
|
m_cstamp ( -1 )
|
||||||
|
@ -41,7 +42,7 @@ State::State( const fs::path& filename, const Json& options ) :
|
||||||
Read( filename ) ;
|
Read( filename ) ;
|
||||||
|
|
||||||
// the "-f" option will make grive always thinks remote is newer
|
// the "-f" option will make grive always thinks remote is newer
|
||||||
Json force ;
|
Val force ;
|
||||||
if ( options.Get("force", force) && force.Bool() )
|
if ( options.Get("force", force) && force.Bool() )
|
||||||
m_last_sync = DateTime() ;
|
m_last_sync = DateTime() ;
|
||||||
|
|
||||||
|
@ -240,9 +241,10 @@ void State::Read( const fs::path& filename )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File file( filename ) ;
|
File file( filename ) ;
|
||||||
Json json = Json::Parse( &file ) ;
|
|
||||||
|
Val json = ParseJson( file );
|
||||||
Json last_sync = json["last_sync"] ;
|
|
||||||
|
Val last_sync = json["last_sync"] ;
|
||||||
m_last_sync.Assign(
|
m_last_sync.Assign(
|
||||||
last_sync["sec"].Int(),
|
last_sync["sec"].Int(),
|
||||||
last_sync["nsec"].Int() ) ;
|
last_sync["nsec"].Int() ) ;
|
||||||
|
@ -257,19 +259,19 @@ void State::Read( const fs::path& filename )
|
||||||
|
|
||||||
void State::Write( const fs::path& filename ) const
|
void State::Write( const fs::path& filename ) const
|
||||||
{
|
{
|
||||||
Json last_sync ;
|
Val last_sync ;
|
||||||
last_sync.Add( "sec", Json( (int)m_last_sync.Sec() ) );
|
last_sync.Add( "sec", Val( (int)m_last_sync.Sec() ) );
|
||||||
last_sync.Add( "nsec", Json( (unsigned)m_last_sync.NanoSec() ) );
|
last_sync.Add( "nsec", Val( (unsigned)m_last_sync.NanoSec() ) );
|
||||||
|
|
||||||
Json result ;
|
Val result ;
|
||||||
result.Add( "last_sync", last_sync ) ;
|
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() ) ;
|
std::ofstream fs( filename.string().c_str() ) ;
|
||||||
fs << result ;
|
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
|
// 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)
|
// if the sync time hasn't changed (i.e. now files have been uploaded)
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace http
|
||||||
class Agent ;
|
class Agent ;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Json ;
|
class Val ;
|
||||||
|
|
||||||
namespace v1 {
|
namespace v1 {
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public :
|
||||||
typedef ResourceTree::iterator iterator ;
|
typedef ResourceTree::iterator iterator ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
explicit State( const fs::path& filename, const Json& options ) ;
|
explicit State( const fs::path& filename, const Val& options ) ;
|
||||||
~State() ;
|
~State() ;
|
||||||
|
|
||||||
void FromLocal( const fs::path& p ) ;
|
void FromLocal( const fs::path& p ) ;
|
||||||
|
@ -59,7 +59,7 @@ public :
|
||||||
Resource* FindByHref( const std::string& href ) ;
|
Resource* FindByHref( const std::string& href ) ;
|
||||||
Resource* FindByID( const std::string& id ) ;
|
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 begin() ;
|
||||||
iterator end() ;
|
iterator end() ;
|
||||||
|
|
|
@ -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.Parse( json.c_str(), json.size() ) ;
|
||||||
parser.Finish() ;
|
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
|
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()
|
void JsonParser::Finish()
|
||||||
{
|
{
|
||||||
if ( yajl_complete_parse(m_impl->hand) != yajl_status_ok )
|
if ( yajl_complete_parse(m_impl->hand) != yajl_status_ok )
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Val.hh"
|
||||||
#include "util/Exception.hh"
|
#include "util/Exception.hh"
|
||||||
|
#include "util/DataStream.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -29,6 +31,9 @@ namespace gr {
|
||||||
|
|
||||||
class ValVisitor ;
|
class ValVisitor ;
|
||||||
|
|
||||||
|
Val ParseJson( const std::string& json ) ;
|
||||||
|
Val ParseJson( DataStream &in ) ;
|
||||||
|
|
||||||
class JsonParser
|
class JsonParser
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
@ -36,12 +41,11 @@ public :
|
||||||
typedef boost::error_info<struct ParseErr, std::string> ParseErr_ ;
|
typedef boost::error_info<struct ParseErr, std::string> ParseErr_ ;
|
||||||
typedef boost::error_info<struct JsonText, std::string> JsonText_ ;
|
typedef boost::error_info<struct JsonText, std::string> JsonText_ ;
|
||||||
|
|
||||||
static void Parse( const std::string& json, ValVisitor *callback ) ;
|
|
||||||
|
|
||||||
explicit JsonParser( ValVisitor *callback ) ;
|
explicit JsonParser( ValVisitor *callback ) ;
|
||||||
~JsonParser() ;
|
~JsonParser() ;
|
||||||
|
|
||||||
void Parse( const char *str, std::size_t size ) ;
|
void Parse( const char *str, std::size_t size ) ;
|
||||||
|
void Parse( DataStream &in ) ;
|
||||||
void Finish() ;
|
void Finish() ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
|
@ -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 <boost/cstdint.hpp>
|
|
||||||
|
|
||||||
// disable macro re-def warning for json-c headers
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable: 4005)
|
|
||||||
#endif
|
|
||||||
#include <json_tokener.h>
|
|
||||||
#include <linkhash.h>
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
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<int>(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<Json>& arr ) :
|
|
||||||
m_json( ::json_object_new_array( ) )
|
|
||||||
{
|
|
||||||
if ( m_json == 0 )
|
|
||||||
BOOST_THROW_EXCEPTION( Error() << JsonCApi_( "json_object_new_array" ) ) ;
|
|
||||||
|
|
||||||
for ( std::vector<Json>::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<bool>() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_is_type( m_json, json_type_boolean ) == TRUE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool Json::As<bool>() const
|
|
||||||
{
|
|
||||||
return Bool() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Json::Str() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_get_string( m_json ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool Json::Is<std::string>() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_is_type( m_json, json_type_string ) == TRUE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
std::string Json::As<std::string>() const
|
|
||||||
{
|
|
||||||
return Str() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Json::Int() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_get_int( m_json ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
bool Json::Is<int>() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_is_type( m_json, json_type_int ) == TRUE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
boost::int32_t Json::As<boost::int32_t>() const
|
|
||||||
{
|
|
||||||
return Int() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
boost::uint32_t Json::As<boost::uint32_t>() const
|
|
||||||
{
|
|
||||||
return static_cast<boost::uint32_t>(Int()) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
boost::int64_t Json::As<boost::int64_t>() const
|
|
||||||
{
|
|
||||||
return ::json_object_get_int64( m_json ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
boost::uint64_t Json::As<boost::uint64_t>() 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<Type>( ::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<Json::Object>() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_is_type( m_json, json_type_object ) == TRUE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
Json::Object Json::As<Json::Object>() 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<Json::Array>() const
|
|
||||||
{
|
|
||||||
assert( m_json != 0 ) ;
|
|
||||||
return ::json_object_is_type( m_json, json_type_array ) == TRUE ;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
Json::Array Json::As<Json::Array>() 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() ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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 <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
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<std::string, Json> Object ;
|
|
||||||
typedef std::vector<Json> Array ;
|
|
||||||
|
|
||||||
struct Error : virtual Exception {} ;
|
|
||||||
typedef boost::error_info<struct JsonTag, std::string> Json_ ;
|
|
||||||
typedef boost::error_info<struct OutOfRange, std::size_t> OutOfRange_ ;
|
|
||||||
typedef boost::error_info<struct KeyNotFound, std::string> KeyNotFound_ ;
|
|
||||||
typedef boost::error_info<struct JsonCApi, std::string> JsonCApi_ ;
|
|
||||||
typedef boost::error_info<struct Value, std::string> Value_ ;
|
|
||||||
typedef boost::error_info<struct ErrMsg, std::string> ErrMsg_ ;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Val_
|
|
||||||
{
|
|
||||||
typedef boost::error_info<struct Value, T> Err ;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
public :
|
|
||||||
template <typename T>
|
|
||||||
explicit Json( const T& val ) ;
|
|
||||||
|
|
||||||
template <std::size_t n>
|
|
||||||
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 <typename T>
|
|
||||||
bool Is() const ;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
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 <typename T, typename Out>
|
|
||||||
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<T>() ;
|
|
||||||
}
|
|
||||||
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 <typename T> static typename Val_<T>::Err ValueErr( const T& t )
|
|
||||||
{
|
|
||||||
return typename Val_<T>::Err(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
private :
|
|
||||||
struct json_object *m_json ;
|
|
||||||
} ;
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -19,8 +19,7 @@
|
||||||
|
|
||||||
#include "OAuth2.hh"
|
#include "OAuth2.hh"
|
||||||
|
|
||||||
#include "JsonResponse.hh"
|
#include "json/ValResponse.hh"
|
||||||
#include "Json.hh"
|
|
||||||
|
|
||||||
#include "http/CurlAgent.hh"
|
#include "http/CurlAgent.hh"
|
||||||
#include "http/Header.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" +
|
"&redirect_uri=" + "urn:ietf:wg:oauth:2.0:oob" +
|
||||||
"&grant_type=authorization_code" ;
|
"&grant_type=authorization_code" ;
|
||||||
|
|
||||||
http::JsonResponse resp ;
|
http::ValResponse resp ;
|
||||||
http::CurlAgent http ;
|
http::CurlAgent http ;
|
||||||
|
|
||||||
DisableLog dlog( log::debug ) ;
|
DisableLog dlog( log::debug ) ;
|
||||||
http.Post( token_url, post, &resp, http::Header() ) ;
|
http.Post( token_url, post, &resp, http::Header() ) ;
|
||||||
|
|
||||||
Json jresp = resp.Response() ;
|
Val jresp = resp.Response() ;
|
||||||
m_access = jresp["access_token"].Str() ;
|
m_access = jresp["access_token"].Str() ;
|
||||||
m_refresh = jresp["refresh_token"].Str() ;
|
m_refresh = jresp["refresh_token"].Str() ;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +97,7 @@ void OAuth2::Refresh( )
|
||||||
"&client_secret=" + m_client_secret +
|
"&client_secret=" + m_client_secret +
|
||||||
"&grant_type=refresh_token" ;
|
"&grant_type=refresh_token" ;
|
||||||
|
|
||||||
http::JsonResponse resp ;
|
http::ValResponse resp ;
|
||||||
http::CurlAgent http ;
|
http::CurlAgent http ;
|
||||||
|
|
||||||
DisableLog dlog( log::debug ) ;
|
DisableLog dlog( log::debug ) ;
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "Config.hh"
|
#include "Config.hh"
|
||||||
|
|
||||||
#include "util/File.hh"
|
#include "util/File.hh"
|
||||||
|
#include "json/JsonWriter.hh"
|
||||||
|
#include "json/JsonParser.hh"
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
@ -36,13 +38,13 @@ const std::string default_root_folder = ".";
|
||||||
|
|
||||||
Config::Config( const po::variables_map& vm )
|
Config::Config( const po::variables_map& vm )
|
||||||
{
|
{
|
||||||
m_cmd.Add( "log-xml", Json(vm.count("log-xml") > 0) ) ;
|
m_cmd.Add( "log-xml", Val(vm.count("log-xml") > 0) ) ;
|
||||||
m_cmd.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ;
|
m_cmd.Add( "new-rev", Val(vm.count("new-rev") > 0) ) ;
|
||||||
m_cmd.Add( "force", Json(vm.count("force") > 0 ) ) ;
|
m_cmd.Add( "force", Val(vm.count("force") > 0 ) ) ;
|
||||||
m_cmd.Add( "path", Json(vm.count("path") > 0
|
m_cmd.Add( "path", Val(vm.count("path") > 0
|
||||||
? vm["path"].as<std::string>()
|
? vm["path"].as<std::string>()
|
||||||
: default_root_folder ) ) ;
|
: default_root_folder ) ) ;
|
||||||
m_cmd.Add( "dir", Json(vm.count("dir") > 0
|
m_cmd.Add( "dir", Val(vm.count("dir") > 0
|
||||||
? vm["dir"].as<std::string>()
|
? vm["dir"].as<std::string>()
|
||||||
: "" ) ) ;
|
: "" ) ) ;
|
||||||
|
|
||||||
|
@ -68,40 +70,41 @@ const fs::path Config::Filename() const
|
||||||
void Config::Save( )
|
void Config::Save( )
|
||||||
{
|
{
|
||||||
gr::File file( m_path.string(), 0600 ) ;
|
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 ) ;
|
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] ;
|
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() ;
|
Val::Object obj = m_file.AsObject() ;
|
||||||
Json::Object cmd_obj = m_cmd.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 ;
|
obj[i->first] = i->second ;
|
||||||
|
|
||||||
return Json( obj ) ;
|
return Val( obj ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json Config::Read()
|
Val Config::Read()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
gr::File file(m_path) ;
|
gr::File file(m_path) ;
|
||||||
return Json::Parse( &file ) ;
|
return ParseJson( file ) ;
|
||||||
}
|
}
|
||||||
catch ( Exception& e )
|
catch ( Exception& e )
|
||||||
{
|
{
|
||||||
return Json() ;
|
return Val() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "Exception.hh"
|
#include "Exception.hh"
|
||||||
#include "FileSystem.hh"
|
#include "FileSystem.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
@ -43,14 +43,14 @@ public :
|
||||||
|
|
||||||
const fs::path Filename() const ;
|
const fs::path Filename() const ;
|
||||||
|
|
||||||
void Set( const std::string& key, const Json& value ) ;
|
void Set( const std::string& key, const Val& value ) ;
|
||||||
Json Get( const std::string& key ) const ;
|
Val Get( const std::string& key ) const ;
|
||||||
|
|
||||||
Json GetAll() const ;
|
Val GetAll() const ;
|
||||||
void Save() ;
|
void Save() ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
Json Read( ) ;
|
Val Read( ) ;
|
||||||
static fs::path GetPath( const fs::path& root_path ) ;
|
static fs::path GetPath( const fs::path& root_path ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
@ -58,10 +58,10 @@ private :
|
||||||
fs::path m_path;
|
fs::path m_path;
|
||||||
|
|
||||||
//! config values loaded from config file
|
//! config values loaded from config file
|
||||||
Json m_file ;
|
Val m_file ;
|
||||||
|
|
||||||
//! config values from command line
|
//! config values from command line
|
||||||
Json m_cmd ;
|
Val m_cmd ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
|
@ -38,9 +38,7 @@ BOOST_FIXTURE_TEST_SUITE( JsonValTest, F )
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( Test )
|
BOOST_AUTO_TEST_CASE( Test )
|
||||||
{
|
{
|
||||||
ValBuilder b ;
|
Val json = ParseJson( "{\"key\": 100 }" ) ;
|
||||||
JsonParser::Parse( "{\"key\": 100 }", &b ) ;
|
|
||||||
Val json = b.Result() ;
|
|
||||||
|
|
||||||
BOOST_CHECK( json.Is<Val::Object>() ) ;
|
BOOST_CHECK( json.Is<Val::Object>() ) ;
|
||||||
BOOST_CHECK_EQUAL( json["key"].As<long long>(), 100 ) ;
|
BOOST_CHECK_EQUAL( json["key"].As<long long>(), 100 ) ;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "Assert.hh"
|
#include "Assert.hh"
|
||||||
|
|
||||||
#include "drive/State.hh"
|
#include "drive/State.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "Assert.hh"
|
#include "Assert.hh"
|
||||||
|
|
||||||
#include "util/Config.hh"
|
#include "util/Config.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "json/Val.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
|
@ -31,7 +31,7 @@ Source0: https://github.com/grive/%{name}/tarball/v%{version}
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
BuildRequires: libstdc++-devel
|
BuildRequires: libstdc++-devel
|
||||||
BuildRequires: libcurl-devel
|
BuildRequires: libcurl-devel
|
||||||
BuildRequires: json-c-devel
|
BuildRequires: yajl-devel
|
||||||
BuildRequires: expat-devel
|
BuildRequires: expat-devel
|
||||||
BuildRequires: openssl-devel
|
BuildRequires: openssl-devel
|
||||||
BuildRequires: boost-devel
|
BuildRequires: boost-devel
|
||||||
|
|
Loading…
Reference in New Issue