mirror of https://github.com/vitalif/grive2
new qt gui
parent
113b1107d8
commit
755ee1c9ad
|
@ -6,6 +6,8 @@ set( GRIVE_VERSION "0.3.0-pre" )
|
|||
# common compile options
|
||||
add_definitions( -DVERSION="${GRIVE_VERSION}" )
|
||||
add_definitions( -D_FILE_OFFSET_BITS=64 )
|
||||
add_definitions( -DPROJ_NS=gr )
|
||||
|
||||
add_subdirectory( libgrive )
|
||||
add_subdirectory( grive )
|
||||
add_subdirectory( bgrive )
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
project( bgrive )
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(Boost REQUIRED)
|
||||
INCLUDE(${QT_USE_FILE})
|
||||
|
||||
include_directories(
|
||||
${bgrive_SOURCE_DIR}/../libgrive/src
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
file (GLOB BGRIVE_EXE_SRC
|
||||
${bgrive_SOURCE_DIR}/src/*.cc
|
||||
)
|
||||
|
||||
file (GLOB BGRIVE_UI
|
||||
${bgrive_SOURCE_DIR}/ui/*.ui
|
||||
)
|
||||
|
||||
QT4_WRAP_UI(BGRIVE_UI_SRCS ${BGRIVE_UI})
|
||||
QT4_WRAP_CPP(BGRIVE_MOC_SRCS
|
||||
src/MainWnd.hh )
|
||||
|
||||
add_executable( bgrive_executable
|
||||
${BGRIVE_EXE_SRC}
|
||||
${BGRIVE_UI_SRCS}
|
||||
${BGRIVE_MOC_SRCS}
|
||||
)
|
||||
|
||||
target_link_libraries( bgrive_executable
|
||||
${Boost_LIBRARIES}
|
||||
${QT_QTMAIN_LIBRARY}
|
||||
${QT_LIBRARIES}
|
||||
grive
|
||||
)
|
||||
|
||||
set_target_properties( bgrive_executable
|
||||
PROPERTIES OUTPUT_NAME bgrive
|
||||
)
|
||||
|
||||
install(TARGETS bgrive_executable RUNTIME DESTINATION bin)
|
||||
install(FILES doc/grive.1 DESTINATION share/man/man1 )
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2013 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 "MainWnd.hh"
|
||||
|
||||
namespace gr {
|
||||
|
||||
MainWnd::MainWnd( )
|
||||
{
|
||||
m_ui.setupUi(this) ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2013 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 <QtGui/QMainWindow>
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
namespace gr {
|
||||
|
||||
class MainWnd : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public :
|
||||
MainWnd( ) ;
|
||||
|
||||
private :
|
||||
Ui::MainWindow m_ui ;
|
||||
} ;
|
||||
|
||||
} // end of namespace
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2013 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 "MainWnd.hh"
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "drive/CommonUri.hh"
|
||||
#include "drive/Entry.hh"
|
||||
#include "drive/Feed.hh"
|
||||
|
||||
#include "http/CurlAgent.hh"
|
||||
#include "http/Header.hh"
|
||||
#include "http/XmlResponse.hh"
|
||||
|
||||
#include "protocol/Json.hh"
|
||||
#include "protocol/OAuth2.hh"
|
||||
#include "protocol/AuthAgent.hh"
|
||||
|
||||
#include "util/File.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
const std::string client_id = "22314510474.apps.googleusercontent.com" ;
|
||||
const std::string client_secret = "bl4ufi89h-9MkFlypcI7R785" ;
|
||||
|
||||
using namespace gr ;
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
File file( ".grive" ) ;
|
||||
Json cfg = Json::Parse( &file ) ;
|
||||
|
||||
std::string refresh_token = cfg["refresh_token"].Str() ;
|
||||
qDebug() << refresh_token.c_str() ;
|
||||
|
||||
OAuth2 token( refresh_token, client_id, client_secret ) ;
|
||||
AuthAgent agent( token, std::auto_ptr<http::Agent>( new http::CurlAgent ) ) ;
|
||||
|
||||
|
||||
http::XmlResponse xml ;
|
||||
agent.Get( feed_base + "/-/folder?max-results=50&showroot=true", &xml, http::Header() ) ;
|
||||
|
||||
Feed feed( xml.Response() ) ;
|
||||
do
|
||||
{
|
||||
// first, get all collections from the query result
|
||||
for ( Feed::iterator i = feed.begin() ; i != feed.end() ; ++i )
|
||||
{
|
||||
Entry e( *i ) ;
|
||||
qDebug() << e.Name().c_str() ;
|
||||
}
|
||||
} while ( feed.GetNext( &agent, http::Header() ) ) ;
|
||||
|
||||
QApplication app( argc, argv ) ;
|
||||
MainWnd wnd ;
|
||||
wnd.show();
|
||||
|
||||
return app.exec() ;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Grive</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="m_dir">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QListView" name="m_files">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="m_menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="m_menu_file">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="m_action_exit"/>
|
||||
</widget>
|
||||
<addaction name="m_menu_file"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="m_statusbar"/>
|
||||
<action name="m_action_exit">
|
||||
<property name="text">
|
||||
<string>E&xit</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>m_action_exit</sender>
|
||||
<signal>activated()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>299</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -67,7 +67,7 @@ private :
|
|||
std::auto_ptr<LogInfo> m_log ;
|
||||
|
||||
xml::Node m_root ;
|
||||
xml::NodeSet m_entries ;
|
||||
xml::NodeSet m_entries ;
|
||||
} ;
|
||||
|
||||
class Feed::iterator : public boost::iterator_adaptor<
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "util/Crypt.hh"
|
||||
#include "util/log/Log.hh"
|
||||
#include "util/OS.hh"
|
||||
#include "util/StdioFile.hh"
|
||||
#include "util/File.hh"
|
||||
#include "xml/Node.hh"
|
||||
#include "xml/NodeSet.hh"
|
||||
#include "xml/String.hh"
|
||||
|
@ -269,7 +269,7 @@ void Resource::FromLocal( const DateTime& last_sync )
|
|||
else
|
||||
m_state = ( m_mtime > last_sync ? local_new : remote_deleted ) ;
|
||||
|
||||
m_name = Path2Str( path.filename() ) ;
|
||||
m_name = path.filename().string() ;
|
||||
m_kind = fs::is_directory(path) ? "folder" : "file" ;
|
||||
m_md5 = fs::is_directory(path) ? "" : crypt::MD5::Get( path ) ;
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ bool Resource::Upload(
|
|||
{
|
||||
assert( http != 0 ) ;
|
||||
|
||||
StdioFile file( Path() ) ;
|
||||
File file( Path() ) ;
|
||||
std::ostringstream xcontent_len ;
|
||||
xcontent_len << "X-Upload-Content-Length: " << file.Size() ;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "http/Agent.hh"
|
||||
#include "util/Crypt.hh"
|
||||
#include "util/File.hh"
|
||||
#include "util/log/Log.hh"
|
||||
#include "protocol/Json.hh"
|
||||
|
||||
|
@ -72,7 +73,7 @@ void State::FromLocal( const fs::path& p, gr::Resource* folder )
|
|||
|
||||
for ( fs::directory_iterator i( p ) ; i != fs::directory_iterator() ; ++i )
|
||||
{
|
||||
std::string fname = Path2Str(i->path().filename()) ;
|
||||
std::string fname = i->path().filename().string() ;
|
||||
|
||||
if ( IsIgnore(fname) )
|
||||
Log( "file %1% is ignored by grive", fname, log::verbose ) ;
|
||||
|
@ -228,7 +229,8 @@ void State::Read( const fs::path& filename )
|
|||
{
|
||||
try
|
||||
{
|
||||
Json json = Json::ParseFile( filename.string() ) ;
|
||||
File file( filename ) ;
|
||||
Json json = Json::Parse( &file ) ;
|
||||
|
||||
Json last_sync = json["last_sync"] ;
|
||||
m_last_sync.Assign(
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
namespace gr {
|
||||
|
||||
class StdioFile ;
|
||||
class File ;
|
||||
|
||||
namespace http {
|
||||
|
||||
|
@ -33,6 +33,8 @@ class Receivable ;
|
|||
class Agent
|
||||
{
|
||||
public :
|
||||
virtual ~Agent() {}
|
||||
|
||||
virtual long Put(
|
||||
const std::string& url,
|
||||
const std::string& data,
|
||||
|
@ -41,7 +43,7 @@ public :
|
|||
|
||||
virtual long Put(
|
||||
const std::string& url,
|
||||
StdioFile& file,
|
||||
File& file,
|
||||
Receivable *dest,
|
||||
const Header& hdr ) = 0 ;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "Receivable.hh"
|
||||
|
||||
#include "util/log/Log.hh"
|
||||
#include "util/StdioFile.hh"
|
||||
#include "util/File.hh"
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
|
@ -62,7 +62,7 @@ size_t ReadStringCallback( void *ptr, std::size_t size, std::size_t nmemb, std::
|
|||
return count ;
|
||||
}
|
||||
|
||||
size_t ReadFileCallback( void *ptr, std::size_t size, std::size_t nmemb, StdioFile *file )
|
||||
size_t ReadFileCallback( void *ptr, std::size_t size, std::size_t nmemb, File *file )
|
||||
{
|
||||
assert( ptr != 0 ) ;
|
||||
assert( file != 0 ) ;
|
||||
|
@ -73,7 +73,7 @@ size_t ReadFileCallback( void *ptr, std::size_t size, std::size_t nmemb, StdioFi
|
|||
assert( count <= std::numeric_limits<std::size_t>::max() ) ;
|
||||
|
||||
if ( count > 0 )
|
||||
file->Read( ptr, static_cast<std::size_t>(count) ) ;
|
||||
file->Read( static_cast<char*>(ptr), static_cast<std::size_t>(count) ) ;
|
||||
|
||||
return count ;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ long CurlAgent::Put(
|
|||
|
||||
long CurlAgent::Put(
|
||||
const std::string& url,
|
||||
StdioFile& file,
|
||||
File& file,
|
||||
Receivable *dest,
|
||||
const Header& hdr )
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ public :
|
|||
|
||||
long Put(
|
||||
const std::string& url,
|
||||
StdioFile& file,
|
||||
File& file,
|
||||
Receivable *dest,
|
||||
const Header& hdr ) ;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ std::size_t Download::OnData( void *data, std::size_t count )
|
|||
if ( m_crypt.get() != 0 )
|
||||
m_crypt->Write( data, count ) ;
|
||||
|
||||
return m_file.Write( data, count ) ;
|
||||
return m_file.Write( static_cast<char*>(data), count ) ;
|
||||
}
|
||||
|
||||
} } // end of namespace
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Receivable.hh"
|
||||
#include "util/StdioFile.hh"
|
||||
#include "util/File.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -47,7 +47,7 @@ public :
|
|||
std::size_t OnData( void *data, std::size_t count ) ;
|
||||
|
||||
private :
|
||||
StdioFile m_file ;
|
||||
File m_file ;
|
||||
std::auto_ptr<crypt::MD5> m_crypt ;
|
||||
} ;
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
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 "http/Agent.hh"
|
||||
|
||||
namespace gr { namespace http {
|
||||
|
||||
class HttpRequest ;
|
||||
|
||||
/*! \brief An marshaller for HTTP agent
|
||||
|
||||
This agent will marshal the HTTP requests to a request objects containing the arguments
|
||||
of the request and the response.
|
||||
*/
|
||||
class MarshalAgent : public Agent
|
||||
{
|
||||
public :
|
||||
MarshalAgent( std::auto_ptr<Agent> real_agent ) ;
|
||||
} ;
|
||||
|
||||
}} // end of namespace
|
|
@ -26,6 +26,7 @@ namespace gr { namespace http {
|
|||
class Receivable
|
||||
{
|
||||
public :
|
||||
virtual ~Receivable() {}
|
||||
virtual std::size_t OnData( void *data, std::size_t count ) = 0 ;
|
||||
virtual void Clear() = 0 ;
|
||||
} ;
|
||||
|
|
|
@ -62,7 +62,7 @@ long AuthAgent::Put(
|
|||
|
||||
long AuthAgent::Put(
|
||||
const std::string& url,
|
||||
StdioFile& file,
|
||||
File& file,
|
||||
Receivable *dest,
|
||||
const Header& hdr )
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ public :
|
|||
|
||||
long Put(
|
||||
const std::string& url,
|
||||
StdioFile& file,
|
||||
File& file,
|
||||
http::Receivable *dest,
|
||||
const http::Header& hdr ) ;
|
||||
|
||||
|
|
|
@ -19,10 +19,21 @@
|
|||
|
||||
#include "Json.hh"
|
||||
|
||||
#include "util/StdioFile.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/json_tokener.h>
|
||||
#include <json/linkhash.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
@ -35,51 +46,99 @@ Json::Json( ) :
|
|||
m_json( ::json_object_new_object() )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json object" ) ) ;
|
||||
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() << expt::ErrMsg( "cannot create json string \"" + std::string(str) + "\"" ) ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< JsonCApi_( "json_object_new_string" )
|
||||
<< ValueErr( str )
|
||||
) ;
|
||||
}
|
||||
|
||||
struct json_object* Json::InitStr( const char *str, std::size_t n )
|
||||
{
|
||||
struct json_object *j = ::json_object_new_string_len( str, n ) ;
|
||||
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( ::json_object_new_string( str.c_str() ) )
|
||||
m_json( InitStr( str.c_str(), str.size() ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << expt::ErrMsg( "cannot create json string \"" + str + "\"" ) ) ;
|
||||
|
||||
// paranoid check
|
||||
assert( ::json_object_get_string( m_json ) == str ) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
Json::Json( const int& l ) :
|
||||
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() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< JsonCApi_( "json_object_new_int" )
|
||||
<< ValueErr( l )
|
||||
) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
Json::Json( const long& l ) :
|
||||
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
||||
Json::Json( const boost::int64_t& l ) :
|
||||
m_json( ::json_object_new_int64( l ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< JsonCApi_( "json_object_new_int64" )
|
||||
<< ValueErr( l )
|
||||
) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
Json::Json( const unsigned long& l ) :
|
||||
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() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
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 <>
|
||||
|
@ -87,7 +146,7 @@ Json::Json( const std::vector<Json>& arr ) :
|
|||
m_json( ::json_object_new_array( ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << JsonCApi_( "json_object_new_array" ) ) ;
|
||||
|
||||
for ( std::vector<Json>::const_iterator i = arr.begin() ; i != arr.end() ; ++i )
|
||||
Add( *i ) ;
|
||||
|
@ -98,7 +157,11 @@ Json::Json( const bool& b ) :
|
|||
m_json( ::json_object_new_boolean( b ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json bool" ) ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< JsonCApi_( "json_object_new_boolean" )
|
||||
<< ValueErr( b )
|
||||
) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -106,7 +169,7 @@ Json::Json( const Object& obj ) :
|
|||
m_json( ::json_object_new_object() )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json object" ) ) ;
|
||||
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 ) ;
|
||||
|
@ -157,13 +220,15 @@ Json Json::operator[]( const std::string& key ) const
|
|||
{
|
||||
assert( m_json != 0 ) ;
|
||||
|
||||
struct json_object *j = ::json_object_object_get( m_json, key.c_str() ) ;
|
||||
if ( j == 0 )
|
||||
struct json_object *j = 0 ;
|
||||
if ( !::json_object_object_get_ex( m_json, key.c_str(), &j ) )
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< expt::ErrMsg( "key: " + key + " is not found in object" )
|
||||
<< JsonInfo( *this ) ) ;
|
||||
<< JsonCApi_( "json_object_object_get" )
|
||||
<< KeyNotFound_( key )
|
||||
<< Json_( ::json_object_to_json_string(m_json) ) ) ;
|
||||
|
||||
assert( j != 0 ) ;
|
||||
return Json( j ) ;
|
||||
}
|
||||
|
||||
|
@ -174,12 +239,11 @@ Json Json::operator[]( const std::size_t& idx ) const
|
|||
struct json_object *j = ::json_object_array_get_idx( m_json, idx ) ;
|
||||
if ( j == 0 )
|
||||
{
|
||||
std::ostringstream ss ;
|
||||
ss << "index " << idx << " is not found in array" ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< expt::ErrMsg( ss.str() )
|
||||
<< JsonInfo( *this ) ) ;
|
||||
<< JsonCApi_( "json_object_array_get_idx" )
|
||||
<< OutOfRange_( idx )
|
||||
<< Json_( ::json_object_to_json_string(m_json) ) ) ;
|
||||
}
|
||||
|
||||
return Json( j ) ;
|
||||
|
@ -188,15 +252,17 @@ Json Json::operator[]( const std::size_t& idx ) const
|
|||
bool Json::Has( const std::string& key ) const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_object_get( m_json, key.c_str() ) != 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 = ::json_object_object_get( m_json, key.c_str() ) ;
|
||||
if ( j != 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 ;
|
||||
|
@ -226,14 +292,20 @@ void Json::Add( const Json& json )
|
|||
bool Json::Bool() const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_get_boolean( m_json ) ;
|
||||
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 ) ;
|
||||
return ::json_object_is_type( m_json, json_type_boolean ) == TRUE ;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Json::As<bool>() const
|
||||
{
|
||||
return Bool() ;
|
||||
}
|
||||
|
||||
std::string Json::Str() const
|
||||
|
@ -246,7 +318,13 @@ template <>
|
|||
bool Json::Is<std::string>() const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_is_type( m_json, json_type_string ) ;
|
||||
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
|
||||
|
@ -259,7 +337,31 @@ template <>
|
|||
bool Json::Is<int>() const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_is_type( m_json, json_type_int ) ;
|
||||
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 )
|
||||
|
@ -268,10 +370,12 @@ std::ostream& operator<<( std::ostream& os, const Json& json )
|
|||
return os << ::json_object_to_json_string( json.m_json ) ;
|
||||
}
|
||||
|
||||
void Json::Write( StdioFile& file ) const
|
||||
void Json::Write( DataStream *out ) const
|
||||
{
|
||||
assert( out != 0 ) ;
|
||||
|
||||
const char *str = ::json_object_to_json_string( m_json ) ;
|
||||
file.Write( str, std::strlen(str) ) ;
|
||||
out->Write( str, std::strlen(str) ) ;
|
||||
}
|
||||
|
||||
Json::Type Json::DataType() const
|
||||
|
@ -296,7 +400,13 @@ template <>
|
|||
bool Json::Is<Json::Object>() const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_is_type( m_json, json_type_object ) ;
|
||||
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
|
||||
|
@ -314,9 +424,18 @@ template <>
|
|||
bool Json::Is<Json::Array>() const
|
||||
{
|
||||
assert( m_json != 0 ) ;
|
||||
return ::json_object_is_type( m_json, json_type_array ) ;
|
||||
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 ) ;
|
||||
|
@ -327,8 +446,16 @@ Json Json::FindInArray( const std::string& key, const std::string& value ) const
|
|||
if ( item.Has(key) && item[key].Str() == value )
|
||||
return item ;
|
||||
}
|
||||
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << expt::ErrMsg( "cannot find " + key + " = " + value + " in array" ) ) ;
|
||||
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
|
||||
|
@ -340,37 +467,58 @@ bool Json::FindInArray( const std::string& key, const std::string& value, Json&
|
|||
}
|
||||
catch ( Error& )
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
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() << expt::ErrMsg( "json parse error" ) ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< JsonCApi_( "json_tokener_parse" )
|
||||
<< ValueErr( str )
|
||||
) ;
|
||||
|
||||
return Json( json, NotOwned() ) ;
|
||||
}
|
||||
|
||||
Json Json::ParseFile( const std::string& filename )
|
||||
/// 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 )
|
||||
{
|
||||
StdioFile file( filename ) ;
|
||||
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 = file.Read( buf, sizeof(buf) ) ) > 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 ;
|
||||
}
|
||||
|
||||
if ( json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ) ;
|
||||
|
||||
::json_tokener_free( tok ) ;
|
||||
// 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" )
|
||||
<< expt::ErrMsg( ::json_tokener_error_desc(err) )
|
||||
) ;
|
||||
}
|
||||
|
||||
return Json( json, NotOwned() ) ;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,13 @@ struct json_object ;
|
|||
|
||||
namespace gr {
|
||||
|
||||
class StdioFile ;
|
||||
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 :
|
||||
|
@ -38,19 +43,35 @@ public :
|
|||
typedef std::vector<Json> Array ;
|
||||
|
||||
struct Error : virtual Exception {} ;
|
||||
typedef boost::error_info<struct JsonTag, Json> JsonInfo ;
|
||||
|
||||
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_ ;
|
||||
|
||||
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( ) ;
|
||||
~Json() ;
|
||||
|
||||
static Json Parse( const std::string& str ) ;
|
||||
static Json ParseFile( const std::string& filename ) ;
|
||||
static Json Parse( DataStream *in ) ;
|
||||
|
||||
Json operator[]( const std::string& key ) const ;
|
||||
Json operator[]( const std::size_t& idx ) const ;
|
||||
|
@ -68,6 +89,9 @@ public :
|
|||
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 ) ;
|
||||
|
@ -76,7 +100,7 @@ public :
|
|||
bool FindInArray( const std::string& key, const std::string& value, Json& result ) const ;
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& os, const Json& json ) ;
|
||||
void Write( StdioFile& file ) const ;
|
||||
void Write( DataStream *out ) const ;
|
||||
|
||||
enum Type { null_type, bool_type, double_type, int_type, object_type, array_type, string_type } ;
|
||||
|
||||
|
@ -87,10 +111,17 @@ private :
|
|||
|
||||
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 :
|
||||
public :
|
||||
struct json_object *m_json ;
|
||||
} ;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "Config.hh"
|
||||
|
||||
#include "util/StdioFile.hh"
|
||||
#include "util/File.hh"
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
namespace gr {
|
||||
namespace PROJ_NS {
|
||||
|
||||
const std::string default_filename = ".grive";
|
||||
const char *env_name = "GR_CONFIG";
|
||||
|
@ -64,8 +64,8 @@ const fs::path Config::Filename() const
|
|||
|
||||
void Config::Save( )
|
||||
{
|
||||
StdioFile file( m_path.string(), 0600 ) ;
|
||||
m_file.Write( file ) ;
|
||||
gr::File file( m_path.string(), 0600 ) ;
|
||||
m_file.Write( &file ) ;
|
||||
}
|
||||
|
||||
void Config::Set( const std::string& key, const Json& value )
|
||||
|
@ -93,7 +93,8 @@ Json Config::Read()
|
|||
{
|
||||
try
|
||||
{
|
||||
return Json::ParseFile( m_path.string() ) ;
|
||||
gr::File file(m_path) ;
|
||||
return Json::Parse( &file ) ;
|
||||
}
|
||||
catch ( Exception& e )
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace boost
|
|||
}
|
||||
}
|
||||
|
||||
namespace gr {
|
||||
namespace PROJ_NS {
|
||||
|
||||
class Config
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "Crypt.hh"
|
||||
|
||||
#include "StdioFile.hh"
|
||||
#include "File.hh"
|
||||
#include "Exception.hh"
|
||||
#include "MemMap.hh"
|
||||
|
||||
|
@ -76,16 +76,16 @@ std::string MD5::Get( const fs::path& file )
|
|||
{
|
||||
try
|
||||
{
|
||||
StdioFile sfile( file ) ;
|
||||
File sfile( file ) ;
|
||||
return Get( sfile ) ;
|
||||
}
|
||||
catch ( StdioFile::Error& )
|
||||
catch ( File::Error& )
|
||||
{
|
||||
return "" ;
|
||||
}
|
||||
}
|
||||
|
||||
std::string MD5::Get( StdioFile& file )
|
||||
std::string MD5::Get( File& file )
|
||||
{
|
||||
MD5 crypt ;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace gr {
|
||||
|
||||
class StdioFile ;
|
||||
class File ;
|
||||
|
||||
namespace crypt {
|
||||
|
||||
|
@ -36,7 +36,7 @@ public :
|
|||
MD5() ;
|
||||
~MD5() ;
|
||||
|
||||
static std::string Get( StdioFile& file ) ;
|
||||
static std::string Get( File& file ) ;
|
||||
static std::string Get( const boost::filesystem::path& file ) ;
|
||||
|
||||
void Write( const void *data, std::size_t size ) ;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
webwrite: 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 <cstddef>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/** \brief Encapsulation of data streams. Useful for unit tests.
|
||||
This class provides two functions: Read() and Write().
|
||||
*/
|
||||
class DataStream
|
||||
{
|
||||
protected :
|
||||
virtual ~DataStream() {}
|
||||
|
||||
public :
|
||||
/** Reading from the stream. The caller indicates that it wants
|
||||
to read `size` bytes and must provide enough space pointed
|
||||
by `data`.
|
||||
\param data Buffer to hold the data read from the stream
|
||||
Must have at least `size` bytes.
|
||||
\param size Number of bytes the caller wants to read.
|
||||
\throw wb::Exception In case of any error.
|
||||
\return The number of byte actually read from the stream.
|
||||
0 indicates the end of stream, i.e. you will
|
||||
still get 0 if you call again.
|
||||
*/
|
||||
virtual std::size_t Read( char *data, std::size_t size ) = 0 ;
|
||||
virtual std::size_t Write( const char *data, std::size_t size ) = 0 ;
|
||||
} ;
|
||||
|
||||
/// Stream for /dev/null, i.e. read and writing nothing
|
||||
DataStream* DevNull() ;
|
||||
|
||||
|
||||
|
||||
} // end of namespace
|
|
@ -17,7 +17,7 @@
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "util/Exception.hh"
|
||||
#include "Exception.hh"
|
||||
|
||||
#include "bfd/Backtrace.hh"
|
||||
#include "bfd/Debug.hh"
|
||||
|
@ -28,15 +28,20 @@
|
|||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
namespace gr {
|
||||
namespace PROJ_NS {
|
||||
|
||||
class Backtrace ;
|
||||
|
||||
Exception::Exception( )
|
||||
{
|
||||
#ifdef HAVE_BFD
|
||||
*this << expt::BacktraceInfo( Backtrace() ) ;
|
||||
*this << expt::Backtrace_( Backtrace() ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* Exception::what() const throw()
|
||||
{
|
||||
return boost::diagnostic_information_what( *this ) ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
webwrite: 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
|
||||
|
@ -25,54 +25,35 @@
|
|||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace gr {
|
||||
namespace PROJ_NS {
|
||||
|
||||
class Backtrace ;
|
||||
|
||||
/** \defgroup exception Exception Classes
|
||||
*/
|
||||
|
||||
/// base class for exception in libpdfdoc
|
||||
/** \ingroup exception
|
||||
This class is the base class for all exception class in libpdfdoc.
|
||||
/** \brief base class for exception in WebWrite
|
||||
\ingroup exception
|
||||
This class is the base class for all exception class in WebWrite.
|
||||
It allows us to catch all WebWrite exception with one catch clause.
|
||||
*/
|
||||
struct Exception :
|
||||
virtual public std::exception,
|
||||
virtual public boost::exception
|
||||
{
|
||||
Exception( ) ;
|
||||
|
||||
virtual const char* what() const throw() ;
|
||||
} ;
|
||||
|
||||
struct FileError : virtual Exception {} ;
|
||||
|
||||
/// Parse error exception.
|
||||
/** \ingroup exception
|
||||
This exception will be thrown when there is a parse error when reading
|
||||
a PDF file.
|
||||
*/
|
||||
struct ParseError : virtual Exception {} ;
|
||||
|
||||
/// Invalid type exception.
|
||||
/** \ingroup exception
|
||||
This exception will be thrown when the Object cannot convert its
|
||||
underlying data to a specific type. The what() member function will
|
||||
describe the expected and actual type of the data.
|
||||
*/
|
||||
struct BadType : virtual Exception {} ;
|
||||
|
||||
struct Unsupported : virtual Exception {} ;
|
||||
|
||||
// Exception informations
|
||||
/// Exception informations
|
||||
namespace expt
|
||||
{
|
||||
// back-trace information. should be present for all exceptions
|
||||
typedef boost::error_info<struct BacktraceTag, Backtrace> BacktraceInfo ;
|
||||
typedef boost::error_info<struct BacktraceTag, Backtrace> Backtrace_ ;
|
||||
|
||||
// generic error message
|
||||
typedef boost::error_info<struct MsgTag, std::string> ErrMsg ;
|
||||
|
||||
// nested exception
|
||||
typedef boost::error_info<struct ExceptionTag, Exception> Nested ;
|
||||
/// generic error message
|
||||
typedef boost::error_info<struct MsgTag, std::string> ErrMsg ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
|
|
@ -17,27 +17,34 @@
|
|||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "StdioFile.hh"
|
||||
#include "File.hh"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// boost headers
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/exception/errinfo_api_function.hpp>
|
||||
#include <boost/exception/errinfo_at_line.hpp>
|
||||
#include <boost/exception/errinfo_errno.hpp>
|
||||
#include <boost/exception/errinfo_file_name.hpp>
|
||||
#include <boost/exception/errinfo_file_open_mode.hpp>
|
||||
#include <boost/exception/info.hpp>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
typedef int ssize_t ;
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
// local functions
|
||||
namespace {
|
||||
|
||||
using namespace gr ;
|
||||
|
||||
off_t LSeek( int fd, off_t offset, int whence )
|
||||
{
|
||||
assert( fd >= 0 ) ;
|
||||
|
@ -46,7 +53,7 @@ off_t LSeek( int fd, off_t offset, int whence )
|
|||
if ( r == static_cast<off_t>(-1) )
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
gr::StdioFile::Error()
|
||||
File::Error()
|
||||
<< boost::errinfo_api_function("lseek")
|
||||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
|
@ -61,7 +68,7 @@ struct stat FStat( int fd )
|
|||
if ( ::fstat( fd, &s ) != 0 )
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
gr::StdioFile::Error()
|
||||
File::Error()
|
||||
<< boost::errinfo_api_function("fstat")
|
||||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
|
@ -71,28 +78,40 @@ struct stat FStat( int fd )
|
|||
|
||||
} // end of local functions
|
||||
|
||||
namespace gr {
|
||||
namespace PROJ_NS {
|
||||
|
||||
StdioFile::StdioFile( ) : m_fd( -1 )
|
||||
File::File( ) : m_fd( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
StdioFile::StdioFile( const fs::path& path ) : m_fd( -1 )
|
||||
/** Opens the file for reading.
|
||||
\param path Path to the file to be opened.
|
||||
\throw Error When the file cannot be openned.
|
||||
*/
|
||||
File::File( const fs::path& path ) : m_fd( -1 )
|
||||
{
|
||||
OpenForRead( path ) ;
|
||||
}
|
||||
|
||||
StdioFile::StdioFile( const fs::path& path, int mode ) : m_fd( -1 )
|
||||
/** Opens the file for writing.
|
||||
\param path Path to the file to be opened.
|
||||
\param mode Mode of the file to be created, e.g. 0600 for user
|
||||
readable/writable.
|
||||
\throw Error When the file cannot be opened.
|
||||
*/
|
||||
File::File( const fs::path& path, int mode ) : m_fd( -1 )
|
||||
{
|
||||
OpenForWrite( path, mode ) ;
|
||||
}
|
||||
|
||||
StdioFile::~StdioFile( )
|
||||
/** The destructor will close the file.
|
||||
*/
|
||||
File::~File( )
|
||||
{
|
||||
Close() ;
|
||||
}
|
||||
|
||||
void StdioFile::Open( const fs::path& path, int flags, int mode )
|
||||
void File::Open( const fs::path& path, int flags, int mode )
|
||||
{
|
||||
if ( IsOpened() )
|
||||
Close() ;
|
||||
|
@ -110,17 +129,25 @@ void StdioFile::Open( const fs::path& path, int flags, int mode )
|
|||
}
|
||||
}
|
||||
|
||||
void StdioFile::OpenForRead( const fs::path& path )
|
||||
void File::OpenForRead( const fs::path& path )
|
||||
{
|
||||
Open( path, O_RDONLY, 0 ) ;
|
||||
int flags = O_RDONLY ;
|
||||
#ifdef WIN32
|
||||
flags |= O_BINARY ;
|
||||
#endif
|
||||
Open( path, flags, 0 ) ;
|
||||
}
|
||||
|
||||
void StdioFile::OpenForWrite( const fs::path& path, int mode )
|
||||
void File::OpenForWrite( const fs::path& path, int mode )
|
||||
{
|
||||
Open( path, O_CREAT|O_RDWR|O_TRUNC, mode ) ;
|
||||
int flags = O_CREAT|O_RDWR|O_TRUNC ;
|
||||
#ifdef WIN32
|
||||
flags |= O_BINARY ;
|
||||
#endif
|
||||
Open( path, flags, mode ) ;
|
||||
}
|
||||
|
||||
void StdioFile::Close()
|
||||
void File::Close()
|
||||
{
|
||||
if ( IsOpened() )
|
||||
{
|
||||
|
@ -129,12 +156,15 @@ void StdioFile::Close()
|
|||
}
|
||||
}
|
||||
|
||||
bool StdioFile::IsOpened() const
|
||||
bool File::IsOpened() const
|
||||
{
|
||||
return m_fd != -1 ;
|
||||
}
|
||||
|
||||
std::size_t StdioFile::Read( void *ptr, std::size_t size )
|
||||
/** Read bytes from file. See DataStream::Read() for details.
|
||||
\throw Error In case of any error.
|
||||
*/
|
||||
std::size_t File::Read( char *ptr, std::size_t size )
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
ssize_t count = ::read( m_fd, ptr, size ) ;
|
||||
|
@ -149,7 +179,7 @@ std::size_t StdioFile::Read( void *ptr, std::size_t size )
|
|||
return count ;
|
||||
}
|
||||
|
||||
std::size_t StdioFile::Write( const void *ptr, std::size_t size )
|
||||
std::size_t File::Write( const char *ptr, std::size_t size )
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
ssize_t count = ::write( m_fd, ptr, size ) ;
|
||||
|
@ -157,26 +187,26 @@ std::size_t StdioFile::Write( const void *ptr, std::size_t size )
|
|||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< boost::errinfo_api_function("read")
|
||||
<< boost::errinfo_api_function("write")
|
||||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
}
|
||||
return count ;
|
||||
}
|
||||
|
||||
off_t StdioFile::Seek( off_t offset, int whence )
|
||||
off_t File::Seek( off_t offset, int whence )
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
return LSeek( m_fd, offset, whence ) ;
|
||||
}
|
||||
|
||||
off_t StdioFile::Tell() const
|
||||
off_t File::Tell() const
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
return LSeek( m_fd, 0, SEEK_CUR ) ;
|
||||
}
|
||||
|
||||
u64_t StdioFile::Size() const
|
||||
u64_t File::Size() const
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
|
||||
|
@ -186,10 +216,10 @@ u64_t StdioFile::Size() const
|
|||
return static_cast<uint64_t>( s.st_size ) ;
|
||||
}
|
||||
|
||||
void StdioFile::Chmod( int mode )
|
||||
void File::Chmod( int mode )
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
|
||||
#ifndef WIN32
|
||||
if ( ::fchmod( m_fd, mode ) != 0 )
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
|
@ -198,12 +228,18 @@ void StdioFile::Chmod( int mode )
|
|||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void* StdioFile::Map( off_t offset, std::size_t length )
|
||||
/// This function is not implemented in win32 yet.
|
||||
void* File::Map( off_t offset, std::size_t length )
|
||||
{
|
||||
assert( IsOpened() ) ;
|
||||
|
||||
#ifdef WIN32
|
||||
assert( false ) ;
|
||||
return 0 ;
|
||||
#else
|
||||
void *addr = ::mmap( 0, length, PROT_READ, MAP_PRIVATE, m_fd, offset ) ;
|
||||
if ( addr == reinterpret_cast<void*>( -1 ) )
|
||||
{
|
||||
|
@ -214,10 +250,12 @@ void* StdioFile::Map( off_t offset, std::size_t length )
|
|||
) ;
|
||||
}
|
||||
return addr ;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StdioFile::UnMap( void *addr, std::size_t length )
|
||||
void File::UnMap( void *addr, std::size_t length )
|
||||
{
|
||||
#ifndef WIN32
|
||||
if ( ::munmap( addr, length ) != 0 )
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
|
@ -226,6 +264,21 @@ void StdioFile::UnMap( void *addr, std::size_t length )
|
|||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct stat File::Stat() const
|
||||
{
|
||||
struct stat result = {} ;
|
||||
if ( ::fstat( m_fd, &result ) != 0 )
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< boost::errinfo_api_function("fstat")
|
||||
<< boost::errinfo_errno(errno)
|
||||
) ;
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
|
@ -19,32 +19,47 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "DataStream.hh"
|
||||
#include "Exception.hh"
|
||||
#include "FileSystem.hh"
|
||||
#include "Types.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
struct stat ;
|
||||
|
||||
namespace gr {
|
||||
|
||||
class StdioFile
|
||||
/** \brief A wrapper class for file read/write.
|
||||
|
||||
It is a simple wrapper around the UNIX file descriptor. It will
|
||||
throw exceptions (i.e. Error) when it encounters errors.
|
||||
*/
|
||||
class File : public DataStream
|
||||
{
|
||||
public :
|
||||
/// File specific errors. It often includes
|
||||
/// boost::errinfo_api_function and boost::errinfo_errno for the
|
||||
/// detail information.
|
||||
struct Error : virtual Exception {} ;
|
||||
|
||||
public :
|
||||
StdioFile() ;
|
||||
StdioFile( const fs::path& path ) ;
|
||||
StdioFile( const fs::path& path, int mode ) ;
|
||||
~StdioFile( ) ;
|
||||
File() ;
|
||||
File( const fs::path& path ) ;
|
||||
File( const fs::path& path, int mode ) ;
|
||||
~File( ) ;
|
||||
|
||||
File( const File& rhs ) ;
|
||||
File& operator=( const File& rhs ) ;
|
||||
void Swap( File& other ) ;
|
||||
|
||||
void OpenForRead( const fs::path& path ) ;
|
||||
void OpenForWrite( const fs::path& path, int mode = 0600 ) ;
|
||||
void Close() ;
|
||||
bool IsOpened() const ;
|
||||
|
||||
std::size_t Read( void *ptr, std::size_t size ) ;
|
||||
std::size_t Write( const void *ptr, std::size_t size ) ;
|
||||
std::size_t Read( char *ptr, std::size_t size ) ;
|
||||
std::size_t Write( const char *ptr, std::size_t size ) ;
|
||||
|
||||
off_t Seek( off_t offset, int whence ) ;
|
||||
off_t Tell() const ;
|
||||
|
@ -54,7 +69,9 @@ public :
|
|||
|
||||
void* Map( off_t offset, std::size_t length ) ;
|
||||
static void UnMap( void *addr, std::size_t length ) ;
|
||||
|
||||
|
||||
struct stat Stat() const ;
|
||||
|
||||
private :
|
||||
void Open( const fs::path& path, int flags, int mode ) ;
|
||||
|
|
@ -25,17 +25,4 @@
|
|||
namespace gr
|
||||
{
|
||||
namespace fs = boost::filesystem ;
|
||||
|
||||
// these two functions are for ancient distro which does not have boost v1.44 or later
|
||||
// will be removed once people upgrade
|
||||
|
||||
inline std::string Path2Str( const fs::path& p )
|
||||
{
|
||||
return p.string() ;
|
||||
}
|
||||
|
||||
inline std::string Path2Str( const std::string& s )
|
||||
{
|
||||
return s ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
*/
|
||||
|
||||
#include "MemMap.hh"
|
||||
#include "StdioFile.hh"
|
||||
#include "File.hh"
|
||||
|
||||
namespace gr {
|
||||
|
||||
MemMap::MemMap( StdioFile& file, off_t offset, std::size_t length ) :
|
||||
MemMap::MemMap( File& file, off_t offset, std::size_t length ) :
|
||||
m_addr ( file.Map( offset, length ) ),
|
||||
m_length( length )
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ MemMap::MemMap( StdioFile& file, off_t offset, std::size_t length ) :
|
|||
|
||||
MemMap::~MemMap()
|
||||
{
|
||||
StdioFile::UnMap( m_addr, m_length ) ;
|
||||
File::UnMap( m_addr, m_length ) ;
|
||||
}
|
||||
|
||||
void* MemMap::Addr() const
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
namespace gr {
|
||||
|
||||
class StdioFile ;
|
||||
class File ;
|
||||
|
||||
class MemMap
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ public :
|
|||
struct Error : virtual Exception {} ;
|
||||
|
||||
public :
|
||||
MemMap( StdioFile& file, off_t offset, std::size_t length ) ;
|
||||
MemMap( File& file, off_t offset, std::size_t length ) ;
|
||||
~MemMap() ;
|
||||
|
||||
void* Addr() const ;
|
||||
|
|
Loading…
Reference in New Issue